diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 101 |
1 files changed, 90 insertions, 11 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f287f7c97..775afccf6 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -69,37 +69,45 @@ bool IsInsideNewMapRegion(const VMManager& vm, VAddr address, u64 size) { | |||
| 69 | ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_addr, VAddr src_addr, | 69 | ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_addr, VAddr src_addr, |
| 70 | u64 size) { | 70 | u64 size) { |
| 71 | if (!Common::Is4KBAligned(dst_addr) || !Common::Is4KBAligned(src_addr)) { | 71 | if (!Common::Is4KBAligned(dst_addr) || !Common::Is4KBAligned(src_addr)) { |
| 72 | LOG_ERROR(Kernel_SVC, "Invalid address"); | ||
| 72 | return ERR_INVALID_ADDRESS; | 73 | return ERR_INVALID_ADDRESS; |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | if (size == 0 || !Common::Is4KBAligned(size)) { | 76 | if (size == 0 || !Common::Is4KBAligned(size)) { |
| 77 | LOG_ERROR(Kernel_SVC, "Invalid size"); | ||
| 76 | return ERR_INVALID_SIZE; | 78 | return ERR_INVALID_SIZE; |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 79 | if (!IsValidAddressRange(dst_addr, size)) { | 81 | if (!IsValidAddressRange(dst_addr, size)) { |
| 82 | LOG_ERROR(Kernel_SVC, "size is out of range"); | ||
| 80 | return ERR_INVALID_ADDRESS_STATE; | 83 | return ERR_INVALID_ADDRESS_STATE; |
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | if (!IsValidAddressRange(src_addr, size)) { | 86 | if (!IsValidAddressRange(src_addr, size)) { |
| 87 | LOG_ERROR(Kernel_SVC, "size is out of range"); | ||
| 84 | return ERR_INVALID_ADDRESS_STATE; | 88 | return ERR_INVALID_ADDRESS_STATE; |
| 85 | } | 89 | } |
| 86 | 90 | ||
| 87 | if (!IsInsideAddressSpace(vm_manager, src_addr, size)) { | 91 | if (!IsInsideAddressSpace(vm_manager, src_addr, size)) { |
| 92 | LOG_ERROR(Kernel_SVC, "Region is out of the address space"); | ||
| 88 | return ERR_INVALID_ADDRESS_STATE; | 93 | return ERR_INVALID_ADDRESS_STATE; |
| 89 | } | 94 | } |
| 90 | 95 | ||
| 91 | if (!IsInsideNewMapRegion(vm_manager, dst_addr, size)) { | 96 | if (!IsInsideNewMapRegion(vm_manager, dst_addr, size)) { |
| 97 | LOG_ERROR(Kernel_SVC, "Region is out of the address space"); | ||
| 92 | return ERR_INVALID_MEMORY_RANGE; | 98 | return ERR_INVALID_MEMORY_RANGE; |
| 93 | } | 99 | } |
| 94 | 100 | ||
| 95 | const VAddr dst_end_address = dst_addr + size; | 101 | const VAddr dst_end_address = dst_addr + size; |
| 96 | if (dst_end_address > vm_manager.GetHeapRegionBaseAddress() && | 102 | if (dst_end_address > vm_manager.GetHeapRegionBaseAddress() && |
| 97 | vm_manager.GetHeapRegionEndAddress() > dst_addr) { | 103 | vm_manager.GetHeapRegionEndAddress() > dst_addr) { |
| 104 | LOG_ERROR(Kernel_SVC, "Region is not in the correct address space"); | ||
| 98 | return ERR_INVALID_MEMORY_RANGE; | 105 | return ERR_INVALID_MEMORY_RANGE; |
| 99 | } | 106 | } |
| 100 | 107 | ||
| 101 | if (dst_end_address > vm_manager.GetMapRegionBaseAddress() && | 108 | if (dst_end_address > vm_manager.GetMapRegionBaseAddress() && |
| 102 | vm_manager.GetMapRegionEndAddress() > dst_addr) { | 109 | vm_manager.GetMapRegionEndAddress() > dst_addr) { |
| 110 | LOG_ERROR(Kernel_SVC, "Region is not in the correct address space"); | ||
| 103 | return ERR_INVALID_MEMORY_RANGE; | 111 | return ERR_INVALID_MEMORY_RANGE; |
| 104 | } | 112 | } |
| 105 | 113 | ||
| @@ -113,6 +121,7 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { | |||
| 113 | 121 | ||
| 114 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 4GB. | 122 | // Size must be a multiple of 0x200000 (2MB) and be equal to or less than 4GB. |
| 115 | if ((heap_size & 0xFFFFFFFE001FFFFF) != 0) { | 123 | if ((heap_size & 0xFFFFFFFE001FFFFF) != 0) { |
| 124 | LOG_ERROR(Kernel_SVC, "Invalid heap size"); | ||
| 116 | return ERR_INVALID_SIZE; | 125 | return ERR_INVALID_SIZE; |
| 117 | } | 126 | } |
| 118 | 127 | ||
| @@ -127,20 +136,24 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | |||
| 127 | LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); | 136 | LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); |
| 128 | 137 | ||
| 129 | if (!Common::Is4KBAligned(addr)) { | 138 | if (!Common::Is4KBAligned(addr)) { |
| 139 | LOG_ERROR(Kernel_SVC, "Address is not aligned"); | ||
| 130 | return ERR_INVALID_ADDRESS; | 140 | return ERR_INVALID_ADDRESS; |
| 131 | } | 141 | } |
| 132 | 142 | ||
| 133 | if (size == 0 || !Common::Is4KBAligned(size)) { | 143 | if (size == 0 || !Common::Is4KBAligned(size)) { |
| 144 | LOG_ERROR(Kernel_SVC, "Invalid size"); | ||
| 134 | return ERR_INVALID_SIZE; | 145 | return ERR_INVALID_SIZE; |
| 135 | } | 146 | } |
| 136 | 147 | ||
| 137 | if (!IsValidAddressRange(addr, size)) { | 148 | if (!IsValidAddressRange(addr, size)) { |
| 149 | LOG_ERROR(Kernel_SVC, "Region is out of the address space"); | ||
| 138 | return ERR_INVALID_ADDRESS_STATE; | 150 | return ERR_INVALID_ADDRESS_STATE; |
| 139 | } | 151 | } |
| 140 | 152 | ||
| 141 | const auto permission = static_cast<MemoryPermission>(prot); | 153 | const auto permission = static_cast<MemoryPermission>(prot); |
| 142 | if (permission != MemoryPermission::None && permission != MemoryPermission::Read && | 154 | if (permission != MemoryPermission::None && permission != MemoryPermission::Read && |
| 143 | permission != MemoryPermission::ReadWrite) { | 155 | permission != MemoryPermission::ReadWrite) { |
| 156 | LOG_ERROR(Kernel_SVC, "Incorrect memory permissions"); | ||
| 144 | return ERR_INVALID_MEMORY_PERMISSIONS; | 157 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 145 | } | 158 | } |
| 146 | 159 | ||
| @@ -148,11 +161,13 @@ static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | |||
| 148 | auto& vm_manager = current_process->VMManager(); | 161 | auto& vm_manager = current_process->VMManager(); |
| 149 | 162 | ||
| 150 | if (!IsInsideAddressSpace(vm_manager, addr, size)) { | 163 | if (!IsInsideAddressSpace(vm_manager, addr, size)) { |
| 164 | LOG_ERROR(Kernel_SVC, "Region is not inside the address space"); | ||
| 151 | return ERR_INVALID_ADDRESS_STATE; | 165 | return ERR_INVALID_ADDRESS_STATE; |
| 152 | } | 166 | } |
| 153 | 167 | ||
| 154 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); | 168 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); |
| 155 | if (iter == vm_manager.vma_map.end()) { | 169 | if (iter == vm_manager.vma_map.end()) { |
| 170 | LOG_ERROR(Kernel_SVC, "Unable to find VMA"); | ||
| 156 | return ERR_INVALID_ADDRESS_STATE; | 171 | return ERR_INVALID_ADDRESS_STATE; |
| 157 | } | 172 | } |
| 158 | 173 | ||
| @@ -182,6 +197,7 @@ static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | |||
| 182 | 197 | ||
| 183 | const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); | 198 | const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); |
| 184 | if (result != RESULT_SUCCESS) { | 199 | if (result != RESULT_SUCCESS) { |
| 200 | LOG_ERROR(Kernel_SVC, "Map Memory failed"); | ||
| 185 | return result; | 201 | return result; |
| 186 | } | 202 | } |
| 187 | 203 | ||
| @@ -198,6 +214,7 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | |||
| 198 | 214 | ||
| 199 | const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); | 215 | const auto result = MapUnmapMemorySanityChecks(vm_manager, dst_addr, src_addr, size); |
| 200 | if (result != RESULT_SUCCESS) { | 216 | if (result != RESULT_SUCCESS) { |
| 217 | LOG_ERROR(Kernel_SVC, "UnmapMemory failed"); | ||
| 201 | return result; | 218 | return result; |
| 202 | } | 219 | } |
| 203 | 220 | ||
| @@ -207,6 +224,7 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | |||
| 207 | /// Connect to an OS service given the port name, returns the handle to the port to out | 224 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 208 | static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { | 225 | static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) { |
| 209 | if (!Memory::IsValidVirtualAddress(port_name_address)) { | 226 | if (!Memory::IsValidVirtualAddress(port_name_address)) { |
| 227 | LOG_ERROR(Kernel_SVC, "Invalid port name address"); | ||
| 210 | return ERR_NOT_FOUND; | 228 | return ERR_NOT_FOUND; |
| 211 | } | 229 | } |
| 212 | 230 | ||
| @@ -214,6 +232,7 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address | |||
| 214 | // Read 1 char beyond the max allowed port name to detect names that are too long. | 232 | // Read 1 char beyond the max allowed port name to detect names that are too long. |
| 215 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | 233 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); |
| 216 | if (port_name.size() > PortNameMaxLength) { | 234 | if (port_name.size() > PortNameMaxLength) { |
| 235 | LOG_ERROR(Kernel_SVC, "Port name is too long"); | ||
| 217 | return ERR_OUT_OF_RANGE; | 236 | return ERR_OUT_OF_RANGE; |
| 218 | } | 237 | } |
| 219 | 238 | ||
| @@ -262,6 +281,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | |||
| 262 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 281 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 263 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 282 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 264 | if (!thread) { | 283 | if (!thread) { |
| 284 | LOG_ERROR(Kernel_SVC, "Invalid thread handle"); | ||
| 265 | return ERR_INVALID_HANDLE; | 285 | return ERR_INVALID_HANDLE; |
| 266 | } | 286 | } |
| 267 | 287 | ||
| @@ -276,6 +296,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | |||
| 276 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 296 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 277 | const SharedPtr<Process> process = handle_table.Get<Process>(process_handle); | 297 | const SharedPtr<Process> process = handle_table.Get<Process>(process_handle); |
| 278 | if (!process) { | 298 | if (!process) { |
| 299 | LOG_ERROR(Kernel_SVC, "Invalid process"); | ||
| 279 | return ERR_INVALID_HANDLE; | 300 | return ERR_INVALID_HANDLE; |
| 280 | } | 301 | } |
| 281 | 302 | ||
| @@ -305,12 +326,15 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 305 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", | 326 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", |
| 306 | handles_address, handle_count, nano_seconds); | 327 | handles_address, handle_count, nano_seconds); |
| 307 | 328 | ||
| 308 | if (!Memory::IsValidVirtualAddress(handles_address)) | 329 | if (!Memory::IsValidVirtualAddress(handles_address)) { |
| 330 | LOG_ERROR(Kernel_SVC, "Invalid handle address"); | ||
| 309 | return ERR_INVALID_POINTER; | 331 | return ERR_INVALID_POINTER; |
| 332 | } | ||
| 310 | 333 | ||
| 311 | static constexpr u64 MaxHandles = 0x40; | 334 | static constexpr u64 MaxHandles = 0x40; |
| 312 | 335 | ||
| 313 | if (handle_count > MaxHandles) { | 336 | if (handle_count > MaxHandles) { |
| 337 | LOG_ERROR(Kernel_SVC, "Handle count is too big"); | ||
| 314 | return ERR_OUT_OF_RANGE; | 338 | return ERR_OUT_OF_RANGE; |
| 315 | } | 339 | } |
| 316 | 340 | ||
| @@ -325,6 +349,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 325 | const auto object = handle_table.Get<WaitObject>(handle); | 349 | const auto object = handle_table.Get<WaitObject>(handle); |
| 326 | 350 | ||
| 327 | if (object == nullptr) { | 351 | if (object == nullptr) { |
| 352 | LOG_ERROR(Kernel_SVC, "Object is a nullptr"); | ||
| 328 | return ERR_INVALID_HANDLE; | 353 | return ERR_INVALID_HANDLE; |
| 329 | } | 354 | } |
| 330 | 355 | ||
| @@ -348,11 +373,13 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 348 | 373 | ||
| 349 | // If a timeout value of 0 was provided, just return the Timeout error code instead of | 374 | // If a timeout value of 0 was provided, just return the Timeout error code instead of |
| 350 | // suspending the thread. | 375 | // suspending the thread. |
| 351 | if (nano_seconds == 0) | 376 | if (nano_seconds == 0) { |
| 352 | return RESULT_TIMEOUT; | 377 | return RESULT_TIMEOUT; |
| 378 | } | ||
| 353 | 379 | ||
| 354 | for (auto& object : objects) | 380 | for (auto& object : objects) { |
| 355 | object->AddWaitingThread(thread); | 381 | object->AddWaitingThread(thread); |
| 382 | } | ||
| 356 | 383 | ||
| 357 | thread->SetWaitObjects(std::move(objects)); | 384 | thread->SetWaitObjects(std::move(objects)); |
| 358 | thread->SetStatus(ThreadStatus::WaitSynchAny); | 385 | thread->SetStatus(ThreadStatus::WaitSynchAny); |
| @@ -373,6 +400,7 @@ static ResultCode CancelSynchronization(Handle thread_handle) { | |||
| 373 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 400 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 374 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 401 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 375 | if (!thread) { | 402 | if (!thread) { |
| 403 | LOG_ERROR(Kernel_SVC, "Invalid thread handle"); | ||
| 376 | return ERR_INVALID_HANDLE; | 404 | return ERR_INVALID_HANDLE; |
| 377 | } | 405 | } |
| 378 | 406 | ||
| @@ -391,10 +419,12 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr, | |||
| 391 | holding_thread_handle, mutex_addr, requesting_thread_handle); | 419 | holding_thread_handle, mutex_addr, requesting_thread_handle); |
| 392 | 420 | ||
| 393 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 421 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 422 | LOG_ERROR(Kernel_SVC, "Invalid mutex address"); | ||
| 394 | return ERR_INVALID_ADDRESS_STATE; | 423 | return ERR_INVALID_ADDRESS_STATE; |
| 395 | } | 424 | } |
| 396 | 425 | ||
| 397 | if (!Common::IsWordAligned(mutex_addr)) { | 426 | if (!Common::IsWordAligned(mutex_addr)) { |
| 427 | LOG_ERROR(Kernel_SVC, "Mutex address is not aligned"); | ||
| 398 | return ERR_INVALID_ADDRESS; | 428 | return ERR_INVALID_ADDRESS; |
| 399 | } | 429 | } |
| 400 | 430 | ||
| @@ -408,10 +438,12 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) { | |||
| 408 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); | 438 | LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr); |
| 409 | 439 | ||
| 410 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { | 440 | if (Memory::IsKernelVirtualAddress(mutex_addr)) { |
| 441 | LOG_ERROR(Kernel_SVC, "Invalid size"); | ||
| 411 | return ERR_INVALID_ADDRESS_STATE; | 442 | return ERR_INVALID_ADDRESS_STATE; |
| 412 | } | 443 | } |
| 413 | 444 | ||
| 414 | if (!Common::IsWordAligned(mutex_addr)) { | 445 | if (!Common::IsWordAligned(mutex_addr)) { |
| 446 | LOG_ERROR(Kernel_SVC, "Mutex address is not aligned"); | ||
| 415 | return ERR_INVALID_ADDRESS; | 447 | return ERR_INVALID_ADDRESS; |
| 416 | } | 448 | } |
| 417 | 449 | ||
| @@ -602,10 +634,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 602 | break; | 634 | break; |
| 603 | case GetInfoType::RandomEntropy: | 635 | case GetInfoType::RandomEntropy: |
| 604 | if (handle != 0) { | 636 | if (handle != 0) { |
| 637 | LOG_ERROR(Kernel_SVC, "Non zero handle specified"); | ||
| 605 | return ERR_INVALID_HANDLE; | 638 | return ERR_INVALID_HANDLE; |
| 606 | } | 639 | } |
| 607 | 640 | ||
| 608 | if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { | 641 | if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { |
| 642 | LOG_ERROR(Kernel_SVC, "Entropy size is too big"); | ||
| 609 | return ERR_INVALID_COMBINATION; | 643 | return ERR_INVALID_COMBINATION; |
| 610 | } | 644 | } |
| 611 | 645 | ||
| @@ -643,12 +677,14 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 643 | case GetInfoType::ThreadTickCount: { | 677 | case GetInfoType::ThreadTickCount: { |
| 644 | constexpr u64 num_cpus = 4; | 678 | constexpr u64 num_cpus = 4; |
| 645 | if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { | 679 | if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { |
| 680 | LOG_ERROR(Kernel_SVC, "Incorrect info_sub_id"); | ||
| 646 | return ERR_INVALID_COMBINATION; | 681 | return ERR_INVALID_COMBINATION; |
| 647 | } | 682 | } |
| 648 | 683 | ||
| 649 | const auto thread = | 684 | const auto thread = |
| 650 | current_process->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); | 685 | current_process->GetHandleTable().Get<Thread>(static_cast<Handle>(handle)); |
| 651 | if (!thread) { | 686 | if (!thread) { |
| 687 | LOG_ERROR(Kernel_SVC, "Thread is not a valid handle"); | ||
| 652 | return ERR_INVALID_HANDLE; | 688 | return ERR_INVALID_HANDLE; |
| 653 | } | 689 | } |
| 654 | 690 | ||
| @@ -691,14 +727,17 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { | |||
| 691 | const auto* current_process = Core::CurrentProcess(); | 727 | const auto* current_process = Core::CurrentProcess(); |
| 692 | const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | 728 | const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); |
| 693 | if (!thread) { | 729 | if (!thread) { |
| 730 | LOG_ERROR(Kernel_SVC, "Thread is not a valid handle"); | ||
| 694 | return ERR_INVALID_HANDLE; | 731 | return ERR_INVALID_HANDLE; |
| 695 | } | 732 | } |
| 696 | 733 | ||
| 697 | if (thread->GetOwnerProcess() != current_process) { | 734 | if (thread->GetOwnerProcess() != current_process) { |
| 735 | LOG_ERROR(Kernel_SVC, "Thread owner process is not the current process"); | ||
| 698 | return ERR_INVALID_HANDLE; | 736 | return ERR_INVALID_HANDLE; |
| 699 | } | 737 | } |
| 700 | 738 | ||
| 701 | if (thread == GetCurrentThread()) { | 739 | if (thread == GetCurrentThread()) { |
| 740 | LOG_ERROR(Kernel_SVC, "Thread is already registered"); | ||
| 702 | return ERR_ALREADY_REGISTERED; | 741 | return ERR_ALREADY_REGISTERED; |
| 703 | } | 742 | } |
| 704 | 743 | ||
| @@ -719,9 +758,12 @@ static ResultCode GetThreadContext(VAddr thread_context, Handle handle) { | |||
| 719 | 758 | ||
| 720 | /// Gets the priority for the specified thread | 759 | /// Gets the priority for the specified thread |
| 721 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { | 760 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { |
| 761 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 762 | |||
| 722 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 763 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 723 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); | 764 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle); |
| 724 | if (!thread) { | 765 | if (!thread) { |
| 766 | LOG_ERROR(Kernel_SVC, "Invalid thread handle"); | ||
| 725 | return ERR_INVALID_HANDLE; | 767 | return ERR_INVALID_HANDLE; |
| 726 | } | 768 | } |
| 727 | 769 | ||
| @@ -731,7 +773,10 @@ static ResultCode GetThreadPriority(u32* priority, Handle handle) { | |||
| 731 | 773 | ||
| 732 | /// Sets the priority for the specified thread | 774 | /// Sets the priority for the specified thread |
| 733 | static ResultCode SetThreadPriority(Handle handle, u32 priority) { | 775 | static ResultCode SetThreadPriority(Handle handle, u32 priority) { |
| 776 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 777 | |||
| 734 | if (priority > THREADPRIO_LOWEST) { | 778 | if (priority > THREADPRIO_LOWEST) { |
| 779 | LOG_ERROR(Kernel_SVC, "Priority is out of range"); | ||
| 735 | return ERR_INVALID_THREAD_PRIORITY; | 780 | return ERR_INVALID_THREAD_PRIORITY; |
| 736 | } | 781 | } |
| 737 | 782 | ||
| @@ -739,6 +784,7 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { | |||
| 739 | 784 | ||
| 740 | SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); | 785 | SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle); |
| 741 | if (!thread) { | 786 | if (!thread) { |
| 787 | LOG_ERROR(Kernel_SVC, "Invalid thread handle"); | ||
| 742 | return ERR_INVALID_HANDLE; | 788 | return ERR_INVALID_HANDLE; |
| 743 | } | 789 | } |
| 744 | 790 | ||
| @@ -761,14 +807,17 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 761 | shared_memory_handle, addr, size, permissions); | 807 | shared_memory_handle, addr, size, permissions); |
| 762 | 808 | ||
| 763 | if (!Common::Is4KBAligned(addr)) { | 809 | if (!Common::Is4KBAligned(addr)) { |
| 810 | LOG_ERROR(Kernel_SVC, "Address is not aligned"); | ||
| 764 | return ERR_INVALID_ADDRESS; | 811 | return ERR_INVALID_ADDRESS; |
| 765 | } | 812 | } |
| 766 | 813 | ||
| 767 | if (size == 0 || !Common::Is4KBAligned(size)) { | 814 | if (size == 0 || !Common::Is4KBAligned(size)) { |
| 815 | LOG_ERROR(Kernel_SVC, "Invalid size"); | ||
| 768 | return ERR_INVALID_SIZE; | 816 | return ERR_INVALID_SIZE; |
| 769 | } | 817 | } |
| 770 | 818 | ||
| 771 | if (!IsValidAddressRange(addr, size)) { | 819 | if (!IsValidAddressRange(addr, size)) { |
| 820 | LOG_ERROR(Kernel_SVC, "Region is not in the address space"); | ||
| 772 | return ERR_INVALID_ADDRESS_STATE; | 821 | return ERR_INVALID_ADDRESS_STATE; |
| 773 | } | 822 | } |
| 774 | 823 | ||
| @@ -782,11 +831,13 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s | |||
| 782 | auto* const current_process = Core::CurrentProcess(); | 831 | auto* const current_process = Core::CurrentProcess(); |
| 783 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); | 832 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); |
| 784 | if (!shared_memory) { | 833 | if (!shared_memory) { |
| 834 | LOG_ERROR(Kernel_SVC, "Invalid shared memory handle"); | ||
| 785 | return ERR_INVALID_HANDLE; | 835 | return ERR_INVALID_HANDLE; |
| 786 | } | 836 | } |
| 787 | 837 | ||
| 788 | const auto& vm_manager = current_process->VMManager(); | 838 | const auto& vm_manager = current_process->VMManager(); |
| 789 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | 839 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { |
| 840 | LOG_ERROR(Kernel_SVC, "Region is not within the ASLR region"); | ||
| 790 | return ERR_INVALID_MEMORY_RANGE; | 841 | return ERR_INVALID_MEMORY_RANGE; |
| 791 | } | 842 | } |
| 792 | 843 | ||
| @@ -798,25 +849,30 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 798 | shared_memory_handle, addr, size); | 849 | shared_memory_handle, addr, size); |
| 799 | 850 | ||
| 800 | if (!Common::Is4KBAligned(addr)) { | 851 | if (!Common::Is4KBAligned(addr)) { |
| 852 | LOG_ERROR(Kernel_SVC, "Address is not aligned"); | ||
| 801 | return ERR_INVALID_ADDRESS; | 853 | return ERR_INVALID_ADDRESS; |
| 802 | } | 854 | } |
| 803 | 855 | ||
| 804 | if (size == 0 || !Common::Is4KBAligned(size)) { | 856 | if (size == 0 || !Common::Is4KBAligned(size)) { |
| 857 | LOG_ERROR(Kernel_SVC, "Size is invalid"); | ||
| 805 | return ERR_INVALID_SIZE; | 858 | return ERR_INVALID_SIZE; |
| 806 | } | 859 | } |
| 807 | 860 | ||
| 808 | if (!IsValidAddressRange(addr, size)) { | 861 | if (!IsValidAddressRange(addr, size)) { |
| 862 | LOG_ERROR(Kernel_SVC, "Region is not in the valid address range"); | ||
| 809 | return ERR_INVALID_ADDRESS_STATE; | 863 | return ERR_INVALID_ADDRESS_STATE; |
| 810 | } | 864 | } |
| 811 | 865 | ||
| 812 | auto* const current_process = Core::CurrentProcess(); | 866 | auto* const current_process = Core::CurrentProcess(); |
| 813 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); | 867 | auto shared_memory = current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle); |
| 814 | if (!shared_memory) { | 868 | if (!shared_memory) { |
| 869 | LOG_ERROR(Kernel_SVC, "Shared memory is an invalid handle"); | ||
| 815 | return ERR_INVALID_HANDLE; | 870 | return ERR_INVALID_HANDLE; |
| 816 | } | 871 | } |
| 817 | 872 | ||
| 818 | const auto& vm_manager = current_process->VMManager(); | 873 | const auto& vm_manager = current_process->VMManager(); |
| 819 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { | 874 | if (!vm_manager.IsWithinASLRRegion(addr, size)) { |
| 875 | LOG_ERROR(Kernel_SVC, "Region is not within the ASLR region"); | ||
| 820 | return ERR_INVALID_MEMORY_RANGE; | 876 | return ERR_INVALID_MEMORY_RANGE; |
| 821 | } | 877 | } |
| 822 | 878 | ||
| @@ -826,9 +882,11 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 | |||
| 826 | /// Query process memory | 882 | /// Query process memory |
| 827 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, | 883 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, |
| 828 | Handle process_handle, u64 addr) { | 884 | Handle process_handle, u64 addr) { |
| 885 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr); | ||
| 829 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 886 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 830 | SharedPtr<Process> process = handle_table.Get<Process>(process_handle); | 887 | SharedPtr<Process> process = handle_table.Get<Process>(process_handle); |
| 831 | if (!process) { | 888 | if (!process) { |
| 889 | LOG_ERROR(Kernel_SVC, "Invalid process handle"); | ||
| 832 | return ERR_INVALID_HANDLE; | 890 | return ERR_INVALID_HANDLE; |
| 833 | } | 891 | } |
| 834 | auto vma = process->VMManager().FindVMA(addr); | 892 | auto vma = process->VMManager().FindVMA(addr); |
| @@ -844,8 +902,6 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i | |||
| 844 | memory_info->size = vma->second.size; | 902 | memory_info->size = vma->second.size; |
| 845 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); | 903 | memory_info->type = static_cast<u32>(vma->second.meminfo_state); |
| 846 | } | 904 | } |
| 847 | |||
| 848 | LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr); | ||
| 849 | return RESULT_SUCCESS; | 905 | return RESULT_SUCCESS; |
| 850 | } | 906 | } |
| 851 | 907 | ||
| @@ -874,7 +930,13 @@ static void ExitProcess() { | |||
| 874 | /// Creates a new thread | 930 | /// Creates a new thread |
| 875 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, | 931 | static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, VAddr stack_top, |
| 876 | u32 priority, s32 processor_id) { | 932 | u32 priority, s32 processor_id) { |
| 933 | LOG_TRACE(Kernel_SVC, | ||
| 934 | "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " | ||
| 935 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", | ||
| 936 | entry_point, name, arg, stack_top, priority, processor_id, *out_handle); | ||
| 937 | |||
| 877 | if (priority > THREADPRIO_LOWEST) { | 938 | if (priority > THREADPRIO_LOWEST) { |
| 939 | LOG_ERROR(Kernel_SVC, "Invalid thread priority"); | ||
| 878 | return ERR_INVALID_THREAD_PRIORITY; | 940 | return ERR_INVALID_THREAD_PRIORITY; |
| 879 | } | 941 | } |
| 880 | 942 | ||
| @@ -905,6 +967,8 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 905 | 967 | ||
| 906 | const auto new_guest_handle = current_process->GetHandleTable().Create(thread); | 968 | const auto new_guest_handle = current_process->GetHandleTable().Create(thread); |
| 907 | if (new_guest_handle.Failed()) { | 969 | if (new_guest_handle.Failed()) { |
| 970 | LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", | ||
| 971 | new_guest_handle.Code().raw); | ||
| 908 | return new_guest_handle.Code(); | 972 | return new_guest_handle.Code(); |
| 909 | } | 973 | } |
| 910 | thread->SetGuestHandle(*new_guest_handle); | 974 | thread->SetGuestHandle(*new_guest_handle); |
| @@ -912,11 +976,6 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V | |||
| 912 | 976 | ||
| 913 | Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); | 977 | Core::System::GetInstance().CpuCore(thread->GetProcessorID()).PrepareReschedule(); |
| 914 | 978 | ||
| 915 | LOG_TRACE(Kernel_SVC, | ||
| 916 | "called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, " | ||
| 917 | "threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}", | ||
| 918 | entry_point, name, arg, stack_top, priority, processor_id, *out_handle); | ||
| 919 | |||
| 920 | return RESULT_SUCCESS; | 979 | return RESULT_SUCCESS; |
| 921 | } | 980 | } |
| 922 | 981 | ||
| @@ -927,6 +986,7 @@ static ResultCode StartThread(Handle thread_handle) { | |||
| 927 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 986 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 928 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 987 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 929 | if (!thread) { | 988 | if (!thread) { |
| 989 | LOG_ERROR(Kernel_SVC, "Thread is an invalid handle"); | ||
| 930 | return ERR_INVALID_HANDLE; | 990 | return ERR_INVALID_HANDLE; |
| 931 | } | 991 | } |
| 932 | 992 | ||
| @@ -1106,10 +1166,12 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 1106 | address, type, value, timeout); | 1166 | address, type, value, timeout); |
| 1107 | // If the passed address is a kernel virtual address, return invalid memory state. | 1167 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 1108 | if (Memory::IsKernelVirtualAddress(address)) { | 1168 | if (Memory::IsKernelVirtualAddress(address)) { |
| 1169 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address"); | ||
| 1109 | return ERR_INVALID_ADDRESS_STATE; | 1170 | return ERR_INVALID_ADDRESS_STATE; |
| 1110 | } | 1171 | } |
| 1111 | // If the address is not properly aligned to 4 bytes, return invalid address. | 1172 | // If the address is not properly aligned to 4 bytes, return invalid address. |
| 1112 | if (address % sizeof(u32) != 0) { | 1173 | if (address % sizeof(u32) != 0) { |
| 1174 | LOG_ERROR(Kernel_SVC, "Address is not aligned"); | ||
| 1113 | return ERR_INVALID_ADDRESS; | 1175 | return ERR_INVALID_ADDRESS; |
| 1114 | } | 1176 | } |
| 1115 | 1177 | ||
| @@ -1121,6 +1183,7 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout | |||
| 1121 | case AddressArbiter::ArbitrationType::WaitIfEqual: | 1183 | case AddressArbiter::ArbitrationType::WaitIfEqual: |
| 1122 | return AddressArbiter::WaitForAddressIfEqual(address, value, timeout); | 1184 | return AddressArbiter::WaitForAddressIfEqual(address, value, timeout); |
| 1123 | default: | 1185 | default: |
| 1186 | LOG_ERROR(Kernel_SVC, "Invalid arbitration type"); | ||
| 1124 | return ERR_INVALID_ENUM_VALUE; | 1187 | return ERR_INVALID_ENUM_VALUE; |
| 1125 | } | 1188 | } |
| 1126 | } | 1189 | } |
| @@ -1131,10 +1194,12 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 1131 | address, type, value, num_to_wake); | 1194 | address, type, value, num_to_wake); |
| 1132 | // If the passed address is a kernel virtual address, return invalid memory state. | 1195 | // If the passed address is a kernel virtual address, return invalid memory state. |
| 1133 | if (Memory::IsKernelVirtualAddress(address)) { | 1196 | if (Memory::IsKernelVirtualAddress(address)) { |
| 1197 | LOG_ERROR(Kernel_SVC, "Address is a kernel virtual address"); | ||
| 1134 | return ERR_INVALID_ADDRESS_STATE; | 1198 | return ERR_INVALID_ADDRESS_STATE; |
| 1135 | } | 1199 | } |
| 1136 | // If the address is not properly aligned to 4 bytes, return invalid address. | 1200 | // If the address is not properly aligned to 4 bytes, return invalid address. |
| 1137 | if (address % sizeof(u32) != 0) { | 1201 | if (address % sizeof(u32) != 0) { |
| 1202 | LOG_ERROR(Kernel_SVC, "Address is not aligned"); | ||
| 1138 | return ERR_INVALID_ADDRESS; | 1203 | return ERR_INVALID_ADDRESS; |
| 1139 | } | 1204 | } |
| 1140 | 1205 | ||
| @@ -1147,12 +1212,15 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 1147 | return AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, | 1212 | return AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, |
| 1148 | num_to_wake); | 1213 | num_to_wake); |
| 1149 | default: | 1214 | default: |
| 1215 | LOG_ERROR(Kernel_SVC, "Invalid arbitration type"); | ||
| 1150 | return ERR_INVALID_ENUM_VALUE; | 1216 | return ERR_INVALID_ENUM_VALUE; |
| 1151 | } | 1217 | } |
| 1152 | } | 1218 | } |
| 1153 | 1219 | ||
| 1154 | /// This returns the total CPU ticks elapsed since the CPU was powered-on | 1220 | /// This returns the total CPU ticks elapsed since the CPU was powered-on |
| 1155 | static u64 GetSystemTick() { | 1221 | static u64 GetSystemTick() { |
| 1222 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 1223 | |||
| 1156 | const u64 result{CoreTiming::GetTicks()}; | 1224 | const u64 result{CoreTiming::GetTicks()}; |
| 1157 | 1225 | ||
| 1158 | // Advance time to defeat dumb games that busy-wait for the frame to end. | 1226 | // Advance time to defeat dumb games that busy-wait for the frame to end. |
| @@ -1226,6 +1294,7 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) | |||
| 1226 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1294 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1227 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 1295 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 1228 | if (!thread) { | 1296 | if (!thread) { |
| 1297 | LOG_ERROR(Kernel_SVC, "Thread is an invalid handle"); | ||
| 1229 | return ERR_INVALID_HANDLE; | 1298 | return ERR_INVALID_HANDLE; |
| 1230 | } | 1299 | } |
| 1231 | 1300 | ||
| @@ -1236,12 +1305,13 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) | |||
| 1236 | } | 1305 | } |
| 1237 | 1306 | ||
| 1238 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | 1307 | static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { |
| 1239 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, | 1308 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:016X}, core=0x{:X}", thread_handle, |
| 1240 | mask, core); | 1309 | mask, core); |
| 1241 | 1310 | ||
| 1242 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1311 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1243 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); | 1312 | const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle); |
| 1244 | if (!thread) { | 1313 | if (!thread) { |
| 1314 | LOG_ERROR(Kernel_SVC, "Thread is an invalid handle"); | ||
| 1245 | return ERR_INVALID_HANDLE; | 1315 | return ERR_INVALID_HANDLE; |
| 1246 | } | 1316 | } |
| 1247 | 1317 | ||
| @@ -1256,6 +1326,7 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | |||
| 1256 | } | 1326 | } |
| 1257 | 1327 | ||
| 1258 | if (mask == 0) { | 1328 | if (mask == 0) { |
| 1329 | LOG_ERROR(Kernel_SVC, "Mask is 0"); | ||
| 1259 | return ERR_INVALID_COMBINATION; | 1330 | return ERR_INVALID_COMBINATION; |
| 1260 | } | 1331 | } |
| 1261 | 1332 | ||
| @@ -1265,11 +1336,13 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) { | |||
| 1265 | if (core == OnlyChangeMask) { | 1336 | if (core == OnlyChangeMask) { |
| 1266 | core = thread->GetIdealCore(); | 1337 | core = thread->GetIdealCore(); |
| 1267 | } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(-1)) { | 1338 | } else if (core >= Core::NUM_CPU_CORES && core != static_cast<u32>(-1)) { |
| 1339 | LOG_ERROR(Kernel_SVC, "Invalid processor ID specified"); | ||
| 1268 | return ERR_INVALID_PROCESSOR_ID; | 1340 | return ERR_INVALID_PROCESSOR_ID; |
| 1269 | } | 1341 | } |
| 1270 | 1342 | ||
| 1271 | // Error out if the input core isn't enabled in the input mask. | 1343 | // Error out if the input core isn't enabled in the input mask. |
| 1272 | if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) { | 1344 | if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) { |
| 1345 | LOG_ERROR(Kernel_SVC, "Invalid core and mask"); | ||
| 1273 | return ERR_INVALID_COMBINATION; | 1346 | return ERR_INVALID_COMBINATION; |
| 1274 | } | 1347 | } |
| 1275 | 1348 | ||
| @@ -1286,17 +1359,20 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss | |||
| 1286 | // Size must be a multiple of 4KB and be less than or equal to | 1359 | // Size must be a multiple of 4KB and be less than or equal to |
| 1287 | // approx. 8 GB (actually (1GB - 512B) * 8) | 1360 | // approx. 8 GB (actually (1GB - 512B) * 8) |
| 1288 | if (size == 0 || (size & 0xFFFFFFFE00000FFF) != 0) { | 1361 | if (size == 0 || (size & 0xFFFFFFFE00000FFF) != 0) { |
| 1362 | LOG_ERROR(Kernel_SVC, "Invalid size"); | ||
| 1289 | return ERR_INVALID_SIZE; | 1363 | return ERR_INVALID_SIZE; |
| 1290 | } | 1364 | } |
| 1291 | 1365 | ||
| 1292 | const auto local_perms = static_cast<MemoryPermission>(local_permissions); | 1366 | const auto local_perms = static_cast<MemoryPermission>(local_permissions); |
| 1293 | if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) { | 1367 | if (local_perms != MemoryPermission::Read && local_perms != MemoryPermission::ReadWrite) { |
| 1368 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions"); | ||
| 1294 | return ERR_INVALID_MEMORY_PERMISSIONS; | 1369 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 1295 | } | 1370 | } |
| 1296 | 1371 | ||
| 1297 | const auto remote_perms = static_cast<MemoryPermission>(remote_permissions); | 1372 | const auto remote_perms = static_cast<MemoryPermission>(remote_permissions); |
| 1298 | if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite && | 1373 | if (remote_perms != MemoryPermission::Read && remote_perms != MemoryPermission::ReadWrite && |
| 1299 | remote_perms != MemoryPermission::DontCare) { | 1374 | remote_perms != MemoryPermission::DontCare) { |
| 1375 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions"); | ||
| 1300 | return ERR_INVALID_MEMORY_PERMISSIONS; | 1376 | return ERR_INVALID_MEMORY_PERMISSIONS; |
| 1301 | } | 1377 | } |
| 1302 | 1378 | ||
| @@ -1316,6 +1392,7 @@ static ResultCode ClearEvent(Handle handle) { | |||
| 1316 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1392 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1317 | SharedPtr<Event> evt = handle_table.Get<Event>(handle); | 1393 | SharedPtr<Event> evt = handle_table.Get<Event>(handle); |
| 1318 | if (evt == nullptr) { | 1394 | if (evt == nullptr) { |
| 1395 | LOG_ERROR(Kernel_SVC, "Invalid event handle"); | ||
| 1319 | return ERR_INVALID_HANDLE; | 1396 | return ERR_INVALID_HANDLE; |
| 1320 | } | 1397 | } |
| 1321 | 1398 | ||
| @@ -1334,11 +1411,13 @@ static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { | |||
| 1334 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); | 1411 | const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); |
| 1335 | const auto process = handle_table.Get<Process>(process_handle); | 1412 | const auto process = handle_table.Get<Process>(process_handle); |
| 1336 | if (!process) { | 1413 | if (!process) { |
| 1414 | LOG_ERROR(Kernel_SVC, "Invalid process handle"); | ||
| 1337 | return ERR_INVALID_HANDLE; | 1415 | return ERR_INVALID_HANDLE; |
| 1338 | } | 1416 | } |
| 1339 | 1417 | ||
| 1340 | const auto info_type = static_cast<InfoType>(type); | 1418 | const auto info_type = static_cast<InfoType>(type); |
| 1341 | if (info_type != InfoType::Status) { | 1419 | if (info_type != InfoType::Status) { |
| 1420 | LOG_ERROR(Kernel_SVC, "Info type is not status"); | ||
| 1342 | return ERR_INVALID_ENUM_VALUE; | 1421 | return ERR_INVALID_ENUM_VALUE; |
| 1343 | } | 1422 | } |
| 1344 | 1423 | ||