diff options
| author | 2020-04-17 16:33:08 -0400 | |
|---|---|---|
| committer | 2020-04-17 16:33:08 -0400 | |
| commit | b8f5c71f2d7f819821acf036175cce65ab1ae12c (patch) | |
| tree | 151d7ed4e47536dc0e149a7117387b6a502d7da6 /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #3682 from lioncash/uam (diff) | |
| parent | core: hle: Address various feedback & code cleanup. (diff) | |
| download | yuzu-b8f5c71f2d7f819821acf036175cce65ab1ae12c.tar.gz yuzu-b8f5c71f2d7f819821acf036175cce65ab1ae12c.tar.xz yuzu-b8f5c71f2d7f819821acf036175cce65ab1ae12c.zip | |
Merge pull request #3666 from bunnei/new-vmm
Implement a new virtual memory manager
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 621 |
1 files changed, 125 insertions, 496 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 4ffc113c2..4134acf65 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | #include "core/hle/kernel/errors.h" | 24 | #include "core/hle/kernel/errors.h" |
| 25 | #include "core/hle/kernel/handle_table.h" | 25 | #include "core/hle/kernel/handle_table.h" |
| 26 | #include "core/hle/kernel/kernel.h" | 26 | #include "core/hle/kernel/kernel.h" |
| 27 | #include "core/hle/kernel/memory/memory_block.h" | ||
| 28 | #include "core/hle/kernel/memory/page_table.h" | ||
| 27 | #include "core/hle/kernel/mutex.h" | 29 | #include "core/hle/kernel/mutex.h" |
| 28 | #include "core/hle/kernel/process.h" | 30 | #include "core/hle/kernel/process.h" |
| 29 | #include "core/hle/kernel/readable_event.h" | 31 | #include "core/hle/kernel/readable_event.h" |
| @@ -31,6 +33,7 @@ | |||
| 31 | #include "core/hle/kernel/scheduler.h" | 33 | #include "core/hle/kernel/scheduler.h" |
| 32 | #include "core/hle/kernel/shared_memory.h" | 34 | #include "core/hle/kernel/shared_memory.h" |
| 33 | #include "core/hle/kernel/svc.h" | 35 | #include "core/hle/kernel/svc.h" |
| 36 | #include "core/hle/kernel/svc_types.h" | ||
| 34 | #include "core/hle/kernel/svc_wrap.h" | 37 | #include "core/hle/kernel/svc_wrap.h" |
| 35 | #include "core/hle/kernel/synchronization.h" | 38 | #include "core/hle/kernel/synchronization.h" |
| 36 | #include "core/hle/kernel/thread.h" | 39 | #include "core/hle/kernel/thread.h" |
| @@ -42,7 +45,7 @@ | |||
| 42 | #include "core/memory.h" | 45 | #include "core/memory.h" |
| 43 | #include "core/reporter.h" | 46 | #include "core/reporter.h" |
| 44 | 47 | ||
| 45 | namespace Kernel { | 48 | namespace Kernel::Svc { |
| 46 | namespace { | 49 | namespace { |
| 47 | 50 | ||
| 48 | // Checks if address + size is greater than the given address | 51 | // Checks if address + size is greater than the given address |
| @@ -58,8 +61,8 @@ constexpr u64 MAIN_MEMORY_SIZE = 0x200000000; | |||
| 58 | // Helper function that performs the common sanity checks for svcMapMemory | 61 | // Helper function that performs the common sanity checks for svcMapMemory |
| 59 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing | 62 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing |
| 60 | // in the same order. | 63 | // in the same order. |
| 61 | ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_addr, VAddr src_addr, | 64 | ResultCode MapUnmapMemorySanityChecks(const Memory::PageTable& manager, VAddr dst_addr, |
| 62 | u64 size) { | 65 | VAddr src_addr, u64 size) { |
| 63 | if (!Common::Is4KBAligned(dst_addr)) { | 66 | if (!Common::Is4KBAligned(dst_addr)) { |
| 64 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); | 67 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); |
| 65 | return ERR_INVALID_ADDRESS; | 68 | return ERR_INVALID_ADDRESS; |
| @@ -93,36 +96,33 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add | |||
| 93 | return ERR_INVALID_ADDRESS_STATE; | 96 | return ERR_INVALID_ADDRESS_STATE; |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | if (!vm_manager.IsWithinAddressSpace(src_addr, size)) { | 99 | if (!manager.IsInsideAddressSpace(src_addr, size)) { |
| 97 | LOG_ERROR(Kernel_SVC, | 100 | LOG_ERROR(Kernel_SVC, |
| 98 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", | 101 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", |
| 99 | src_addr, size); | 102 | src_addr, size); |
| 100 | return ERR_INVALID_ADDRESS_STATE; | 103 | return ERR_INVALID_ADDRESS_STATE; |
| 101 | } | 104 | } |
| 102 | 105 | ||
| 103 | if (!vm_manager.IsWithinStackRegion(dst_addr, size)) { | 106 | if (manager.IsOutsideStackRegion(dst_addr, size)) { |
| 104 | LOG_ERROR(Kernel_SVC, | 107 | LOG_ERROR(Kernel_SVC, |
| 105 | "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}", | 108 | "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}", |
| 106 | dst_addr, size); | 109 | dst_addr, size); |
| 107 | return ERR_INVALID_MEMORY_RANGE; | 110 | return ERR_INVALID_MEMORY_RANGE; |
| 108 | } | 111 | } |
| 109 | 112 | ||
| 110 | const VAddr dst_end_address = dst_addr + size; | 113 | if (manager.IsInsideHeapRegion(dst_addr, size)) { |
| 111 | if (dst_end_address > vm_manager.GetHeapRegionBaseAddress() && | ||
| 112 | vm_manager.GetHeapRegionEndAddress() > dst_addr) { | ||
| 113 | LOG_ERROR(Kernel_SVC, | 114 | LOG_ERROR(Kernel_SVC, |
| 114 | "Destination does not fit within the heap region, addr=0x{:016X}, " | 115 | "Destination does not fit within the heap region, addr=0x{:016X}, " |
| 115 | "size=0x{:016X}, end_addr=0x{:016X}", | 116 | "size=0x{:016X}", |
| 116 | dst_addr, size, dst_end_address); | 117 | dst_addr, size); |
| 117 | return ERR_INVALID_MEMORY_RANGE; | 118 | return ERR_INVALID_MEMORY_RANGE; |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | if (dst_end_address > vm_manager.GetMapRegionBaseAddress() && | 121 | if (manager.IsInsideAliasRegion(dst_addr, size)) { |
| 121 | vm_manager.GetMapRegionEndAddress() > dst_addr) { | ||
| 122 | LOG_ERROR(Kernel_SVC, | 122 | LOG_ERROR(Kernel_SVC, |
| 123 | "Destination does not fit within the map region, addr=0x{:016X}, " | 123 | "Destination does not fit within the map region, addr=0x{:016X}, " |
| 124 | "size=0x{:016X}, end_addr=0x{:016X}", | 124 | "size=0x{:016X}", |
| 125 | dst_addr, size, dst_end_address); | 125 | dst_addr, size); |
| 126 | return ERR_INVALID_MEMORY_RANGE; | 126 | return ERR_INVALID_MEMORY_RANGE; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| @@ -177,13 +177,10 @@ static ResultCode SetHeapSize(Core::System& system, VAddr* heap_addr, u64 heap_s | |||
| 177 | return ERR_INVALID_SIZE; | 177 | return ERR_INVALID_SIZE; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | auto& vm_manager = system.Kernel().CurrentProcess()->VMManager(); | 180 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 181 | const auto alloc_result = vm_manager.SetHeapSize(heap_size); | 181 | |
| 182 | if (alloc_result.Failed()) { | 182 | CASCADE_RESULT(*heap_addr, page_table.SetHeapSize(heap_size)); |
| 183 | return alloc_result.Code(); | ||
| 184 | } | ||
| 185 | 183 | ||
| 186 | *heap_addr = *alloc_result; | ||
| 187 | return RESULT_SUCCESS; | 184 | return RESULT_SUCCESS; |
| 188 | } | 185 | } |
| 189 | 186 | ||
| @@ -194,63 +191,6 @@ static ResultCode SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_s | |||
| 194 | return result; | 191 | return result; |
| 195 | } | 192 | } |
| 196 | 193 | ||
| 197 | static ResultCode SetMemoryPermission(Core::System& system, VAddr addr, u64 size, u32 prot) { | ||
| 198 | LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); | ||
| 199 | |||
| 200 | if (!Common::Is4KBAligned(addr)) { | ||
| 201 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, addr=0x{:016X}", addr); | ||
| 202 | return ERR_INVALID_ADDRESS; | ||
| 203 | } | ||
| 204 | |||
| 205 | if (size == 0) { | ||
| 206 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 207 | return ERR_INVALID_SIZE; | ||
| 208 | } | ||
| 209 | |||
| 210 | if (!Common::Is4KBAligned(size)) { | ||
| 211 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, size=0x{:016X}", size); | ||
| 212 | return ERR_INVALID_SIZE; | ||
| 213 | } | ||
| 214 | |||
| 215 | if (!IsValidAddressRange(addr, size)) { | ||
| 216 | LOG_ERROR(Kernel_SVC, "Region is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | ||
| 217 | addr, size); | ||
| 218 | return ERR_INVALID_ADDRESS_STATE; | ||
| 219 | } | ||
| 220 | |||
| 221 | const auto permission = static_cast<MemoryPermission>(prot); | ||
| 222 | if (permission != MemoryPermission::None && permission != MemoryPermission::Read && | ||
| 223 | permission != MemoryPermission::ReadWrite) { | ||
| 224 | LOG_ERROR(Kernel_SVC, "Invalid memory permission specified, Got memory permission=0x{:08X}", | ||
| 225 | static_cast<u32>(permission)); | ||
| 226 | return ERR_INVALID_MEMORY_PERMISSIONS; | ||
| 227 | } | ||
| 228 | |||
| 229 | auto* const current_process = system.Kernel().CurrentProcess(); | ||
| 230 | auto& vm_manager = current_process->VMManager(); | ||
| 231 | |||
| 232 | if (!vm_manager.IsWithinAddressSpace(addr, size)) { | ||
| 233 | LOG_ERROR(Kernel_SVC, | ||
| 234 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | ||
| 235 | size); | ||
| 236 | return ERR_INVALID_ADDRESS_STATE; | ||
| 237 | } | ||
| 238 | |||
| 239 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); | ||
| 240 | if (!vm_manager.IsValidHandle(iter)) { | ||
| 241 | LOG_ERROR(Kernel_SVC, "Unable to find VMA for address=0x{:016X}", addr); | ||
| 242 | return ERR_INVALID_ADDRESS_STATE; | ||
| 243 | } | ||
| 244 | |||
| 245 | LOG_WARNING(Kernel_SVC, "Uniformity check on protected memory is not implemented."); | ||
| 246 | // TODO: Performs a uniformity check to make sure only protected memory is changed (it doesn't | ||
| 247 | // make sense to allow changing permissions on kernel memory itself, etc). | ||
| 248 | |||
| 249 | const auto converted_permissions = SharedMemory::ConvertPermissions(permission); | ||
| 250 | |||
| 251 | return vm_manager.ReprotectRange(addr, size, converted_permissions); | ||
| 252 | } | ||
| 253 | |||
| 254 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, | 194 | static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, |
| 255 | u32 attribute) { | 195 | u32 attribute) { |
| 256 | LOG_DEBUG(Kernel_SVC, | 196 | LOG_DEBUG(Kernel_SVC, |
| @@ -274,30 +214,19 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 274 | return ERR_INVALID_ADDRESS_STATE; | 214 | return ERR_INVALID_ADDRESS_STATE; |
| 275 | } | 215 | } |
| 276 | 216 | ||
| 277 | const auto mem_attribute = static_cast<MemoryAttribute>(attribute); | 217 | const auto attributes{static_cast<Memory::MemoryAttribute>(mask | attribute)}; |
| 278 | const auto mem_mask = static_cast<MemoryAttribute>(mask); | 218 | if (attributes != static_cast<Memory::MemoryAttribute>(mask) || |
| 279 | const auto attribute_with_mask = mem_attribute | mem_mask; | 219 | (attributes | Memory::MemoryAttribute::Uncached) != Memory::MemoryAttribute::Uncached) { |
| 280 | |||
| 281 | if (attribute_with_mask != mem_mask) { | ||
| 282 | LOG_ERROR(Kernel_SVC, | 220 | LOG_ERROR(Kernel_SVC, |
| 283 | "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", | 221 | "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", |
| 284 | attribute, mask); | 222 | attribute, mask); |
| 285 | return ERR_INVALID_COMBINATION; | 223 | return ERR_INVALID_COMBINATION; |
| 286 | } | 224 | } |
| 287 | 225 | ||
| 288 | if ((attribute_with_mask | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) { | 226 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 289 | LOG_ERROR(Kernel_SVC, "Specified attribute isn't equal to MemoryAttributeUncached (8)."); | ||
| 290 | return ERR_INVALID_COMBINATION; | ||
| 291 | } | ||
| 292 | |||
| 293 | auto& vm_manager = system.Kernel().CurrentProcess()->VMManager(); | ||
| 294 | if (!vm_manager.IsWithinAddressSpace(address, size)) { | ||
| 295 | LOG_ERROR(Kernel_SVC, | ||
| 296 | "Given address (0x{:016X}) is outside the bounds of the address space.", address); | ||
| 297 | return ERR_INVALID_ADDRESS_STATE; | ||
| 298 | } | ||
| 299 | 227 | ||
| 300 | return vm_manager.SetMemoryAttribute(address, size, mem_mask, mem_attribute); | 228 | return page_table.SetMemoryAttribute(address, size, static_cast<Memory::MemoryAttribute>(mask), |
| 229 | static_cast<Memory::MemoryAttribute>(attribute)); | ||
| 301 | } | 230 | } |
| 302 | 231 | ||
| 303 | /// Maps a memory range into a different range. | 232 | /// Maps a memory range into a different range. |
| @@ -305,14 +234,14 @@ static ResultCode MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr | |||
| 305 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 234 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 306 | src_addr, size); | 235 | src_addr, size); |
| 307 | 236 | ||
| 308 | auto& vm_manager = system.Kernel().CurrentProcess()->VMManager(); | 237 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 309 | const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); | ||
| 310 | 238 | ||
| 311 | if (result.IsError()) { | 239 | if (const ResultCode result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; |
| 240 | result.IsError()) { | ||
| 312 | return result; | 241 | return result; |
| 313 | } | 242 | } |
| 314 | 243 | ||
| 315 | return vm_manager.MirrorMemory(dst_addr, src_addr, size, MemoryState::Stack); | 244 | return page_table.Map(dst_addr, src_addr, size); |
| 316 | } | 245 | } |
| 317 | 246 | ||
| 318 | /// Unmaps a region that was previously mapped with svcMapMemory | 247 | /// Unmaps a region that was previously mapped with svcMapMemory |
| @@ -320,21 +249,14 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | |||
| 320 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, | 249 | LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr, |
| 321 | src_addr, size); | 250 | src_addr, size); |
| 322 | 251 | ||
| 323 | auto& vm_manager = system.Kernel().CurrentProcess()->VMManager(); | 252 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 324 | const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); | ||
| 325 | 253 | ||
| 326 | if (result.IsError()) { | 254 | if (const ResultCode result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)}; |
| 255 | result.IsError()) { | ||
| 327 | return result; | 256 | return result; |
| 328 | } | 257 | } |
| 329 | 258 | ||
| 330 | const auto unmap_res = vm_manager.UnmapRange(dst_addr, size); | 259 | return page_table.Unmap(dst_addr, src_addr, size); |
| 331 | |||
| 332 | // Reprotect the source mapping on success | ||
| 333 | if (unmap_res.IsSuccess()) { | ||
| 334 | ASSERT(vm_manager.ReprotectRange(src_addr, size, VMAPermission::ReadWrite).IsSuccess()); | ||
| 335 | } | ||
| 336 | |||
| 337 | return unmap_res; | ||
| 338 | } | 260 | } |
| 339 | 261 | ||
| 340 | /// Connect to an OS service given the port name, returns the handle to the port to out | 262 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| @@ -367,6 +289,8 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 367 | return ERR_NOT_FOUND; | 289 | return ERR_NOT_FOUND; |
| 368 | } | 290 | } |
| 369 | 291 | ||
| 292 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Sessions, 1)); | ||
| 293 | |||
| 370 | auto client_port = it->second; | 294 | auto client_port = it->second; |
| 371 | 295 | ||
| 372 | std::shared_ptr<ClientSession> client_session; | 296 | std::shared_ptr<ClientSession> client_session; |
| @@ -538,7 +462,7 @@ static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_hand | |||
| 538 | "requesting_current_thread_handle=0x{:08X}", | 462 | "requesting_current_thread_handle=0x{:08X}", |
| 539 | holding_thread_handle, mutex_addr, requesting_thread_handle); | 463 | holding_thread_handle, mutex_addr, requesting_thread_handle); |
| 540 | 464 | ||
| 541 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 465 | if (Core::Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 542 | LOG_ERROR(Kernel_SVC, "Mutex Address is a kernel virtual address, mutex_addr={:016X}", | 466 | LOG_ERROR(Kernel_SVC, "Mutex Address is a kernel virtual address, mutex_addr={:016X}", |
| 543 | mutex_addr); | 467 | mutex_addr); |
| 544 | return ERR_INVALID_ADDRESS_STATE; | 468 | return ERR_INVALID_ADDRESS_STATE; |
| @@ -558,7 +482,7 @@ static ResultCode ArbitrateLock(Core::System& system, Handle holding_thread_hand | |||
| 558 | static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) { | 482 | static ResultCode ArbitrateUnlock(Core::System& system, VAddr mutex_addr) { |
| 559 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); | 483 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); |
| 560 | 484 | ||
| 561 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 485 | if (Core::Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 562 | LOG_ERROR(Kernel_SVC, "Mutex Address is a kernel virtual address, mutex_addr={:016X}", | 486 | LOG_ERROR(Kernel_SVC, "Mutex Address is a kernel virtual address, mutex_addr={:016X}", |
| 563 | mutex_addr); | 487 | mutex_addr); |
| 564 | return ERR_INVALID_ADDRESS_STATE; | 488 | return ERR_INVALID_ADDRESS_STATE; |
| @@ -683,7 +607,6 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 683 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); | 607 | auto* const current_thread = system.CurrentScheduler().GetCurrentThread(); |
| 684 | const auto thread_processor_id = current_thread->GetProcessorID(); | 608 | const auto thread_processor_id = current_thread->GetProcessorID(); |
| 685 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); | 609 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); |
| 686 | ASSERT(false); | ||
| 687 | 610 | ||
| 688 | system.Kernel().CurrentProcess()->PrepareForTermination(); | 611 | system.Kernel().CurrentProcess()->PrepareForTermination(); |
| 689 | 612 | ||
| @@ -785,35 +708,35 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 785 | return RESULT_SUCCESS; | 708 | return RESULT_SUCCESS; |
| 786 | 709 | ||
| 787 | case GetInfoType::MapRegionBaseAddr: | 710 | case GetInfoType::MapRegionBaseAddr: |
| 788 | *result = process->VMManager().GetMapRegionBaseAddress(); | 711 | *result = process->PageTable().GetAliasRegionStart(); |
| 789 | return RESULT_SUCCESS; | 712 | return RESULT_SUCCESS; |
| 790 | 713 | ||
| 791 | case GetInfoType::MapRegionSize: | 714 | case GetInfoType::MapRegionSize: |
| 792 | *result = process->VMManager().GetMapRegionSize(); | 715 | *result = process->PageTable().GetAliasRegionSize(); |
| 793 | return RESULT_SUCCESS; | 716 | return RESULT_SUCCESS; |
| 794 | 717 | ||
| 795 | case GetInfoType::HeapRegionBaseAddr: | 718 | case GetInfoType::HeapRegionBaseAddr: |
| 796 | *result = process->VMManager().GetHeapRegionBaseAddress(); | 719 | *result = process->PageTable().GetHeapRegionStart(); |
| 797 | return RESULT_SUCCESS; | 720 | return RESULT_SUCCESS; |
| 798 | 721 | ||
| 799 | case GetInfoType::HeapRegionSize: | 722 | case GetInfoType::HeapRegionSize: |
| 800 | *result = process->VMManager().GetHeapRegionSize(); | 723 | *result = process->PageTable().GetHeapRegionSize(); |
| 801 | return RESULT_SUCCESS; | 724 | return RESULT_SUCCESS; |
| 802 | 725 | ||
| 803 | case GetInfoType::ASLRRegionBaseAddr: | 726 | case GetInfoType::ASLRRegionBaseAddr: |
| 804 | *result = process->VMManager().GetASLRRegionBaseAddress(); | 727 | *result = process->PageTable().GetAliasCodeRegionStart(); |
| 805 | return RESULT_SUCCESS; | 728 | return RESULT_SUCCESS; |
| 806 | 729 | ||
| 807 | case GetInfoType::ASLRRegionSize: | 730 | case GetInfoType::ASLRRegionSize: |
| 808 | *result = process->VMManager().GetASLRRegionSize(); | 731 | *result = process->PageTable().GetAliasCodeRegionSize(); |
| 809 | return RESULT_SUCCESS; | 732 | return RESULT_SUCCESS; |
| 810 | 733 | ||
| 811 | case GetInfoType::StackRegionBaseAddr: | 734 | case GetInfoType::StackRegionBaseAddr: |
| 812 | *result = process->VMManager().GetStackRegionBaseAddress(); | 735 | *result = process->PageTable().GetStackRegionStart(); |
| 813 | return RESULT_SUCCESS; | 736 | return RESULT_SUCCESS; |
| 814 | 737 | ||
| 815 | case GetInfoType::StackRegionSize: | 738 | case GetInfoType::StackRegionSize: |
| 816 | *result = process->VMManager().GetStackRegionSize(); | 739 | *result = process->PageTable().GetStackRegionSize(); |
| 817 | return RESULT_SUCCESS; | 740 | return RESULT_SUCCESS; |
| 818 | 741 | ||
| 819 | case GetInfoType::TotalPhysicalMemoryAvailable: | 742 | case GetInfoType::TotalPhysicalMemoryAvailable: |
| @@ -987,20 +910,29 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) | |||
| 987 | return ERR_INVALID_MEMORY_RANGE; | 910 | return ERR_INVALID_MEMORY_RANGE; |
| 988 | } | 911 | } |
| 989 | 912 | ||
| 990 | Process* const current_process = system.Kernel().CurrentProcess(); | 913 | Process* const current_process{system.Kernel().CurrentProcess()}; |
| 991 | auto& vm_manager = current_process->VMManager(); | 914 | auto& page_table{current_process->PageTable()}; |
| 992 | 915 | ||
| 993 | if (current_process->GetSystemResourceSize() == 0) { | 916 | if (current_process->GetSystemResourceSize() == 0) { |
| 994 | LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); | 917 | LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); |
| 995 | return ERR_INVALID_STATE; | 918 | return ERR_INVALID_STATE; |
| 996 | } | 919 | } |
| 997 | 920 | ||
| 998 | if (!vm_manager.IsWithinMapRegion(addr, size)) { | 921 | if (!page_table.IsInsideAddressSpace(addr, size)) { |
| 999 | LOG_ERROR(Kernel_SVC, "Range not within map region"); | 922 | LOG_ERROR(Kernel_SVC, |
| 923 | "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | ||
| 924 | size); | ||
| 925 | return ERR_INVALID_MEMORY_RANGE; | ||
| 926 | } | ||
| 927 | |||
| 928 | if (page_table.IsOutsideAliasRegion(addr, size)) { | ||
| 929 | LOG_ERROR(Kernel_SVC, | ||
| 930 | "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, | ||
| 931 | size); | ||
| 1000 | return ERR_INVALID_MEMORY_RANGE; | 932 | return ERR_INVALID_MEMORY_RANGE; |
| 1001 | } | 933 | } |
| 1002 | 934 | ||
| 1003 | return vm_manager.MapPhysicalMemory(addr, size); | 935 | return page_table.MapPhysicalMemory(addr, size); |
| 1004 | } | 936 | } |
| 1005 | 937 | ||
| 1006 | /// Unmaps memory previously mapped via MapPhysicalMemory | 938 | /// Unmaps memory previously mapped via MapPhysicalMemory |
| @@ -1027,20 +959,29 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size | |||
| 1027 | return ERR_INVALID_MEMORY_RANGE; | 959 | return ERR_INVALID_MEMORY_RANGE; |
| 1028 | } | 960 | } |
| 1029 | 961 | ||
| 1030 | Process* const current_process = system.Kernel().CurrentProcess(); | 962 | Process* const current_process{system.Kernel().CurrentProcess()}; |
| 1031 | auto& vm_manager = current_process->VMManager(); | 963 | auto& page_table{current_process->PageTable()}; |
| 1032 | 964 | ||
| 1033 | if (current_process->GetSystemResourceSize() == 0) { | 965 | if (current_process->GetSystemResourceSize() == 0) { |
| 1034 | LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); | 966 | LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); |
| 1035 | return ERR_INVALID_STATE; | 967 | return ERR_INVALID_STATE; |
| 1036 | } | 968 | } |
| 1037 | 969 | ||
| 1038 | if (!vm_manager.IsWithinMapRegion(addr, size)) { | 970 | if (!page_table.IsInsideAddressSpace(addr, size)) { |
| 1039 | LOG_ERROR(Kernel_SVC, "Range not within map region"); | 971 | LOG_ERROR(Kernel_SVC, |
| 972 | "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | ||
| 973 | size); | ||
| 974 | return ERR_INVALID_MEMORY_RANGE; | ||
| 975 | } | ||
| 976 | |||
| 977 | if (page_table.IsOutsideAliasRegion(addr, size)) { | ||
| 978 | LOG_ERROR(Kernel_SVC, | ||
| 979 | "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, | ||
| 980 | size); | ||
| 1040 | return ERR_INVALID_MEMORY_RANGE; | 981 | return ERR_INVALID_MEMORY_RANGE; |
| 1041 | } | 982 | } |
| 1042 | 983 | ||
| 1043 | return vm_manager.UnmapPhysicalMemory(addr, size); | 984 | return page_table.UnmapPhysicalMemory(addr, size); |
| 1044 | } | 985 | } |
| 1045 | 986 | ||
| 1046 | /// Sets the thread activity | 987 | /// Sets the thread activity |
| @@ -1197,74 +1138,49 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1197 | return ERR_INVALID_ADDRESS_STATE; | 1138 | return ERR_INVALID_ADDRESS_STATE; |
| 1198 | } | 1139 | } |
| 1199 | 1140 | ||
| 1200 | const auto permissions_type = static_cast<MemoryPermission>(permissions); | 1141 | const auto permission_type = static_cast<Memory::MemoryPermission>(permissions); |
| 1201 | if (permissions_type != MemoryPermission::Read && | 1142 | if ((permission_type | Memory::MemoryPermission::Write) != |
| 1202 | permissions_type != MemoryPermission::ReadWrite) { | 1143 | Memory::MemoryPermission::ReadAndWrite) { |
| 1203 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", | 1144 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", |
| 1204 | permissions); | 1145 | permissions); |
| 1205 | return ERR_INVALID_MEMORY_PERMISSIONS; | 1146 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 1206 | } | 1147 | } |
| 1207 | 1148 | ||
| 1208 | auto* const current_process = system.Kernel().CurrentProcess(); | 1149 | auto* const current_process{system.Kernel().CurrentProcess()}; |
| 1209 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); | 1150 | auto& page_table{current_process->PageTable()}; |
| 1210 | if (!shared_memory) { | ||
| 1211 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", | ||
| 1212 | shared_memory_handle); | ||
| 1213 | return ERR_INVALID_HANDLE; | ||
| 1214 | } | ||
| 1215 | 1151 | ||
| 1216 | const auto& vm_manager = current_process->VMManager(); | 1152 | if (page_table.IsInvalidRegion(addr, size)) { |
| 1217 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | 1153 | LOG_ERROR(Kernel_SVC, |
| 1218 | LOG_ERROR(Kernel_SVC, "Region is not within the ASLR region. addr=0x{:016X}, size={:016X}", | 1154 | "Addr does not fit within the valid region, addr=0x{:016X}, " |
| 1155 | "size=0x{:016X}", | ||
| 1219 | addr, size); | 1156 | addr, size); |
| 1220 | return ERR_INVALID_MEMORY_RANGE; | 1157 | return ERR_INVALID_MEMORY_RANGE; |
| 1221 | } | 1158 | } |
| 1222 | 1159 | ||
| 1223 | return shared_memory->Map(*current_process, addr, permissions_type, MemoryPermission::DontCare); | 1160 | if (page_table.IsInsideHeapRegion(addr, size)) { |
| 1224 | } | 1161 | LOG_ERROR(Kernel_SVC, |
| 1225 | 1162 | "Addr does not fit within the heap region, addr=0x{:016X}, " | |
| 1226 | static ResultCode UnmapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr, | 1163 | "size=0x{:016X}", |
| 1227 | u64 size) { | 1164 | addr, size); |
| 1228 | LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", | 1165 | return ERR_INVALID_MEMORY_RANGE; |
| 1229 | shared_memory_handle, addr, size); | ||
| 1230 | |||
| 1231 | if (!Common::Is4KBAligned(addr)) { | ||
| 1232 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, addr=0x{:016X}", addr); | ||
| 1233 | return ERR_INVALID_ADDRESS; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | if (size == 0) { | ||
| 1237 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 1238 | return ERR_INVALID_SIZE; | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | if (!Common::Is4KBAligned(size)) { | ||
| 1242 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, size=0x{:016X}", size); | ||
| 1243 | return ERR_INVALID_SIZE; | ||
| 1244 | } | 1166 | } |
| 1245 | 1167 | ||
| 1246 | if (!IsValidAddressRange(addr, size)) { | 1168 | if (page_table.IsInsideAliasRegion(addr, size)) { |
| 1247 | LOG_ERROR(Kernel_SVC, "Region is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | 1169 | LOG_ERROR(Kernel_SVC, |
| 1170 | "Address does not fit within the map region, addr=0x{:016X}, " | ||
| 1171 | "size=0x{:016X}", | ||
| 1248 | addr, size); | 1172 | addr, size); |
| 1249 | return ERR_INVALID_ADDRESS_STATE; | 1173 | return ERR_INVALID_MEMORY_RANGE; |
| 1250 | } | 1174 | } |
| 1251 | 1175 | ||
| 1252 | auto* const current_process = system.Kernel().CurrentProcess(); | 1176 | auto shared_memory{current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle)}; |
| 1253 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); | ||
| 1254 | if (!shared_memory) { | 1177 | if (!shared_memory) { |
| 1255 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", | 1178 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", |
| 1256 | shared_memory_handle); | 1179 | shared_memory_handle); |
| 1257 | return ERR_INVALID_HANDLE; | 1180 | return ERR_INVALID_HANDLE; |
| 1258 | } | 1181 | } |
| 1259 | 1182 | ||
| 1260 | const auto& vm_manager = current_process->VMManager(); | 1183 | return shared_memory->Map(*current_process, addr, size, permission_type); |
| 1261 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | ||
| 1262 | LOG_ERROR(Kernel_SVC, "Region is not within the ASLR region. addr=0x{:016X}, size={:016X}", | ||
| 1263 | addr, size); | ||
| 1264 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | return shared_memory->Unmap(*current_process, addr, size); | ||
| 1268 | } | 1184 | } |
| 1269 | 1185 | ||
| 1270 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, | 1186 | static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, |
| @@ -1279,18 +1195,17 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | |||
| 1279 | return ERR_INVALID_HANDLE; | 1195 | return ERR_INVALID_HANDLE; |
| 1280 | } | 1196 | } |
| 1281 | 1197 | ||
| 1282 | auto& memory = system.Memory(); | 1198 | auto& memory{system.Memory()}; |
| 1283 | const auto& vm_manager = process->VMManager(); | 1199 | const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; |
| 1284 | const MemoryInfo memory_info = vm_manager.QueryMemory(address); | 1200 | |
| 1285 | 1201 | memory.Write64(memory_info_address + 0x00, memory_info.addr); | |
| 1286 | memory.Write64(memory_info_address, memory_info.base_address); | 1202 | memory.Write64(memory_info_address + 0x08, memory_info.size); |
| 1287 | memory.Write64(memory_info_address + 8, memory_info.size); | 1203 | memory.Write32(memory_info_address + 0x10, static_cast<u32>(memory_info.state) & 0xff); |
| 1288 | memory.Write32(memory_info_address + 16, memory_info.state); | 1204 | memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attr)); |
| 1289 | memory.Write32(memory_info_address + 20, memory_info.attributes); | 1205 | memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.perm)); |
| 1290 | memory.Write32(memory_info_address + 24, memory_info.permission); | 1206 | memory.Write32(memory_info_address + 0x1c, memory_info.ipc_refcount); |
| 1291 | memory.Write32(memory_info_address + 32, memory_info.ipc_ref_count); | 1207 | memory.Write32(memory_info_address + 0x20, memory_info.device_refcount); |
| 1292 | memory.Write32(memory_info_address + 28, memory_info.device_ref_count); | 1208 | memory.Write32(memory_info_address + 0x24, 0); |
| 1293 | memory.Write32(memory_info_address + 36, 0); | ||
| 1294 | 1209 | ||
| 1295 | // Page info appears to be currently unused by the kernel and is always set to zero. | 1210 | // Page info appears to be currently unused by the kernel and is always set to zero. |
| 1296 | memory.Write32(page_info_address, 0); | 1211 | memory.Write32(page_info_address, 0); |
| @@ -1314,142 +1229,6 @@ static ResultCode QueryMemory32(Core::System& system, u32 memory_info_address, | |||
| 1314 | return QueryMemory(system, memory_info_address, page_info_address, query_address); | 1229 | return QueryMemory(system, memory_info_address, page_info_address, query_address); |
| 1315 | } | 1230 | } |
| 1316 | 1231 | ||
| 1317 | static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, | ||
| 1318 | u64 src_address, u64 size) { | ||
| 1319 | LOG_DEBUG(Kernel_SVC, | ||
| 1320 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, " | ||
| 1321 | "src_address=0x{:016X}, size=0x{:016X}", | ||
| 1322 | process_handle, dst_address, src_address, size); | ||
| 1323 | |||
| 1324 | if (!Common::Is4KBAligned(src_address)) { | ||
| 1325 | LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", | ||
| 1326 | src_address); | ||
| 1327 | return ERR_INVALID_ADDRESS; | ||
| 1328 | } | ||
| 1329 | |||
| 1330 | if (!Common::Is4KBAligned(dst_address)) { | ||
| 1331 | LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", | ||
| 1332 | dst_address); | ||
| 1333 | return ERR_INVALID_ADDRESS; | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | if (size == 0 || !Common::Is4KBAligned(size)) { | ||
| 1337 | LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X})", size); | ||
| 1338 | return ERR_INVALID_SIZE; | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | if (!IsValidAddressRange(dst_address, size)) { | ||
| 1342 | LOG_ERROR(Kernel_SVC, | ||
| 1343 | "Destination address range overflows the address space (dst_address=0x{:016X}, " | ||
| 1344 | "size=0x{:016X}).", | ||
| 1345 | dst_address, size); | ||
| 1346 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | if (!IsValidAddressRange(src_address, size)) { | ||
| 1350 | LOG_ERROR(Kernel_SVC, | ||
| 1351 | "Source address range overflows the address space (src_address=0x{:016X}, " | ||
| 1352 | "size=0x{:016X}).", | ||
| 1353 | src_address, size); | ||
| 1354 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||
| 1358 | auto process = handle_table.Get<Process>(process_handle); | ||
| 1359 | if (!process) { | ||
| 1360 | LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", | ||
| 1361 | process_handle); | ||
| 1362 | return ERR_INVALID_HANDLE; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | auto& vm_manager = process->VMManager(); | ||
| 1366 | if (!vm_manager.IsWithinAddressSpace(src_address, size)) { | ||
| 1367 | LOG_ERROR(Kernel_SVC, | ||
| 1368 | "Source address range is not within the address space (src_address=0x{:016X}, " | ||
| 1369 | "size=0x{:016X}).", | ||
| 1370 | src_address, size); | ||
| 1371 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | if (!vm_manager.IsWithinASLRRegion(dst_address, size)) { | ||
| 1375 | LOG_ERROR(Kernel_SVC, | ||
| 1376 | "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||
| 1377 | "size=0x{:016X}).", | ||
| 1378 | dst_address, size); | ||
| 1379 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | return vm_manager.MapCodeMemory(dst_address, src_address, size); | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle, | ||
| 1386 | u64 dst_address, u64 src_address, u64 size) { | ||
| 1387 | LOG_DEBUG(Kernel_SVC, | ||
| 1388 | "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " | ||
| 1389 | "size=0x{:016X}", | ||
| 1390 | process_handle, dst_address, src_address, size); | ||
| 1391 | |||
| 1392 | if (!Common::Is4KBAligned(dst_address)) { | ||
| 1393 | LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).", | ||
| 1394 | dst_address); | ||
| 1395 | return ERR_INVALID_ADDRESS; | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | if (!Common::Is4KBAligned(src_address)) { | ||
| 1399 | LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).", | ||
| 1400 | src_address); | ||
| 1401 | return ERR_INVALID_ADDRESS; | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | if (size == 0 || Common::Is4KBAligned(size)) { | ||
| 1405 | LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X}).", size); | ||
| 1406 | return ERR_INVALID_SIZE; | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | if (!IsValidAddressRange(dst_address, size)) { | ||
| 1410 | LOG_ERROR(Kernel_SVC, | ||
| 1411 | "Destination address range overflows the address space (dst_address=0x{:016X}, " | ||
| 1412 | "size=0x{:016X}).", | ||
| 1413 | dst_address, size); | ||
| 1414 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | if (!IsValidAddressRange(src_address, size)) { | ||
| 1418 | LOG_ERROR(Kernel_SVC, | ||
| 1419 | "Source address range overflows the address space (src_address=0x{:016X}, " | ||
| 1420 | "size=0x{:016X}).", | ||
| 1421 | src_address, size); | ||
| 1422 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | ||
| 1426 | auto process = handle_table.Get<Process>(process_handle); | ||
| 1427 | if (!process) { | ||
| 1428 | LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", | ||
| 1429 | process_handle); | ||
| 1430 | return ERR_INVALID_HANDLE; | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | auto& vm_manager = process->VMManager(); | ||
| 1434 | if (!vm_manager.IsWithinAddressSpace(src_address, size)) { | ||
| 1435 | LOG_ERROR(Kernel_SVC, | ||
| 1436 | "Source address range is not within the address space (src_address=0x{:016X}, " | ||
| 1437 | "size=0x{:016X}).", | ||
| 1438 | src_address, size); | ||
| 1439 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1440 | } | ||
| 1441 | |||
| 1442 | if (!vm_manager.IsWithinASLRRegion(dst_address, size)) { | ||
| 1443 | LOG_ERROR(Kernel_SVC, | ||
| 1444 | "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " | ||
| 1445 | "size=0x{:016X}).", | ||
| 1446 | dst_address, size); | ||
| 1447 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | return vm_manager.UnmapCodeMemory(dst_address, src_address, size); | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | /// Exits the current process | 1232 | /// Exits the current process |
| 1454 | static void ExitProcess(Core::System& system) { | 1233 | static void ExitProcess(Core::System& system) { |
| 1455 | auto* current_process = system.Kernel().CurrentProcess(); | 1234 | auto* current_process = system.Kernel().CurrentProcess(); |
| @@ -1506,6 +1285,9 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1506 | } | 1285 | } |
| 1507 | 1286 | ||
| 1508 | auto& kernel = system.Kernel(); | 1287 | auto& kernel = system.Kernel(); |
| 1288 | |||
| 1289 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Threads, 1)); | ||
| 1290 | |||
| 1509 | CASCADE_RESULT(std::shared_ptr<Thread> thread, | 1291 | CASCADE_RESULT(std::shared_ptr<Thread> thread, |
| 1510 | Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top, | 1292 | Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top, |
| 1511 | *current_process)); | 1293 | *current_process)); |
| @@ -1610,7 +1392,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | |||
| 1610 | "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", | 1392 | "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", |
| 1611 | mutex_addr, condition_variable_addr, thread_handle, nano_seconds); | 1393 | mutex_addr, condition_variable_addr, thread_handle, nano_seconds); |
| 1612 | 1394 | ||
| 1613 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 1395 | if (Core::Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 1614 | LOG_ERROR( | 1396 | LOG_ERROR( |
| 1615 | Kernel_SVC, | 1397 | Kernel_SVC, |
| 1616 | "Given mutex address must not be within the kernel address space. address=0x{:016X}", | 1398 | "Given mutex address must not be within the kernel address space. address=0x{:016X}", |
| @@ -1741,7 +1523,7 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, u32 type, | |||
| 1741 | type, value, timeout); | 1523 | type, value, timeout); |
| 1742 | 1524 | ||
| 1743 | // If the passed address is a kernel virtual address, return invalid memory state. | 1525 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 1744 | if (Memory::IsKernelVirtualAddress(address)) { | 1526 | if (Core::Memory::IsKernelVirtualAddress(address)) { |
| 1745 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); | 1527 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); |
| 1746 | return ERR_INVALID_ADDRESS_STATE; | 1528 | return ERR_INVALID_ADDRESS_STATE; |
| 1747 | } | 1529 | } |
| @@ -1769,7 +1551,7 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, u32 type, | |||
| 1769 | address, type, value, num_to_wake); | 1551 | address, type, value, num_to_wake); |
| 1770 | 1552 | ||
| 1771 | // If the passed address is a kernel virtual address, return invalid memory state. | 1553 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 1772 | if (Memory::IsKernelVirtualAddress(address)) { | 1554 | if (Core::Memory::IsKernelVirtualAddress(address)) { |
| 1773 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); | 1555 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); |
| 1774 | return ERR_INVALID_ADDRESS_STATE; | 1556 | return ERR_INVALID_ADDRESS_STATE; |
| 1775 | } | 1557 | } |
| @@ -1865,9 +1647,9 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1865 | return ERR_INVALID_ADDRESS_STATE; | 1647 | return ERR_INVALID_ADDRESS_STATE; |
| 1866 | } | 1648 | } |
| 1867 | 1649 | ||
| 1868 | const auto perms = static_cast<MemoryPermission>(permissions); | 1650 | const auto perms{static_cast<Memory::MemoryPermission>(permissions)}; |
| 1869 | if (perms != MemoryPermission::None && perms != MemoryPermission::Read && | 1651 | if (perms > Memory::MemoryPermission::ReadAndWrite || |
| 1870 | perms != MemoryPermission::ReadWrite) { | 1652 | perms == Memory::MemoryPermission::Write) { |
| 1871 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", | 1653 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", |
| 1872 | permissions); | 1654 | permissions); |
| 1873 | return ERR_INVALID_MEMORY_PERMISSIONS; | 1655 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| @@ -1890,111 +1672,6 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1890 | return RESULT_SUCCESS; | 1672 | return RESULT_SUCCESS; |
| 1891 | } | 1673 | } |
| 1892 | 1674 | ||
| 1893 | static ResultCode MapTransferMemory(Core::System& system, Handle handle, VAddr address, u64 size, | ||
| 1894 | u32 permission_raw) { | ||
| 1895 | LOG_DEBUG(Kernel_SVC, | ||
| 1896 | "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}, permissions=0x{:08X}", | ||
| 1897 | handle, address, size, permission_raw); | ||
| 1898 | |||
| 1899 | if (!Common::Is4KBAligned(address)) { | ||
| 1900 | LOG_ERROR(Kernel_SVC, "Transfer memory addresses must be 4KB aligned (size=0x{:016X}).", | ||
| 1901 | address); | ||
| 1902 | return ERR_INVALID_ADDRESS; | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | if (size == 0 || !Common::Is4KBAligned(size)) { | ||
| 1906 | LOG_ERROR(Kernel_SVC, | ||
| 1907 | "Transfer memory sizes must be 4KB aligned and not be zero (size=0x{:016X}).", | ||
| 1908 | size); | ||
| 1909 | return ERR_INVALID_SIZE; | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | if (!IsValidAddressRange(address, size)) { | ||
| 1913 | LOG_ERROR(Kernel_SVC, | ||
| 1914 | "Given address and size overflows the 64-bit range (address=0x{:016X}, " | ||
| 1915 | "size=0x{:016X}).", | ||
| 1916 | address, size); | ||
| 1917 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1918 | } | ||
| 1919 | |||
| 1920 | const auto permissions = static_cast<MemoryPermission>(permission_raw); | ||
| 1921 | if (permissions != MemoryPermission::None && permissions != MemoryPermission::Read && | ||
| 1922 | permissions != MemoryPermission::ReadWrite) { | ||
| 1923 | LOG_ERROR(Kernel_SVC, "Invalid transfer memory permissions given (permissions=0x{:08X}).", | ||
| 1924 | permission_raw); | ||
| 1925 | return ERR_INVALID_STATE; | ||
| 1926 | } | ||
| 1927 | |||
| 1928 | const auto& kernel = system.Kernel(); | ||
| 1929 | const auto* const current_process = kernel.CurrentProcess(); | ||
| 1930 | const auto& handle_table = current_process->GetHandleTable(); | ||
| 1931 | |||
| 1932 | auto transfer_memory = handle_table.Get<TransferMemory>(handle); | ||
| 1933 | if (!transfer_memory) { | ||
| 1934 | LOG_ERROR(Kernel_SVC, "Nonexistent transfer memory handle given (handle=0x{:08X}).", | ||
| 1935 | handle); | ||
| 1936 | return ERR_INVALID_HANDLE; | ||
| 1937 | } | ||
| 1938 | |||
| 1939 | if (!current_process->VMManager().IsWithinASLRRegion(address, size)) { | ||
| 1940 | LOG_ERROR(Kernel_SVC, | ||
| 1941 | "Given address and size don't fully fit within the ASLR region " | ||
| 1942 | "(address=0x{:016X}, size=0x{:016X}).", | ||
| 1943 | address, size); | ||
| 1944 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1945 | } | ||
| 1946 | |||
| 1947 | return transfer_memory->MapMemory(address, size, permissions); | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | static ResultCode UnmapTransferMemory(Core::System& system, Handle handle, VAddr address, | ||
| 1951 | u64 size) { | ||
| 1952 | LOG_DEBUG(Kernel_SVC, "called. handle=0x{:08X}, address=0x{:016X}, size=0x{:016X}", handle, | ||
| 1953 | address, size); | ||
| 1954 | |||
| 1955 | if (!Common::Is4KBAligned(address)) { | ||
| 1956 | LOG_ERROR(Kernel_SVC, "Transfer memory addresses must be 4KB aligned (size=0x{:016X}).", | ||
| 1957 | address); | ||
| 1958 | return ERR_INVALID_ADDRESS; | ||
| 1959 | } | ||
| 1960 | |||
| 1961 | if (size == 0 || !Common::Is4KBAligned(size)) { | ||
| 1962 | LOG_ERROR(Kernel_SVC, | ||
| 1963 | "Transfer memory sizes must be 4KB aligned and not be zero (size=0x{:016X}).", | ||
| 1964 | size); | ||
| 1965 | return ERR_INVALID_SIZE; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | if (!IsValidAddressRange(address, size)) { | ||
| 1969 | LOG_ERROR(Kernel_SVC, | ||
| 1970 | "Given address and size overflows the 64-bit range (address=0x{:016X}, " | ||
| 1971 | "size=0x{:016X}).", | ||
| 1972 | address, size); | ||
| 1973 | return ERR_INVALID_ADDRESS_STATE; | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | const auto& kernel = system.Kernel(); | ||
| 1977 | const auto* const current_process = kernel.CurrentProcess(); | ||
| 1978 | const auto& handle_table = current_process->GetHandleTable(); | ||
| 1979 | |||
| 1980 | auto transfer_memory = handle_table.Get<TransferMemory>(handle); | ||
| 1981 | if (!transfer_memory) { | ||
| 1982 | LOG_ERROR(Kernel_SVC, "Nonexistent transfer memory handle given (handle=0x{:08X}).", | ||
| 1983 | handle); | ||
| 1984 | return ERR_INVALID_HANDLE; | ||
| 1985 | } | ||
| 1986 | |||
| 1987 | if (!current_process->VMManager().IsWithinASLRRegion(address, size)) { | ||
| 1988 | LOG_ERROR(Kernel_SVC, | ||
| 1989 | "Given address and size don't fully fit within the ASLR region " | ||
| 1990 | "(address=0x{:016X}, size=0x{:016X}).", | ||
| 1991 | address, size); | ||
| 1992 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1993 | } | ||
| 1994 | |||
| 1995 | return transfer_memory->UnmapMemory(address, size); | ||
| 1996 | } | ||
| 1997 | |||
| 1998 | static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, u32* core, | 1675 | static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, u32* core, |
| 1999 | u64* mask) { | 1676 | u64* mask) { |
| 2000 | LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); | 1677 | LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); |
| @@ -2073,52 +1750,6 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, | |||
| 2073 | return RESULT_SUCCESS; | 1750 | return RESULT_SUCCESS; |
| 2074 | } | 1751 | } |
| 2075 | 1752 | ||
| 2076 | static ResultCode CreateSharedMemory(Core::System& system, Handle* handle, u64 size, | ||
| 2077 | u32 local_permissions, u32 remote_permissions) { | ||
| 2078 | LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, | ||
| 2079 | local_permissions, remote_permissions); | ||
| 2080 | if (size == 0) { | ||
| 2081 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 2082 | return ERR_INVALID_SIZE; | ||
| 2083 | } | ||
| 2084 | if (!Common::Is4KBAligned(size)) { | ||
| 2085 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:016X}", size); | ||
| 2086 | return ERR_INVALID_SIZE; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | if (size >= MAIN_MEMORY_SIZE) { | ||
| 2090 | LOG_ERROR(Kernel_SVC, "Size is not less than 8GB, 0x{:016X}", size); | ||
| 2091 | return ERR_INVALID_SIZE; | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | const auto local_perms = static_cast<MemoryPermission>(local_permissions); | ||
| 2095 | if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) { | ||
| 2096 | LOG_ERROR(Kernel_SVC, | ||
| 2097 | "Invalid local memory permissions, expected Read or ReadWrite but got " | ||
| 2098 | "local_permissions={}", | ||
| 2099 | static_cast<u32>(local_permissions)); | ||
| 2100 | return ERR_INVALID_MEMORY_PERMISSIONS; | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | const auto remote_perms = static_cast<MemoryPermission>(remote_permissions); | ||
| 2104 | if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite && | ||
| 2105 | remote_perms != MemoryPermission::DontCare) { | ||
| 2106 | LOG_ERROR(Kernel_SVC, | ||
| 2107 | "Invalid remote memory permissions, expected Read, ReadWrite or DontCare but got " | ||
| 2108 | "remote_permissions={}", | ||
| 2109 | static_cast<u32>(remote_permissions)); | ||
| 2110 | return ERR_INVALID_MEMORY_PERMISSIONS; | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | auto& kernel = system.Kernel(); | ||
| 2114 | auto process = kernel.CurrentProcess(); | ||
| 2115 | auto& handle_table = process->GetHandleTable(); | ||
| 2116 | auto shared_mem_handle = SharedMemory::Create(kernel, process, size, local_perms, remote_perms); | ||
| 2117 | |||
| 2118 | CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle)); | ||
| 2119 | return RESULT_SUCCESS; | ||
| 2120 | } | ||
| 2121 | |||
| 2122 | static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) { | 1753 | static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) { |
| 2123 | LOG_DEBUG(Kernel_SVC, "called"); | 1754 | LOG_DEBUG(Kernel_SVC, "called"); |
| 2124 | 1755 | ||
| @@ -2305,11 +1936,10 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, | |||
| 2305 | } | 1936 | } |
| 2306 | 1937 | ||
| 2307 | const auto& kernel = system.Kernel(); | 1938 | const auto& kernel = system.Kernel(); |
| 2308 | const auto& vm_manager = kernel.CurrentProcess()->VMManager(); | ||
| 2309 | const auto total_copy_size = out_process_ids_size * sizeof(u64); | 1939 | const auto total_copy_size = out_process_ids_size * sizeof(u64); |
| 2310 | 1940 | ||
| 2311 | if (out_process_ids_size > 0 && | 1941 | if (out_process_ids_size > 0 && !kernel.CurrentProcess()->PageTable().IsInsideAddressSpace( |
| 2312 | !vm_manager.IsWithinAddressSpace(out_process_ids, total_copy_size)) { | 1942 | out_process_ids, total_copy_size)) { |
| 2313 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | 1943 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", |
| 2314 | out_process_ids, out_process_ids + total_copy_size); | 1944 | out_process_ids, out_process_ids + total_copy_size); |
| 2315 | return ERR_INVALID_ADDRESS_STATE; | 1945 | return ERR_INVALID_ADDRESS_STATE; |
| @@ -2345,11 +1975,10 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2345 | } | 1975 | } |
| 2346 | 1976 | ||
| 2347 | const auto* const current_process = system.Kernel().CurrentProcess(); | 1977 | const auto* const current_process = system.Kernel().CurrentProcess(); |
| 2348 | const auto& vm_manager = current_process->VMManager(); | ||
| 2349 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); | 1978 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); |
| 2350 | 1979 | ||
| 2351 | if (out_thread_ids_size > 0 && | 1980 | if (out_thread_ids_size > 0 && |
| 2352 | !vm_manager.IsWithinAddressSpace(out_thread_ids, total_copy_size)) { | 1981 | !current_process->PageTable().IsInsideAddressSpace(out_thread_ids, total_copy_size)) { |
| 2353 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", | 1982 | LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}", |
| 2354 | out_thread_ids, out_thread_ids + total_copy_size); | 1983 | out_thread_ids, out_thread_ids + total_copy_size); |
| 2355 | return ERR_INVALID_ADDRESS_STATE; | 1984 | return ERR_INVALID_ADDRESS_STATE; |
| @@ -2510,7 +2139,7 @@ static const FunctionDef SVC_Table_32[] = { | |||
| 2510 | static const FunctionDef SVC_Table_64[] = { | 2139 | static const FunctionDef SVC_Table_64[] = { |
| 2511 | {0x00, nullptr, "Unknown"}, | 2140 | {0x00, nullptr, "Unknown"}, |
| 2512 | {0x01, SvcWrap64<SetHeapSize>, "SetHeapSize"}, | 2141 | {0x01, SvcWrap64<SetHeapSize>, "SetHeapSize"}, |
| 2513 | {0x02, SvcWrap64<SetMemoryPermission>, "SetMemoryPermission"}, | 2142 | {0x02, nullptr, "SetMemoryPermission"}, |
| 2514 | {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, | 2143 | {0x03, SvcWrap64<SetMemoryAttribute>, "SetMemoryAttribute"}, |
| 2515 | {0x04, SvcWrap64<MapMemory>, "MapMemory"}, | 2144 | {0x04, SvcWrap64<MapMemory>, "MapMemory"}, |
| 2516 | {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, | 2145 | {0x05, SvcWrap64<UnmapMemory>, "UnmapMemory"}, |
| @@ -2528,7 +2157,7 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2528 | {0x11, SvcWrap64<SignalEvent>, "SignalEvent"}, | 2157 | {0x11, SvcWrap64<SignalEvent>, "SignalEvent"}, |
| 2529 | {0x12, SvcWrap64<ClearEvent>, "ClearEvent"}, | 2158 | {0x12, SvcWrap64<ClearEvent>, "ClearEvent"}, |
| 2530 | {0x13, SvcWrap64<MapSharedMemory>, "MapSharedMemory"}, | 2159 | {0x13, SvcWrap64<MapSharedMemory>, "MapSharedMemory"}, |
| 2531 | {0x14, SvcWrap64<UnmapSharedMemory>, "UnmapSharedMemory"}, | 2160 | {0x14, nullptr, "UnmapSharedMemory"}, |
| 2532 | {0x15, SvcWrap64<CreateTransferMemory>, "CreateTransferMemory"}, | 2161 | {0x15, SvcWrap64<CreateTransferMemory>, "CreateTransferMemory"}, |
| 2533 | {0x16, SvcWrap64<CloseHandle>, "CloseHandle"}, | 2162 | {0x16, SvcWrap64<CloseHandle>, "CloseHandle"}, |
| 2534 | {0x17, SvcWrap64<ResetSignal>, "ResetSignal"}, | 2163 | {0x17, SvcWrap64<ResetSignal>, "ResetSignal"}, |
| @@ -2588,9 +2217,9 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2588 | {0x4D, nullptr, "SleepSystem"}, | 2217 | {0x4D, nullptr, "SleepSystem"}, |
| 2589 | {0x4E, nullptr, "ReadWriteRegister"}, | 2218 | {0x4E, nullptr, "ReadWriteRegister"}, |
| 2590 | {0x4F, nullptr, "SetProcessActivity"}, | 2219 | {0x4F, nullptr, "SetProcessActivity"}, |
| 2591 | {0x50, SvcWrap64<CreateSharedMemory>, "CreateSharedMemory"}, | 2220 | {0x50, nullptr, "CreateSharedMemory"}, |
| 2592 | {0x51, SvcWrap64<MapTransferMemory>, "MapTransferMemory"}, | 2221 | {0x51, nullptr, "MapTransferMemory"}, |
| 2593 | {0x52, SvcWrap64<UnmapTransferMemory>, "UnmapTransferMemory"}, | 2222 | {0x52, nullptr, "UnmapTransferMemory"}, |
| 2594 | {0x53, nullptr, "CreateInterruptEvent"}, | 2223 | {0x53, nullptr, "CreateInterruptEvent"}, |
| 2595 | {0x54, nullptr, "QueryPhysicalAddress"}, | 2224 | {0x54, nullptr, "QueryPhysicalAddress"}, |
| 2596 | {0x55, nullptr, "QueryIoMapping"}, | 2225 | {0x55, nullptr, "QueryIoMapping"}, |
| @@ -2627,8 +2256,8 @@ static const FunctionDef SVC_Table_64[] = { | |||
| 2627 | {0x74, nullptr, "MapProcessMemory"}, | 2256 | {0x74, nullptr, "MapProcessMemory"}, |
| 2628 | {0x75, nullptr, "UnmapProcessMemory"}, | 2257 | {0x75, nullptr, "UnmapProcessMemory"}, |
| 2629 | {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, | 2258 | {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, |
| 2630 | {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"}, | 2259 | {0x77, nullptr, "MapProcessCodeMemory"}, |
| 2631 | {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"}, | 2260 | {0x78, nullptr, "UnmapProcessCodeMemory"}, |
| 2632 | {0x79, nullptr, "CreateProcess"}, | 2261 | {0x79, nullptr, "CreateProcess"}, |
| 2633 | {0x7A, nullptr, "StartProcess"}, | 2262 | {0x7A, nullptr, "StartProcess"}, |
| 2634 | {0x7B, nullptr, "TerminateProcess"}, | 2263 | {0x7B, nullptr, "TerminateProcess"}, |
| @@ -2656,7 +2285,7 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) { | |||
| 2656 | 2285 | ||
| 2657 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | 2286 | MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); |
| 2658 | 2287 | ||
| 2659 | void CallSVC(Core::System& system, u32 immediate) { | 2288 | void Call(Core::System& system, u32 immediate) { |
| 2660 | MICROPROFILE_SCOPE(Kernel_SVC); | 2289 | MICROPROFILE_SCOPE(Kernel_SVC); |
| 2661 | 2290 | ||
| 2662 | // Lock the global kernel mutex when we enter the kernel HLE. | 2291 | // Lock the global kernel mutex when we enter the kernel HLE. |
| @@ -2675,4 +2304,4 @@ void CallSVC(Core::System& system, u32 immediate) { | |||
| 2675 | } | 2304 | } |
| 2676 | } | 2305 | } |
| 2677 | 2306 | ||
| 2678 | } // namespace Kernel | 2307 | } // namespace Kernel::Svc |