SVC: Add locks to the memory management.
This commit is contained in:
parent
d4ebb510a0
commit
3902067008
|
@ -135,6 +135,7 @@ enum class ResourceLimitValueType {
|
||||||
|
|
||||||
ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
|
ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit,
|
||||||
u32 resource_type, ResourceLimitValueType value_type) {
|
u32 resource_type, ResourceLimitValueType value_type) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
const auto type = static_cast<ResourceType>(resource_type);
|
const auto type = static_cast<ResourceType>(resource_type);
|
||||||
if (!IsValidResourceType(type)) {
|
if (!IsValidResourceType(type)) {
|
||||||
LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
|
LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type);
|
||||||
|
@ -162,6 +163,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_
|
||||||
|
|
||||||
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
||||||
static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) {
|
static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
|
LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
|
||||||
|
|
||||||
// Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB.
|
// Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB.
|
||||||
|
@ -192,6 +194,7 @@ static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_s
|
||||||
|
|
||||||
static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask,
|
static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask,
|
||||||
u32 attribute) {
|
u32 attribute) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_DEBUG(Kernel_SVC,
|
LOG_DEBUG(Kernel_SVC,
|
||||||
"called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
|
"called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address,
|
||||||
size, mask, attribute);
|
size, mask, attribute);
|
||||||
|
@ -230,6 +233,7 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si
|
||||||
|
|
||||||
/// Maps a memory range into a different range.
|
/// Maps a memory range into a different range.
|
||||||
static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
|
static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||||
src_addr, size);
|
src_addr, size);
|
||||||
|
|
||||||
|
@ -245,6 +249,7 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr
|
||||||
|
|
||||||
/// Unmaps a region that was previously mapped with svcMapMemory
|
/// Unmaps a region that was previously mapped with svcMapMemory
|
||||||
static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
|
static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||||
src_addr, size);
|
src_addr, size);
|
||||||
|
|
||||||
|
@ -261,6 +266,7 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad
|
||||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||||
static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
|
static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
|
||||||
VAddr port_name_address) {
|
VAddr port_name_address) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
auto& memory = system.Memory();
|
auto& memory = system.Memory();
|
||||||
|
|
||||||
if (!memory.IsValidVirtualAddress(port_name_address)) {
|
if (!memory.IsValidVirtualAddress(port_name_address)) {
|
||||||
|
@ -309,6 +315,7 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
|
||||||
|
|
||||||
/// Makes a blocking IPC call to an OS service.
|
/// Makes a blocking IPC call to an OS service.
|
||||||
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle);
|
std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
|
@ -639,6 +646,7 @@ static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr addre
|
||||||
/// Gets system/memory information for the current process
|
/// Gets system/memory information for the current process
|
||||||
static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle,
|
static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle,
|
||||||
u64 info_sub_id) {
|
u64 info_sub_id) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
|
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
|
||||||
info_sub_id, handle);
|
info_sub_id, handle);
|
||||||
|
|
||||||
|
@ -904,6 +912,7 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h
|
||||||
|
|
||||||
/// Maps memory at a desired address
|
/// Maps memory at a desired address
|
||||||
static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
|
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
|
||||||
|
|
||||||
if (!Common::Is4KBAligned(addr)) {
|
if (!Common::Is4KBAligned(addr)) {
|
||||||
|
@ -953,6 +962,7 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size)
|
||||||
|
|
||||||
/// Unmaps memory previously mapped via MapPhysicalMemory
|
/// Unmaps memory previously mapped via MapPhysicalMemory
|
||||||
static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
|
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
|
||||||
|
|
||||||
if (!Common::Is4KBAligned(addr)) {
|
if (!Common::Is4KBAligned(addr)) {
|
||||||
|
@ -1129,6 +1139,7 @@ static u32 GetCurrentProcessorNumber(Core::System& system) {
|
||||||
|
|
||||||
static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
|
static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
|
||||||
u64 size, u32 permissions) {
|
u64 size, u32 permissions) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC,
|
LOG_TRACE(Kernel_SVC,
|
||||||
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
||||||
shared_memory_handle, addr, size, permissions);
|
shared_memory_handle, addr, size, permissions);
|
||||||
|
@ -1202,6 +1213,7 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han
|
||||||
static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
|
static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address,
|
||||||
VAddr page_info_address, Handle process_handle,
|
VAddr page_info_address, Handle process_handle,
|
||||||
VAddr address) {
|
VAddr address) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle);
|
std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle);
|
||||||
|
@ -1782,6 +1794,7 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) {
|
||||||
/// Creates a TransferMemory object
|
/// Creates a TransferMemory object
|
||||||
static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size,
|
static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size,
|
||||||
u32 permissions) {
|
u32 permissions) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size,
|
LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size,
|
||||||
permissions);
|
permissions);
|
||||||
|
|
||||||
|
@ -1993,6 +2006,7 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) {
|
static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) {
|
||||||
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
LOG_DEBUG(Kernel_SVC, "called");
|
LOG_DEBUG(Kernel_SVC, "called");
|
||||||
|
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
|
@ -2439,6 +2453,13 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
||||||
void Call(Core::System& system, u32 immediate) {
|
void Call(Core::System& system, u32 immediate) {
|
||||||
MICROPROFILE_SCOPE(Kernel_SVC);
|
MICROPROFILE_SCOPE(Kernel_SVC);
|
||||||
|
|
||||||
|
auto& physical_core = system.CurrentPhysicalCore();
|
||||||
|
if (physical_core.IsInterrupted()) {
|
||||||
|
auto& sched = physical_core.Scheduler();
|
||||||
|
sched.TryDoContextSwitch();
|
||||||
|
}
|
||||||
|
physical_core.ClearExclusive();
|
||||||
|
|
||||||
const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)
|
const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate)
|
||||||
: GetSVCInfo32(immediate);
|
: GetSVCInfo32(immediate);
|
||||||
if (info) {
|
if (info) {
|
||||||
|
|
Reference in New Issue