diff options
| author | 2020-02-27 10:28:44 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:18 -0400 | |
| commit | 3902067008abed4ca748e2f6d4ad582748f9ed52 (patch) | |
| tree | 50b3f9e2a972bfeb1f96ed3826cfaae67aa74f50 /src/core/hle/kernel/svc.cpp | |
| parent | SVC: Correct WaitSynchronization, WaitProcessWideKey, SignalProcessWideKey. (diff) | |
| download | yuzu-3902067008abed4ca748e2f6d4ad582748f9ed52.tar.gz yuzu-3902067008abed4ca748e2f6d4ad582748f9ed52.tar.xz yuzu-3902067008abed4ca748e2f6d4ad582748f9ed52.zip | |
SVC: Add locks to the memory management.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a5193063b..279fe5888 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -135,6 +135,7 @@ enum class ResourceLimitValueType { | |||
| 135 | 135 | ||
| 136 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, | 136 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, |
| 137 | u32 resource_type, ResourceLimitValueType value_type) { | 137 | u32 resource_type, ResourceLimitValueType value_type) { |
| 138 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 138 | const auto type = static_cast<ResourceType>(resource_type); | 139 | const auto type = static_cast<ResourceType>(resource_type); |
| 139 | if (!IsValidResourceType(type)) { | 140 | if (!IsValidResourceType(type)) { |
| 140 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); | 141 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); |
| @@ -162,6 +163,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 162 | 163 | ||
| 163 | /// Set the process heap to a given Size. It can both extend and shrink the heap. | 164 | /// Set the process heap to a given Size. It can both extend and shrink the heap. |
| 164 | static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { | 165 | static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_size) { |
| 166 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 165 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); | 167 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); |
| 166 | 168 | ||
| 167 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. | 169 | // 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 | |||
| 192 | 194 | ||
| 193 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, | 195 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, |
| 194 | u32 attribute) { | 196 | u32 attribute) { |
| 197 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 195 | LOG_DEBUG(Kernel_SVC, | 198 | LOG_DEBUG(Kernel_SVC, |
| 196 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, | 199 | "called, address=0x{:016X}, size=0x{:X}, mask=0x{:08X}, attribute=0x{:08X}", address, |
| 197 | size, mask, attribute); | 200 | size, mask, attribute); |
| @@ -230,6 +233,7 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 230 | 233 | ||
| 231 | /// Maps a memory range into a different range. | 234 | /// Maps a memory range into a different range. |
| 232 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 235 | static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 236 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 233 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 237 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 234 | src_addr, size); | 238 | src_addr, size); |
| 235 | 239 | ||
| @@ -245,6 +249,7 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr | |||
| 245 | 249 | ||
| 246 | /// Unmaps a region that was previously mapped with svcMapMemory | 250 | /// Unmaps a region that was previously mapped with svcMapMemory |
| 247 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { | 251 | static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) { |
| 252 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 248 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 253 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 249 | src_addr, size); | 254 | src_addr, size); |
| 250 | 255 | ||
| @@ -261,6 +266,7 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | |||
| 261 | /// Connect to an OS service given the port name, returns the handle to the port to out | 266 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 262 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | 267 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, |
| 263 | VAddr port_name_address) { | 268 | VAddr port_name_address) { |
| 269 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 264 | auto& memory = system.Memory(); | 270 | auto& memory = system.Memory(); |
| 265 | 271 | ||
| 266 | if (!memory.IsValidVirtualAddress(port_name_address)) { | 272 | if (!memory.IsValidVirtualAddress(port_name_address)) { |
| @@ -309,6 +315,7 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, | |||
| 309 | 315 | ||
| 310 | /// Makes a blocking IPC call to an OS service. | 316 | /// Makes a blocking IPC call to an OS service. |
| 311 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | 317 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { |
| 318 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 312 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 319 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 313 | std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle); | 320 | std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle); |
| 314 | if (!session) { | 321 | if (!session) { |
| @@ -639,6 +646,7 @@ static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr addre | |||
| 639 | /// Gets system/memory information for the current process | 646 | /// Gets system/memory information for the current process |
| 640 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle, | 647 | static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle, |
| 641 | u64 info_sub_id) { | 648 | u64 info_sub_id) { |
| 649 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 642 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, | 650 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, |
| 643 | info_sub_id, handle); | 651 | info_sub_id, handle); |
| 644 | 652 | ||
| @@ -904,6 +912,7 @@ static ResultCode GetInfo32(Core::System& system, u32* result_low, u32* result_h | |||
| 904 | 912 | ||
| 905 | /// Maps memory at a desired address | 913 | /// Maps memory at a desired address |
| 906 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 914 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 915 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 907 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 916 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 908 | 917 | ||
| 909 | if (!Common::Is4KBAligned(addr)) { | 918 | if (!Common::Is4KBAligned(addr)) { |
| @@ -953,6 +962,7 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) | |||
| 953 | 962 | ||
| 954 | /// Unmaps memory previously mapped via MapPhysicalMemory | 963 | /// Unmaps memory previously mapped via MapPhysicalMemory |
| 955 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | 964 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { |
| 965 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 956 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | 966 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); |
| 957 | 967 | ||
| 958 | if (!Common::Is4KBAligned(addr)) { | 968 | if (!Common::Is4KBAligned(addr)) { |
| @@ -1129,6 +1139,7 @@ static u32 GetCurrentProcessorNumber(Core::System& system) { | |||
| 1129 | 1139 | ||
| 1130 | static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr, | 1140 | static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr, |
| 1131 | u64 size, u32 permissions) { | 1141 | u64 size, u32 permissions) { |
| 1142 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 1132 | LOG_TRACE(Kernel_SVC, | 1143 | LOG_TRACE(Kernel_SVC, |
| 1133 | "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", | 1144 | "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", |
| 1134 | shared_memory_handle, addr, size, permissions); | 1145 | shared_memory_handle, addr, size, permissions); |
| @@ -1202,6 +1213,7 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1202 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1213 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| 1203 | VAddr page_info_address, Handle process_handle, | 1214 | VAddr page_info_address, Handle process_handle, |
| 1204 | VAddr address) { | 1215 | VAddr address) { |
| 1216 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 1205 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); | 1217 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); |
| 1206 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1218 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1207 | std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle); | 1219 | std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle); |
| @@ -1782,6 +1794,7 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { | |||
| 1782 | /// Creates a TransferMemory object | 1794 | /// Creates a TransferMemory object |
| 1783 | static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, | 1795 | static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, |
| 1784 | u32 permissions) { | 1796 | u32 permissions) { |
| 1797 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 1785 | LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, | 1798 | LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, |
| 1786 | permissions); | 1799 | permissions); |
| 1787 | 1800 | ||
| @@ -1993,6 +2006,7 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ | |||
| 1993 | } | 2006 | } |
| 1994 | 2007 | ||
| 1995 | static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { | 2008 | static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { |
| 2009 | std::lock_guard lock{HLE::g_hle_lock}; | ||
| 1996 | LOG_DEBUG(Kernel_SVC, "called"); | 2010 | LOG_DEBUG(Kernel_SVC, "called"); |
| 1997 | 2011 | ||
| 1998 | auto& kernel = system.Kernel(); | 2012 | auto& kernel = system.Kernel(); |
| @@ -2439,6 +2453,13 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | |||
| 2439 | void Call(Core::System& system, u32 immediate) { | 2453 | void Call(Core::System& system, u32 immediate) { |
| 2440 | MICROPROFILE_SCOPE(Kernel_SVC); | 2454 | MICROPROFILE_SCOPE(Kernel_SVC); |
| 2441 | 2455 | ||
| 2456 | auto& physical_core = system.CurrentPhysicalCore(); | ||
| 2457 | if (physical_core.IsInterrupted()) { | ||
| 2458 | auto& sched = physical_core.Scheduler(); | ||
| 2459 | sched.TryDoContextSwitch(); | ||
| 2460 | } | ||
| 2461 | physical_core.ClearExclusive(); | ||
| 2462 | |||
| 2442 | const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) | 2463 | const FunctionDef* info = system.CurrentProcess()->Is64BitProcess() ? GetSVCInfo64(immediate) |
| 2443 | : GetSVCInfo32(immediate); | 2464 | : GetSVCInfo32(immediate); |
| 2444 | if (info) { | 2465 | if (info) { |