diff options
| author | 2018-11-29 00:58:46 -0500 | |
|---|---|---|
| committer | 2018-11-29 00:58:46 -0500 | |
| commit | 1e49a85106acdc596db9d1aeca31104fab9552a2 (patch) | |
| tree | 7e295e2921c61866371ac52d63a807782b1094b6 /src/core/hle/kernel | |
| parent | Merge pull request #1808 from Tinob/master (diff) | |
| parent | Added comment on Main memory size for more clarity (diff) | |
| download | yuzu-1e49a85106acdc596db9d1aeca31104fab9552a2.tar.gz yuzu-1e49a85106acdc596db9d1aeca31104fab9552a2.tar.xz yuzu-1e49a85106acdc596db9d1aeca31104fab9552a2.zip | |
Merge pull request #1801 from ogniK5377/log-before-execute
Changed logging to be "Log before execution", Added more error logging, all services/svc should now log on some level
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 230 |
1 files changed, 206 insertions, 24 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 1f19d5576..5e9660a48 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -63,43 +63,77 @@ bool IsInsideNewMapRegion(const VMManager& vm, VAddr address, u64 size) { | |||
| 63 | vm.GetNewMapRegionEndAddress()); | 63 | vm.GetNewMapRegionEndAddress()); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | // 8 GiB | ||
| 67 | constexpr u64 MAIN_MEMORY_SIZE = 0x200000000; | ||
| 68 | |||
| 66 | // Helper function that performs the common sanity checks for svcMapMemory | 69 | // Helper function that performs the common sanity checks for svcMapMemory |
| 67 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing | 70 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing |
| 68 | // in the same order. | 71 | // in the same order. |
| 69 | ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_addr, VAddr src_addr, | 72 | ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_addr, VAddr src_addr, |
| 70 | u64 size) { | 73 | u64 size) { |
| 71 | if (!Common::Is4KBAligned(dst_addr) || !Common::Is4KBAligned(src_addr)) { | 74 | if (!Common::Is4KBAligned(dst_addr)) { |
| 75 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); | ||
| 72 | return ERR_INVALID_ADDRESS; | 76 | return ERR_INVALID_ADDRESS; |
| 73 | } | 77 | } |
| 74 | 78 | ||
| 75 | if (size == 0 || !Common::Is4KBAligned(size)) { | 79 | if (!Common::Is4KBAligned(src_addr)) { |
| 80 | LOG_ERROR(Kernel_SVC, "Source address is not aligned to 4KB, 0x{:016X}", src_addr); | ||
| 81 | return ERR_INVALID_SIZE; | ||
| 82 | } | ||
| 83 | |||
| 84 | if (size == 0) { | ||
| 85 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 86 | return ERR_INVALID_SIZE; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (!Common::Is4KBAligned(size)) { | ||
| 90 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:016X}", size); | ||
| 76 | return ERR_INVALID_SIZE; | 91 | return ERR_INVALID_SIZE; |
| 77 | } | 92 | } |
| 78 | 93 | ||
| 79 | if (!IsValidAddressRange(dst_addr, size)) { | 94 | if (!IsValidAddressRange(dst_addr, size)) { |
| 95 | LOG_ERROR(Kernel_SVC, | ||
| 96 | "Destination is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | ||
| 97 | dst_addr, size); | ||
| 80 | return ERR_INVALID_ADDRESS_STATE; | 98 | return ERR_INVALID_ADDRESS_STATE; |
| 81 | } | 99 | } |
| 82 | 100 | ||
| 83 | if (!IsValidAddressRange(src_addr, size)) { | 101 | if (!IsValidAddressRange(src_addr, size)) { |
| 102 | LOG_ERROR(Kernel_SVC, "Source is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | ||
| 103 | src_addr, size); | ||
| 84 | return ERR_INVALID_ADDRESS_STATE; | 104 | return ERR_INVALID_ADDRESS_STATE; |
| 85 | } | 105 | } |
| 86 | 106 | ||
| 87 | if (!IsInsideAddressSpace(vm_manager, src_addr, size)) { | 107 | if (!IsInsideAddressSpace(vm_manager, src_addr, size)) { |
| 108 | LOG_ERROR(Kernel_SVC, | ||
| 109 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", | ||
| 110 | src_addr, size); | ||
| 88 | return ERR_INVALID_ADDRESS_STATE; | 111 | return ERR_INVALID_ADDRESS_STATE; |
| 89 | } | 112 | } |
| 90 | 113 | ||
| 91 | if (!IsInsideNewMapRegion(vm_manager, dst_addr, size)) { | 114 | if (!IsInsideNewMapRegion(vm_manager, dst_addr, size)) { |
| 115 | LOG_ERROR(Kernel_SVC, | ||
| 116 | "Destination is not within the new map region, addr=0x{:016X}, size=0x{:016X}", | ||
| 117 | dst_addr, size); | ||
| 92 | return ERR_INVALID_MEMORY_RANGE; | 118 | return ERR_INVALID_MEMORY_RANGE; |
| 93 | } | 119 | } |
| 94 | 120 | ||
| 95 | const VAddr dst_end_address = dst_addr + size; | 121 | const VAddr dst_end_address = dst_addr + size; |
| 96 | if (dst_end_address > vm_manager.GetHeapRegionBaseAddress() && | 122 | if (dst_end_address > vm_manager.GetHeapRegionBaseAddress() && |
| 97 | vm_manager.GetHeapRegionEndAddress() > dst_addr) { | 123 | vm_manager.GetHeapRegionEndAddress() > dst_addr) { |
| 124 | LOG_ERROR(Kernel_SVC, | ||
| 125 | "Destination does not fit within the heap region, addr=0x{:016X}, " | ||
| 126 | "size=0x{:016X}, end_addr=0x{:016X}", | ||
| 127 | dst_addr, size, dst_end_address); | ||
| 98 | return ERR_INVALID_MEMORY_RANGE; | 128 | return ERR_INVALID_MEMORY_RANGE; |
| 99 | } | 129 | } |
| 100 | 130 | ||
| 101 | if (dst_end_address > vm_manager.GetMapRegionBaseAddress() && | 131 | if (dst_end_address > vm_manager.GetMapRegionBaseAddress() && |
| 102 | vm_manager.GetMapRegionEndAddress() > dst_addr) { | 132 | vm_manager.GetMapRegionEndAddress() > dst_addr) { |
| 133 | LOG_ERROR(Kernel_SVC, | ||
| 134 | "Destination does not fit within the map region, addr=0x{:016X}, " | ||
| 135 | "size=0x{:016X}, end_addr=0x{:016X}", | ||
| 136 | dst_addr, size, dst_end_address); | ||
| 103 | return ERR_INVALID_MEMORY_RANGE; | 137 | return ERR_INVALID_MEMORY_RANGE; |
| 104 | } | 138 | } |
| 105 | 139 | ||
| @@ -143,8 +177,15 @@ ResultVal<s64> RetrieveResourceLimitValue(Handle resource_limit, u32 resource_ty | |||
| 143 | static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { | 177 | static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { |
| 144 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); | 178 | LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size); |
| 145 | 179 | ||
| 146 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 4GB. | 180 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 8GB. |
| 147 | if ((heap_size & 0xFFFFFFFE001FFFFF) != 0) { | 181 | if ((heap_size % 0x200000) != 0) { |
| 182 | LOG_ERROR(Kernel_SVC, "The heap size is not a multiple of 2MB, heap_size=0x{:016X}", | ||
| 183 | heap_size); | ||
| 184 | return ERR_INVALID_SIZE; | ||
| 185 | } | ||
| 186 | |||
| 187 | if (heap_size >= 0x200000000) { | ||
| 188 | LOG_ERROR(Kernel_SVC, "The heap size is not less than 8GB, heap_size=0x{:016X}", heap_size); | ||
| 148 | return ERR_INVALID_SIZE; | 189 | return ERR_INVALID_SIZE; |
| 149 | } | 190 | } |
| 150 | 191 | ||
| @@ -159,20 +200,31 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | |||
| 159 | LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); | 200 | LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); |
| 160 | 201 | ||
| 161 | if (!Common::Is4KBAligned(addr)) { | 202 | if (!Common::Is4KBAligned(addr)) { |
| 203 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, addr=0x{:016X}", addr); | ||
| 162 | return ERR_INVALID_ADDRESS; | 204 | return ERR_INVALID_ADDRESS; |
| 163 | } | 205 | } |
| 164 | 206 | ||
| 165 | if (size == 0 || !Common::Is4KBAligned(size)) { | 207 | if (size == 0) { |
| 208 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 209 | return ERR_INVALID_SIZE; | ||
| 210 | } | ||
| 211 | |||
| 212 | if (!Common::Is4KBAligned(size)) { | ||
| 213 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, size=0x{:016X}", size); | ||
| 166 | return ERR_INVALID_SIZE; | 214 | return ERR_INVALID_SIZE; |
| 167 | } | 215 | } |
| 168 | 216 | ||
| 169 | if (!IsValidAddressRange(addr, size)) { | 217 | if (!IsValidAddressRange(addr, size)) { |
| 218 | LOG_ERROR(Kernel_SVC, "Region is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | ||
| 219 | addr, size); | ||
| 170 | return ERR_INVALID_ADDRESS_STATE; | 220 | return ERR_INVALID_ADDRESS_STATE; |
| 171 | } | 221 | } |
| 172 | 222 | ||
| 173 | const auto permission = static_cast<MemoryPermission>(prot); | 223 | const auto permission = static_cast<MemoryPermission>(prot); |
| 174 | if (permission != MemoryPermission::None && permission != MemoryPermission::Read && | 224 | if (permission != MemoryPermission::None && permission != MemoryPermission::Read && |
| 175 | permission != MemoryPermission::ReadWrite) { | 225 | permission != MemoryPermission::ReadWrite) { |
| 226 | LOG_ERROR(Kernel_SVC, "Invalid memory permission specified, Got memory permission=0x{:08X}", | ||
| 227 | static_cast<u32>(permission)); | ||
| 176 | return ERR_INVALID_MEMORY_PERMISSIONS; | 228 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 177 | } | 229 | } |
| 178 | 230 | ||
| @@ -180,11 +232,15 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | |||
| 180 | auto& vm_manager = current_process->VMManager(); | 232 | auto& vm_manager = current_process->VMManager(); |
| 181 | 233 | ||
| 182 | if (!IsInsideAddressSpace(vm_manager, addr, size)) { | 234 | if (!IsInsideAddressSpace(vm_manager, addr, size)) { |
| 235 | LOG_ERROR(Kernel_SVC, | ||
| 236 | "Source is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, | ||
| 237 | size); | ||
| 183 | return ERR_INVALID_ADDRESS_STATE; | 238 | return ERR_INVALID_ADDRESS_STATE; |
| 184 | } | 239 | } |
| 185 | 240 | ||
| 186 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); | 241 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); |
| 187 | if (iter == vm_manager.vma_map.end()) { | 242 | if (iter == vm_manager.vma_map.end()) { |
| 243 | LOG_ERROR(Kernel_SVC, "Unable to find VMA for address=0x{:016X}", addr); | ||
| 188 | return ERR_INVALID_ADDRESS_STATE; | 244 | return ERR_INVALID_ADDRESS_STATE; |
| 189 | } | 245 | } |
| 190 | 246 | ||
| @@ -239,6 +295,9 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | |||
| 239 | /// Connect to an OS service given the port name, returns the handle to the port to out | 295 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 240 | static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { | 296 | static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { |
| 241 | if (!Memory::IsValidVirtualAddress(port_name_address)) { | 297 | if (!Memory::IsValidVirtualAddress(port_name_address)) { |
| 298 | LOG_ERROR(Kernel_SVC, | ||
| 299 | "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", | ||
| 300 | port_name_address); | ||
| 242 | return ERR_NOT_FOUND; | 301 | return ERR_NOT_FOUND; |
| 243 | } | 302 | } |
| 244 | 303 | ||
| @@ -246,6 +305,8 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address | |||
| 246 | // Read 1 char beyond the max allowed port name to detect names that are too long. | 305 | // Read 1 char beyond the max allowed port name to detect names that are too long. |
| 247 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | 306 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); |
| 248 | if (port_name.size() > PortNameMaxLength) { | 307 | if (port_name.size() > PortNameMaxLength) { |
| 308 | LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, | ||
| 309 | port_name.size()); | ||
| 249 | return ERR_OUT_OF_RANGE; | 310 | return ERR_OUT_OF_RANGE; |
| 250 | } | 311 | } |
| 251 | 312 | ||
| @@ -294,6 +355,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | |||
| 294 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 355 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 295 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 356 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 296 | if (!thread) { | 357 | if (!thread) { |
| 358 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle); | ||
| 297 | return ERR_INVALID_HANDLE; | 359 | return ERR_INVALID_HANDLE; |
| 298 | } | 360 | } |
| 299 | 361 | ||
| @@ -308,6 +370,8 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | |||
| 308 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 370 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 309 | const SharedPtr<Process> process = handle_table.Get<Process>(process_handle); | 371 | const SharedPtr<Process> process = handle_table.Get<Process>(process_handle); |
| 310 | if (!process) { | 372 | if (!process) { |
| 373 | LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", | ||
| 374 | process_handle); | ||
| 311 | return ERR_INVALID_HANDLE; | 375 | return ERR_INVALID_HANDLE; |
| 312 | } | 376 | } |
| 313 | 377 | ||
| @@ -337,12 +401,18 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 337 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", | 401 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", |
| 338 | handles_address, handle_count, nano_seconds); | 402 | handles_address, handle_count, nano_seconds); |
| 339 | 403 | ||
| 340 | if (!Memory::IsValidVirtualAddress(handles_address)) | 404 | if (!Memory::IsValidVirtualAddress(handles_address)) { |
| 405 | LOG_ERROR(Kernel_SVC, | ||
| 406 | "Handle address is not a valid virtual address, handle_address=0x{:016X}", | ||
| 407 | handles_address); | ||
| 341 | return ERR_INVALID_POINTER; | 408 | return ERR_INVALID_POINTER; |
| 409 | } | ||
| 342 | 410 | ||
| 343 | static constexpr u64 MaxHandles = 0x40; | 411 | static constexpr u64 MaxHandles = 0x40; |
| 344 | 412 | ||
| 345 | if (handle_count > MaxHandles) { | 413 | if (handle_count > MaxHandles) { |
| 414 | LOG_ERROR(Kernel_SVC, "Handle count specified is too large, expected {} but got {}", | ||
| 415 | MaxHandles, handle_count); | ||
| 346 | return ERR_OUT_OF_RANGE; | 416 | return ERR_OUT_OF_RANGE; |
| 347 | } | 417 | } |
| 348 | 418 | ||
| @@ -357,6 +427,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 357 | const auto object = handle_table.Get<WaitObject>(handle); | 427 | const auto object = handle_table.Get<WaitObject>(handle); |
| 358 | 428 | ||
| 359 | if (object == nullptr) { | 429 | if (object == nullptr) { |
| 430 | LOG_ERROR(Kernel_SVC, "Object is a nullptr"); | ||
| 360 | return ERR_INVALID_HANDLE; | 431 | return ERR_INVALID_HANDLE; |
| 361 | } | 432 | } |
| 362 | 433 | ||
| @@ -380,11 +451,13 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 380 | 451 | ||
| 381 | // If a timeout value of 0 was provided, just return the Timeout error code instead of | 452 | // If a timeout value of 0 was provided, just return the Timeout error code instead of |
| 382 | // suspending the thread. | 453 | // suspending the thread. |
| 383 | if (nano_seconds == 0) | 454 | if (nano_seconds == 0) { |
| 384 | return RESULT_TIMEOUT; | 455 | return RESULT_TIMEOUT; |
| 456 | } | ||
| 385 | 457 | ||
| 386 | for (auto& object : objects) | 458 | for (auto& object : objects) { |
| 387 | object->AddWaitingThread(thread); | 459 | object->AddWaitingThread(thread); |
| 460 | } | ||
| 388 | 461 | ||
| 389 | thread->SetWaitObjects(std::move(objects)); | 462 | thread->SetWaitObjects(std::move(objects)); |
| 390 | thread->SetStatus(ThreadStatus::WaitSynchAny); | 463 | thread->SetStatus(ThreadStatus::WaitSynchAny); |
| @@ -405,6 +478,8 @@ static ResultCode CancelSynchronization(Handle thread_handle) { | |||
| 405 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 478 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 406 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 479 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 407 | if (!thread) { | 480 | if (!thread) { |
| 481 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||
| 482 | thread_handle); | ||
| 408 | return ERR_INVALID_HANDLE; | 483 | return ERR_INVALID_HANDLE; |
| 409 | } | 484 | } |
| 410 | 485 | ||
| @@ -423,10 +498,13 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, | |||
| 423 | holding_thread_handle, mutex_addr, requesting_thread_handle); | 498 | holding_thread_handle, mutex_addr, requesting_thread_handle); |
| 424 | 499 | ||
| 425 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 500 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 501 | LOG_ERROR(Kernel_SVC, "Mutex Address is a kernel virtual address, mutex_addr={:016X}", | ||
| 502 | mutex_addr); | ||
| 426 | return ERR_INVALID_ADDRESS_STATE; | 503 | return ERR_INVALID_ADDRESS_STATE; |
| 427 | } | 504 | } |
| 428 | 505 | ||
| 429 | if (!Common::IsWordAligned(mutex_addr)) { | 506 | if (!Common::IsWordAligned(mutex_addr)) { |
| 507 | LOG_ERROR(Kernel_SVC, "Mutex Address is not word aligned, mutex_addr={:016X}", mutex_addr); | ||
| 430 | return ERR_INVALID_ADDRESS; | 508 | return ERR_INVALID_ADDRESS; |
| 431 | } | 509 | } |
| 432 | 510 | ||
| @@ -440,10 +518,13 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) { | |||
| 440 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); | 518 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); |
| 441 | 519 | ||
| 442 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 520 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 521 | LOG_ERROR(Kernel_SVC, "Mutex Address is a kernel virtual address, mutex_addr={:016X}", | ||
| 522 | mutex_addr); | ||
| 443 | return ERR_INVALID_ADDRESS_STATE; | 523 | return ERR_INVALID_ADDRESS_STATE; |
| 444 | } | 524 | } |
| 445 | 525 | ||
| 446 | if (!Common::IsWordAligned(mutex_addr)) { | 526 | if (!Common::IsWordAligned(mutex_addr)) { |
| 527 | LOG_ERROR(Kernel_SVC, "Mutex Address is not word aligned, mutex_addr={:016X}", mutex_addr); | ||
| 447 | return ERR_INVALID_ADDRESS; | 528 | return ERR_INVALID_ADDRESS; |
| 448 | } | 529 | } |
| 449 | 530 | ||
| @@ -634,10 +715,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 634 | break; | 715 | break; |
| 635 | case GetInfoType::RandomEntropy: | 716 | case GetInfoType::RandomEntropy: |
| 636 | if (handle != 0) { | 717 | if (handle != 0) { |
| 718 | LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}", | ||
| 719 | handle); | ||
| 637 | return ERR_INVALID_HANDLE; | 720 | return ERR_INVALID_HANDLE; |
| 638 | } | 721 | } |
| 639 | 722 | ||
| 640 | if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { | 723 | if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { |
| 724 | LOG_ERROR(Kernel_SVC, "Entropy size is out of range, expected {} but got {}", | ||
| 725 | Process::RANDOM_ENTROPY_SIZE, info_sub_id); | ||
| 641 | return ERR_INVALID_COMBINATION; | 726 | return ERR_INVALID_COMBINATION; |
| 642 | } | 727 | } |
| 643 | 728 | ||
| @@ -675,12 +760,16 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 675 | case GetInfoType::ThreadTickCount: { | 760 | case GetInfoType::ThreadTickCount: { |
| 676 | constexpr u64 num_cpus = 4; | 761 | constexpr u64 num_cpus = 4; |
| 677 | if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { | 762 | if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { |
| 763 | LOG_ERROR(Kernel_SVC, "Core count is out of range, expected {} but got {}", num_cpus, | ||
| 764 | info_sub_id); | ||
| 678 | return ERR_INVALID_COMBINATION; | 765 | return ERR_INVALID_COMBINATION; |
| 679 | } | 766 | } |
| 680 | 767 | ||
| 681 | const auto thread = | 768 | const auto thread = |
| 682 | current_process->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); | 769 | current_process->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); |
| 683 | if (!thread) { | 770 | if (!thread) { |
| 771 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", | ||
| 772 | static_cast<Handle>(handle)); | ||
| 684 | return ERR_INVALID_HANDLE; | 773 | return ERR_INVALID_HANDLE; |
| 685 | } | 774 | } |
| 686 | 775 | ||
| @@ -723,14 +812,22 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { | |||
| 723 | const auto* current_process = Core::CurrentProcess(); | 812 | const auto* current_process = Core::CurrentProcess(); |
| 724 | const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | 813 | const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); |
| 725 | if (!thread) { | 814 | if (!thread) { |
| 815 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||
| 726 | return ERR_INVALID_HANDLE; | 816 | return ERR_INVALID_HANDLE; |
| 727 | } | 817 | } |
| 728 | 818 | ||
| 729 | if (thread->GetOwnerProcess() != current_process) { | 819 | if (thread->GetOwnerProcess() != current_process) { |
| 820 | LOG_ERROR(Kernel_SVC, | ||
| 821 | "The current process does not own the current thread, thread_handle={:08X} " | ||
| 822 | "thread_pid={}, " | ||
| 823 | "current_process_pid={}", | ||
| 824 | handle, thread->GetOwnerProcess()->GetProcessID(), | ||
| 825 | current_process->GetProcessID()); | ||
| 730 | return ERR_INVALID_HANDLE; | 826 | return ERR_INVALID_HANDLE; |
| 731 | } | 827 | } |
| 732 | 828 | ||
| 733 | if (thread == GetCurrentThread()) { | 829 | if (thread == GetCurrentThread()) { |
| 830 | LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread"); | ||
| 734 | return ERR_ALREADY_REGISTERED; | 831 | return ERR_ALREADY_REGISTERED; |
| 735 | } | 832 | } |
| 736 | 833 | ||
| @@ -751,9 +848,12 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { | |||
| 751 | 848 | ||
| 752 | /// Gets the priority for the specified thread | 849 | /// Gets the priority for the specified thread |
| 753 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { | 850 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { |
| 851 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 852 | |||
| 754 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 853 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 755 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); | 854 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); |
| 756 | if (!thread) { | 855 | if (!thread) { |
| 856 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||
| 757 | return ERR_INVALID_HANDLE; | 857 | return ERR_INVALID_HANDLE; |
| 758 | } | 858 | } |
| 759 | 859 | ||
| @@ -763,7 +863,13 @@ static ResultCode GetThreadPriority(u32* priority, Handle handle) { | |||
| 763 | 863 | ||
| 764 | /// Sets the priority for the specified thread | 864 | /// Sets the priority for the specified thread |
| 765 | static ResultCode SetThreadPriority(Handle handle, u32 priority) { | 865 | static ResultCode SetThreadPriority(Handle handle, u32 priority) { |
| 866 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 867 | |||
| 766 | if (priority > THREADPRIO_LOWEST) { | 868 | if (priority > THREADPRIO_LOWEST) { |
| 869 | LOG_ERROR( | ||
| 870 | Kernel_SVC, | ||
| 871 | "An invalid priority was specified, expected {} but got {} for thread_handle={:08X}", | ||
| 872 | THREADPRIO_LOWEST, priority, handle); | ||
| 767 | return ERR_INVALID_THREAD_PRIORITY; | 873 | return ERR_INVALID_THREAD_PRIORITY; |
| 768 | } | 874 | } |
| 769 | 875 | ||
| @@ -771,6 +877,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { | |||
| 771 | 877 | ||
| 772 | SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | 878 | SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); |
| 773 | if (!thread) { | 879 | if (!thread) { |
| 880 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle); | ||
| 774 | return ERR_INVALID_HANDLE; | 881 | return ERR_INVALID_HANDLE; |
| 775 | } | 882 | } |
| 776 | 883 | ||
| @@ -793,32 +900,46 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 793 | shared_memory_handle, addr, size, permissions); | 900 | shared_memory_handle, addr, size, permissions); |
| 794 | 901 | ||
| 795 | if (!Common::Is4KBAligned(addr)) { | 902 | if (!Common::Is4KBAligned(addr)) { |
| 903 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, addr=0x{:016X}", addr); | ||
| 796 | return ERR_INVALID_ADDRESS; | 904 | return ERR_INVALID_ADDRESS; |
| 797 | } | 905 | } |
| 798 | 906 | ||
| 799 | if (size == 0 || !Common::Is4KBAligned(size)) { | 907 | if (size == 0) { |
| 908 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 909 | return ERR_INVALID_SIZE; | ||
| 910 | } | ||
| 911 | |||
| 912 | if (!Common::Is4KBAligned(size)) { | ||
| 913 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, size=0x{:016X}", size); | ||
| 800 | return ERR_INVALID_SIZE; | 914 | return ERR_INVALID_SIZE; |
| 801 | } | 915 | } |
| 802 | 916 | ||
| 803 | if (!IsValidAddressRange(addr, size)) { | 917 | if (!IsValidAddressRange(addr, size)) { |
| 918 | LOG_ERROR(Kernel_SVC, "Region is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | ||
| 919 | addr, size); | ||
| 804 | return ERR_INVALID_ADDRESS_STATE; | 920 | return ERR_INVALID_ADDRESS_STATE; |
| 805 | } | 921 | } |
| 806 | 922 | ||
| 807 | const auto permissions_type = static_cast<MemoryPermission>(permissions); | 923 | const auto permissions_type = static_cast<MemoryPermission>(permissions); |
| 808 | if (permissions_type != MemoryPermission::Read && | 924 | if (permissions_type != MemoryPermission::Read && |
| 809 | permissions_type != MemoryPermission::ReadWrite) { | 925 | permissions_type != MemoryPermission::ReadWrite) { |
| 810 | LOG_ERROR(Kernel_SVC, "Invalid permissions=0x{:08X}", permissions); | 926 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", |
| 927 | permissions); | ||
| 811 | return ERR_INVALID_MEMORY_PERMISSIONS; | 928 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 812 | } | 929 | } |
| 813 | 930 | ||
| 814 | auto* const current_process = Core::CurrentProcess(); | 931 | auto* const current_process = Core::CurrentProcess(); |
| 815 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); | 932 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); |
| 816 | if (!shared_memory) { | 933 | if (!shared_memory) { |
| 934 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", | ||
| 935 | shared_memory_handle); | ||
| 817 | return ERR_INVALID_HANDLE; | 936 | return ERR_INVALID_HANDLE; |
| 818 | } | 937 | } |
| 819 | 938 | ||
| 820 | const auto& vm_manager = current_process->VMManager(); | 939 | const auto& vm_manager = current_process->VMManager(); |
| 821 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | 940 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { |
| 941 | LOG_ERROR(Kernel_SVC, "Region is not within the ASLR region. addr=0x{:016X}, size={:016X}", | ||
| 942 | addr, size); | ||
| 822 | return ERR_INVALID_MEMORY_RANGE; | 943 | return ERR_INVALID_MEMORY_RANGE; |
| 823 | } | 944 | } |
| 824 | 945 | ||
| @@ -830,25 +951,38 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 830 | shared_memory_handle, addr, size); | 951 | shared_memory_handle, addr, size); |
| 831 | 952 | ||
| 832 | if (!Common::Is4KBAligned(addr)) { | 953 | if (!Common::Is4KBAligned(addr)) { |
| 954 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, addr=0x{:016X}", addr); | ||
| 833 | return ERR_INVALID_ADDRESS; | 955 | return ERR_INVALID_ADDRESS; |
| 834 | } | 956 | } |
| 835 | 957 | ||
| 836 | if (size == 0 || !Common::Is4KBAligned(size)) { | 958 | if (size == 0) { |
| 959 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 960 | return ERR_INVALID_SIZE; | ||
| 961 | } | ||
| 962 | |||
| 963 | if (!Common::Is4KBAligned(size)) { | ||
| 964 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, size=0x{:016X}", size); | ||
| 837 | return ERR_INVALID_SIZE; | 965 | return ERR_INVALID_SIZE; |
| 838 | } | 966 | } |
| 839 | 967 | ||
| 840 | if (!IsValidAddressRange(addr, size)) { | 968 | if (!IsValidAddressRange(addr, size)) { |
| 969 | LOG_ERROR(Kernel_SVC, "Region is not a valid address range, addr=0x{:016X}, size=0x{:016X}", | ||
| 970 | addr, size); | ||
| 841 | return ERR_INVALID_ADDRESS_STATE; | 971 | return ERR_INVALID_ADDRESS_STATE; |
| 842 | } | 972 | } |
| 843 | 973 | ||
| 844 | auto* const current_process = Core::CurrentProcess(); | 974 | auto* const current_process = Core::CurrentProcess(); |
| 845 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); | 975 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); |
| 846 | if (!shared_memory) { | 976 | if (!shared_memory) { |
| 977 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", | ||
| 978 | shared_memory_handle); | ||
| 847 | return ERR_INVALID_HANDLE; | 979 | return ERR_INVALID_HANDLE; |
| 848 | } | 980 | } |
| 849 | 981 | ||
| 850 | const auto& vm_manager = current_process->VMManager(); | 982 | const auto& vm_manager = current_process->VMManager(); |
| 851 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | 983 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { |
| 984 | LOG_ERROR(Kernel_SVC, "Region is not within the ASLR region. addr=0x{:016X}, size={:016X}", | ||
| 985 | addr, size); | ||
| 852 | return ERR_INVALID_MEMORY_RANGE; | 986 | return ERR_INVALID_MEMORY_RANGE; |
| 853 | } | 987 | } |
| 854 | 988 | ||
| @@ -858,9 +992,12 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 858 | /// Query process memory | 992 | /// Query process memory |
| 859 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, | 993 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, |
| 860 | Handle process_handle, u64 addr) { | 994 | Handle process_handle, u64 addr) { |
| 995 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr); | ||
| 861 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 996 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 862 | SharedPtr<Process> process = handle_table.Get<Process>(process_handle); | 997 | SharedPtr<Process> process = handle_table.Get<Process>(process_handle); |
| 863 | if (!process) { | 998 | if (!process) { |
| 999 | LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", | ||
| 1000 | process_handle); | ||
| 864 | return ERR_INVALID_HANDLE; | 1001 | return ERR_INVALID_HANDLE; |
| 865 | } | 1002 | } |
| 866 | auto vma = process->VMManager().FindVMA(addr); | 1003 | auto vma = process->VMManager().FindVMA(addr); |
| @@ -876,8 +1013,6 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i | |||
| 876 | memory_info->size = vma->second.size; | 1013 | memory_info->size = vma->second.size; |
| 877 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); | 1014 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); |
| 878 | } | 1015 | } |
| 879 | |||
| 880 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr); | ||
| 881 | return RESULT_SUCCESS; | 1016 | return RESULT_SUCCESS; |
| 882 | } | 1017 | } |
| 883 | 1018 | ||
| @@ -906,7 +1041,14 @@ static void ExitProcess() { | |||
| 906 | /// Creates a new thread | 1041 | /// Creates a new thread |
| 907 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, | 1042 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, |
| 908 | u32 priority, s32 processor_id) { | 1043 | u32 priority, s32 processor_id) { |
| 1044 | LOG_TRACE(Kernel_SVC, | ||
| 1045 | "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " | ||
| 1046 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", | ||
| 1047 | entry_point, name, arg, stack_top, priority, processor_id, *out_handle); | ||
| 1048 | |||
| 909 | if (priority > THREADPRIO_LOWEST) { | 1049 | if (priority > THREADPRIO_LOWEST) { |
| 1050 | LOG_ERROR(Kernel_SVC, "An invalid priority was specified, expected {} but got {}", | ||
| 1051 | THREADPRIO_LOWEST, priority); | ||
| 910 | return ERR_INVALID_THREAD_PRIORITY; | 1052 | return ERR_INVALID_THREAD_PRIORITY; |
| 911 | } | 1053 | } |
| 912 | 1054 | ||
| @@ -937,6 +1079,8 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 937 | 1079 | ||
| 938 | const auto new_guest_handle = current_process->GetHandleTable().Create(thread); | 1080 | const auto new_guest_handle = current_process->GetHandleTable().Create(thread); |
| 939 | if (new_guest_handle.Failed()) { | 1081 | if (new_guest_handle.Failed()) { |
| 1082 | LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", | ||
| 1083 | new_guest_handle.Code().raw); | ||
| 940 | return new_guest_handle.Code(); | 1084 | return new_guest_handle.Code(); |
| 941 | } | 1085 | } |
| 942 | thread->SetGuestHandle(*new_guest_handle); | 1086 | thread->SetGuestHandle(*new_guest_handle); |
| @@ -944,11 +1088,6 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 944 | 1088 | ||
| 945 | Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); | 1089 | Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); |
| 946 | 1090 | ||
| 947 | LOG_TRACE(Kernel_SVC, | ||
| 948 | "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " | ||
| 949 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", | ||
| 950 | entry_point, name, arg, stack_top, priority, processor_id, *out_handle); | ||
| 951 | |||
| 952 | return RESULT_SUCCESS; | 1091 | return RESULT_SUCCESS; |
| 953 | } | 1092 | } |
| 954 | 1093 | ||
| @@ -959,6 +1098,8 @@ static ResultCode StartThread(Handle thread_handle) { | |||
| 959 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1098 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 960 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 1099 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 961 | if (!thread) { | 1100 | if (!thread) { |
| 1101 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||
| 1102 | thread_handle); | ||
| 962 | return ERR_INVALID_HANDLE; | 1103 | return ERR_INVALID_HANDLE; |
| 963 | } | 1104 | } |
| 964 | 1105 | ||
| @@ -1138,10 +1279,12 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 1138 | address, type, value, timeout); | 1279 | address, type, value, timeout); |
| 1139 | // If the passed address is a kernel virtual address, return invalid memory state. | 1280 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 1140 | if (Memory::IsKernelVirtualAddress(address)) { | 1281 | if (Memory::IsKernelVirtualAddress(address)) { |
| 1282 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); | ||
| 1141 | return ERR_INVALID_ADDRESS_STATE; | 1283 | return ERR_INVALID_ADDRESS_STATE; |
| 1142 | } | 1284 | } |
| 1143 | // If the address is not properly aligned to 4 bytes, return invalid address. | 1285 | // If the address is not properly aligned to 4 bytes, return invalid address. |
| 1144 | if (address % sizeof(u32) != 0) { | 1286 | if (!Common::IsWordAligned(address)) { |
| 1287 | LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address); | ||
| 1145 | return ERR_INVALID_ADDRESS; | 1288 | return ERR_INVALID_ADDRESS; |
| 1146 | } | 1289 | } |
| 1147 | 1290 | ||
| @@ -1153,6 +1296,10 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 1153 | case AddressArbiter::ArbitrationType::WaitIfEqual: | 1296 | case AddressArbiter::ArbitrationType::WaitIfEqual: |
| 1154 | return AddressArbiter::WaitForAddressIfEqual(address, value, timeout); | 1297 | return AddressArbiter::WaitForAddressIfEqual(address, value, timeout); |
| 1155 | default: | 1298 | default: |
| 1299 | LOG_ERROR(Kernel_SVC, | ||
| 1300 | "Invalid arbitration type, expected WaitIfLessThan, DecrementAndWaitIfLessThan " | ||
| 1301 | "or WaitIfEqual but got {}", | ||
| 1302 | type); | ||
| 1156 | return ERR_INVALID_ENUM_VALUE; | 1303 | return ERR_INVALID_ENUM_VALUE; |
| 1157 | } | 1304 | } |
| 1158 | } | 1305 | } |
| @@ -1163,10 +1310,12 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 1163 | address, type, value, num_to_wake); | 1310 | address, type, value, num_to_wake); |
| 1164 | // If the passed address is a kernel virtual address, return invalid memory state. | 1311 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 1165 | if (Memory::IsKernelVirtualAddress(address)) { | 1312 | if (Memory::IsKernelVirtualAddress(address)) { |
| 1313 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address, address={:016X}", address); | ||
| 1166 | return ERR_INVALID_ADDRESS_STATE; | 1314 | return ERR_INVALID_ADDRESS_STATE; |
| 1167 | } | 1315 | } |
| 1168 | // If the address is not properly aligned to 4 bytes, return invalid address. | 1316 | // If the address is not properly aligned to 4 bytes, return invalid address. |
| 1169 | if (address % sizeof(u32) != 0) { | 1317 | if (!Common::IsWordAligned(address)) { |
| 1318 | LOG_ERROR(Kernel_SVC, "Address is not word aligned, address={:016X}", address); | ||
| 1170 | return ERR_INVALID_ADDRESS; | 1319 | return ERR_INVALID_ADDRESS; |
| 1171 | } | 1320 | } |
| 1172 | 1321 | ||
| @@ -1179,12 +1328,18 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 1179 | return AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, | 1328 | return AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, |
| 1180 | num_to_wake); | 1329 | num_to_wake); |
| 1181 | default: | 1330 | default: |
| 1331 | LOG_ERROR(Kernel_SVC, | ||
| 1332 | "Invalid signal type, expected Signal, IncrementAndSignalIfEqual " | ||
| 1333 | "or ModifyByWaitingCountAndSignalIfEqual but got {}", | ||
| 1334 | type); | ||
| 1182 | return ERR_INVALID_ENUM_VALUE; | 1335 | return ERR_INVALID_ENUM_VALUE; |
| 1183 | } | 1336 | } |
| 1184 | } | 1337 | } |
| 1185 | 1338 | ||
| 1186 | /// This returns the total CPU ticks elapsed since the CPU was powered-on | 1339 | /// This returns the total CPU ticks elapsed since the CPU was powered-on |
| 1187 | static u64 GetSystemTick() { | 1340 | static u64 GetSystemTick() { |
| 1341 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 1342 | |||
| 1188 | const u64 result{CoreTiming::GetTicks()}; | 1343 | const u64 result{CoreTiming::GetTicks()}; |
| 1189 | 1344 | ||
| 1190 | // Advance time to defeat dumb games that busy-wait for the frame to end. | 1345 | // Advance time to defeat dumb games that busy-wait for the frame to end. |
| @@ -1258,6 +1413,8 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) | |||
| 1258 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1413 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1259 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 1414 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 1260 | if (!thread) { | 1415 | if (!thread) { |
| 1416 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||
| 1417 | thread_handle); | ||
| 1261 | return ERR_INVALID_HANDLE; | 1418 | return ERR_INVALID_HANDLE; |
| 1262 | } | 1419 | } |
| 1263 | 1420 | ||
| @@ -1268,12 +1425,14 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) | |||
| 1268 | } | 1425 | } |
| 1269 | 1426 | ||
| 1270 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | 1427 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { |
| 1271 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, | 1428 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle, |
| 1272 | mask, core); | 1429 | mask, core); |
| 1273 | 1430 | ||
| 1274 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1431 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1275 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 1432 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 1276 | if (!thread) { | 1433 | if (!thread) { |
| 1434 | LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}", | ||
| 1435 | thread_handle); | ||
| 1277 | return ERR_INVALID_HANDLE; | 1436 | return ERR_INVALID_HANDLE; |
| 1278 | } | 1437 | } |
| 1279 | 1438 | ||
| @@ -1288,6 +1447,7 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | |||
| 1288 | } | 1447 | } |
| 1289 | 1448 | ||
| 1290 | if (mask == 0) { | 1449 | if (mask == 0) { |
| 1450 | LOG_ERROR(Kernel_SVC, "Mask is 0"); | ||
| 1291 | return ERR_INVALID_COMBINATION; | 1451 | return ERR_INVALID_COMBINATION; |
| 1292 | } | 1452 | } |
| 1293 | 1453 | ||
| @@ -1297,11 +1457,14 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | |||
| 1297 | if (core == OnlyChangeMask) { | 1457 | if (core == OnlyChangeMask) { |
| 1298 | core = thread->GetIdealCore(); | 1458 | core = thread->GetIdealCore(); |
| 1299 | } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(-1)) { | 1459 | } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(-1)) { |
| 1460 | LOG_ERROR(Kernel_SVC, "Invalid core specified, got {}", core); | ||
| 1300 | return ERR_INVALID_PROCESSOR_ID; | 1461 | return ERR_INVALID_PROCESSOR_ID; |
| 1301 | } | 1462 | } |
| 1302 | 1463 | ||
| 1303 | // Error out if the input core isn't enabled in the input mask. | 1464 | // Error out if the input core isn't enabled in the input mask. |
| 1304 | if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) { | 1465 | if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) { |
| 1466 | LOG_ERROR(Kernel_SVC, "Core is not enabled for the current mask, core={}, mask={:016X}", | ||
| 1467 | core, mask); | ||
| 1305 | return ERR_INVALID_COMBINATION; | 1468 | return ERR_INVALID_COMBINATION; |
| 1306 | } | 1469 | } |
| 1307 | 1470 | ||
| @@ -1314,21 +1477,36 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss | |||
| 1314 | u32 remote_permissions) { | 1477 | u32 remote_permissions) { |
| 1315 | LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, | 1478 | LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, |
| 1316 | local_permissions, remote_permissions); | 1479 | local_permissions, remote_permissions); |
| 1480 | if (size == 0) { | ||
| 1481 | LOG_ERROR(Kernel_SVC, "Size is 0"); | ||
| 1482 | return ERR_INVALID_SIZE; | ||
| 1483 | } | ||
| 1484 | if (!Common::Is4KBAligned(size)) { | ||
| 1485 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:016X}", size); | ||
| 1486 | return ERR_INVALID_SIZE; | ||
| 1487 | } | ||
| 1317 | 1488 | ||
| 1318 | // Size must be a multiple of 4KB and be less than or equal to | 1489 | if (size >= MAIN_MEMORY_SIZE) { |
| 1319 | // approx. 8 GB (actually (1GB - 512B) * 8) | 1490 | LOG_ERROR(Kernel_SVC, "Size is not less than 8GB, 0x{:016X}", size); |
| 1320 | if (size == 0 || (size & 0xFFFFFFFE00000FFF) != 0) { | ||
| 1321 | return ERR_INVALID_SIZE; | 1491 | return ERR_INVALID_SIZE; |
| 1322 | } | 1492 | } |
| 1323 | 1493 | ||
| 1324 | const auto local_perms = static_cast<MemoryPermission>(local_permissions); | 1494 | const auto local_perms = static_cast<MemoryPermission>(local_permissions); |
| 1325 | if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) { | 1495 | if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) { |
| 1496 | LOG_ERROR(Kernel_SVC, | ||
| 1497 | "Invalid local memory permissions, expected Read or ReadWrite but got " | ||
| 1498 | "local_permissions={}", | ||
| 1499 | static_cast<u32>(local_permissions)); | ||
| 1326 | return ERR_INVALID_MEMORY_PERMISSIONS; | 1500 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 1327 | } | 1501 | } |
| 1328 | 1502 | ||
| 1329 | const auto remote_perms = static_cast<MemoryPermission>(remote_permissions); | 1503 | const auto remote_perms = static_cast<MemoryPermission>(remote_permissions); |
| 1330 | if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite && | 1504 | if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite && |
| 1331 | remote_perms != MemoryPermission::DontCare) { | 1505 | remote_perms != MemoryPermission::DontCare) { |
| 1506 | LOG_ERROR(Kernel_SVC, | ||
| 1507 | "Invalid remote memory permissions, expected Read, ReadWrite or DontCare but got " | ||
| 1508 | "remote_permissions={}", | ||
| 1509 | static_cast<u32>(remote_permissions)); | ||
| 1332 | return ERR_INVALID_MEMORY_PERMISSIONS; | 1510 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 1333 | } | 1511 | } |
| 1334 | 1512 | ||
| @@ -1348,6 +1526,7 @@ static ResultCode ClearEvent(Handle handle) { | |||
| 1348 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1526 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1349 | SharedPtr<Event> evt = handle_table.Get<Event>(handle); | 1527 | SharedPtr<Event> evt = handle_table.Get<Event>(handle); |
| 1350 | if (evt == nullptr) { | 1528 | if (evt == nullptr) { |
| 1529 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); | ||
| 1351 | return ERR_INVALID_HANDLE; | 1530 | return ERR_INVALID_HANDLE; |
| 1352 | } | 1531 | } |
| 1353 | 1532 | ||
| @@ -1366,11 +1545,14 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { | |||
| 1366 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1545 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1367 | const auto process = handle_table.Get<Process>(process_handle); | 1546 | const auto process = handle_table.Get<Process>(process_handle); |
| 1368 | if (!process) { | 1547 | if (!process) { |
| 1548 | LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", | ||
| 1549 | process_handle); | ||
| 1369 | return ERR_INVALID_HANDLE; | 1550 | return ERR_INVALID_HANDLE; |
| 1370 | } | 1551 | } |
| 1371 | 1552 | ||
| 1372 | const auto info_type = static_cast<InfoType>(type); | 1553 | const auto info_type = static_cast<InfoType>(type); |
| 1373 | if (info_type != InfoType::Status) { | 1554 | if (info_type != InfoType::Status) { |
| 1555 | LOG_ERROR(Kernel_SVC, "Expected info_type to be Status but got {} instead", type); | ||
| 1374 | return ERR_INVALID_ENUM_VALUE; | 1556 | return ERR_INVALID_ENUM_VALUE; |
| 1375 | } | 1557 | } |
| 1376 | 1558 | ||