diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 31d899e06..cc8fa6576 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -27,21 +27,21 @@ | |||
| 27 | #include "core/hle/kernel/k_address_arbiter.h" | 27 | #include "core/hle/kernel/k_address_arbiter.h" |
| 28 | #include "core/hle/kernel/k_condition_variable.h" | 28 | #include "core/hle/kernel/k_condition_variable.h" |
| 29 | #include "core/hle/kernel/k_event.h" | 29 | #include "core/hle/kernel/k_event.h" |
| 30 | #include "core/hle/kernel/k_memory_block.h" | ||
| 31 | #include "core/hle/kernel/k_memory_layout.h" | ||
| 32 | #include "core/hle/kernel/k_page_table.h" | ||
| 30 | #include "core/hle/kernel/k_readable_event.h" | 33 | #include "core/hle/kernel/k_readable_event.h" |
| 31 | #include "core/hle/kernel/k_resource_limit.h" | 34 | #include "core/hle/kernel/k_resource_limit.h" |
| 32 | #include "core/hle/kernel/k_scheduler.h" | 35 | #include "core/hle/kernel/k_scheduler.h" |
| 33 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 36 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 34 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 37 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 38 | #include "core/hle/kernel/k_shared_memory.h" | ||
| 35 | #include "core/hle/kernel/k_synchronization_object.h" | 39 | #include "core/hle/kernel/k_synchronization_object.h" |
| 36 | #include "core/hle/kernel/k_thread.h" | 40 | #include "core/hle/kernel/k_thread.h" |
| 37 | #include "core/hle/kernel/k_writable_event.h" | 41 | #include "core/hle/kernel/k_writable_event.h" |
| 38 | #include "core/hle/kernel/kernel.h" | 42 | #include "core/hle/kernel/kernel.h" |
| 39 | #include "core/hle/kernel/memory/memory_block.h" | ||
| 40 | #include "core/hle/kernel/memory/memory_layout.h" | ||
| 41 | #include "core/hle/kernel/memory/page_table.h" | ||
| 42 | #include "core/hle/kernel/physical_core.h" | 43 | #include "core/hle/kernel/physical_core.h" |
| 43 | #include "core/hle/kernel/process.h" | 44 | #include "core/hle/kernel/process.h" |
| 44 | #include "core/hle/kernel/shared_memory.h" | ||
| 45 | #include "core/hle/kernel/svc.h" | 45 | #include "core/hle/kernel/svc.h" |
| 46 | #include "core/hle/kernel/svc_results.h" | 46 | #include "core/hle/kernel/svc_results.h" |
| 47 | #include "core/hle/kernel/svc_types.h" | 47 | #include "core/hle/kernel/svc_types.h" |
| @@ -67,8 +67,8 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) { | |||
| 67 | // Helper function that performs the common sanity checks for svcMapMemory | 67 | // Helper function that performs the common sanity checks for svcMapMemory |
| 68 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing | 68 | // and svcUnmapMemory. This is doable, as both functions perform their sanitizing |
| 69 | // in the same order. | 69 | // in the same order. |
| 70 | ResultCode MapUnmapMemorySanityChecks(const Memory::PageTable& manager, VAddr dst_addr, | 70 | ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, VAddr src_addr, |
| 71 | VAddr src_addr, u64 size) { | 71 | u64 size) { |
| 72 | if (!Common::Is4KBAligned(dst_addr)) { | 72 | if (!Common::Is4KBAligned(dst_addr)) { |
| 73 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); | 73 | LOG_ERROR(Kernel_SVC, "Destination address is not aligned to 4KB, 0x{:016X}", dst_addr); |
| 74 | return ResultInvalidAddress; | 74 | return ResultInvalidAddress; |
| @@ -230,9 +230,9 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 230 | return ResultInvalidCurrentMemory; | 230 | return ResultInvalidCurrentMemory; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | const auto attributes{static_cast<Memory::MemoryAttribute>(mask | attribute)}; | 233 | const auto attributes{static_cast<MemoryAttribute>(mask | attribute)}; |
| 234 | if (attributes != static_cast<Memory::MemoryAttribute>(mask) || | 234 | if (attributes != static_cast<MemoryAttribute>(mask) || |
| 235 | (attributes | Memory::MemoryAttribute::Uncached) != Memory::MemoryAttribute::Uncached) { | 235 | (attributes | MemoryAttribute::Uncached) != MemoryAttribute::Uncached) { |
| 236 | LOG_ERROR(Kernel_SVC, | 236 | LOG_ERROR(Kernel_SVC, |
| 237 | "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", | 237 | "Memory attribute doesn't match the given mask (Attribute: 0x{:X}, Mask: {:X}", |
| 238 | attribute, mask); | 238 | attribute, mask); |
| @@ -241,8 +241,8 @@ static ResultCode SetMemoryAttribute(Core::System& system, VAddr address, u64 si | |||
| 241 | 241 | ||
| 242 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; | 242 | auto& page_table{system.Kernel().CurrentProcess()->PageTable()}; |
| 243 | 243 | ||
| 244 | return page_table.SetMemoryAttribute(address, size, static_cast<Memory::MemoryAttribute>(mask), | 244 | return page_table.SetMemoryAttribute(address, size, static_cast<KMemoryAttribute>(mask), |
| 245 | static_cast<Memory::MemoryAttribute>(attribute)); | 245 | static_cast<KMemoryAttribute>(attribute)); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, | 248 | static ResultCode SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, |
| @@ -508,7 +508,7 @@ static ResultCode ArbitrateLock(Core::System& system, Handle thread_handle, VAdd | |||
| 508 | thread_handle, address, tag); | 508 | thread_handle, address, tag); |
| 509 | 509 | ||
| 510 | // Validate the input address. | 510 | // Validate the input address. |
| 511 | if (Memory::IsKernelAddress(address)) { | 511 | if (IsKernelAddress(address)) { |
| 512 | LOG_ERROR(Kernel_SVC, "Attempting to arbitrate a lock on a kernel address (address={:08X})", | 512 | LOG_ERROR(Kernel_SVC, "Attempting to arbitrate a lock on a kernel address (address={:08X})", |
| 513 | address); | 513 | address); |
| 514 | return ResultInvalidCurrentMemory; | 514 | return ResultInvalidCurrentMemory; |
| @@ -531,8 +531,7 @@ static ResultCode ArbitrateUnlock(Core::System& system, VAddr address) { | |||
| 531 | LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); | 531 | LOG_TRACE(Kernel_SVC, "called address=0x{:X}", address); |
| 532 | 532 | ||
| 533 | // Validate the input address. | 533 | // Validate the input address. |
| 534 | 534 | if (IsKernelAddress(address)) { | |
| 535 | if (Memory::IsKernelAddress(address)) { | ||
| 536 | LOG_ERROR(Kernel_SVC, | 535 | LOG_ERROR(Kernel_SVC, |
| 537 | "Attempting to arbitrate an unlock on a kernel address (address={:08X})", | 536 | "Attempting to arbitrate an unlock on a kernel address (address={:08X})", |
| 538 | address); | 537 | address); |
| @@ -1232,9 +1231,8 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1232 | return ResultInvalidCurrentMemory; | 1231 | return ResultInvalidCurrentMemory; |
| 1233 | } | 1232 | } |
| 1234 | 1233 | ||
| 1235 | const auto permission_type = static_cast<Memory::MemoryPermission>(permissions); | 1234 | const auto permission_type = static_cast<MemoryPermission>(permissions); |
| 1236 | if ((permission_type | Memory::MemoryPermission::Write) != | 1235 | if ((permission_type | MemoryPermission::Write) != MemoryPermission::ReadWrite) { |
| 1237 | Memory::MemoryPermission::ReadAndWrite) { | ||
| 1238 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", | 1236 | LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", |
| 1239 | permissions); | 1237 | permissions); |
| 1240 | return ResultInvalidMemoryPermissions; | 1238 | return ResultInvalidMemoryPermissions; |
| @@ -1267,14 +1265,15 @@ static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_han | |||
| 1267 | return ResultInvalidMemoryRange; | 1265 | return ResultInvalidMemoryRange; |
| 1268 | } | 1266 | } |
| 1269 | 1267 | ||
| 1270 | auto shared_memory{current_process->GetHandleTable().Get<SharedMemory>(shared_memory_handle)}; | 1268 | auto shared_memory{current_process->GetHandleTable().Get<KSharedMemory>(shared_memory_handle)}; |
| 1271 | if (!shared_memory) { | 1269 | if (!shared_memory) { |
| 1272 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", | 1270 | LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", |
| 1273 | shared_memory_handle); | 1271 | shared_memory_handle); |
| 1274 | return ResultInvalidHandle; | 1272 | return ResultInvalidHandle; |
| 1275 | } | 1273 | } |
| 1276 | 1274 | ||
| 1277 | return shared_memory->Map(*current_process, addr, size, permission_type); | 1275 | return shared_memory->Map(*current_process, addr, size, |
| 1276 | static_cast<KMemoryPermission>(permission_type)); | ||
| 1278 | } | 1277 | } |
| 1279 | 1278 | ||
| 1280 | static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, | 1279 | static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, |
| @@ -1638,7 +1637,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr address, | |||
| 1638 | cv_key, tag, timeout_ns); | 1637 | cv_key, tag, timeout_ns); |
| 1639 | 1638 | ||
| 1640 | // Validate input. | 1639 | // Validate input. |
| 1641 | if (Memory::IsKernelAddress(address)) { | 1640 | if (IsKernelAddress(address)) { |
| 1642 | LOG_ERROR(Kernel_SVC, "Attempted to wait on kernel address (address={:08X})", address); | 1641 | LOG_ERROR(Kernel_SVC, "Attempted to wait on kernel address (address={:08X})", address); |
| 1643 | return ResultInvalidCurrentMemory; | 1642 | return ResultInvalidCurrentMemory; |
| 1644 | } | 1643 | } |
| @@ -1720,7 +1719,7 @@ static ResultCode WaitForAddress(Core::System& system, VAddr address, Svc::Arbit | |||
| 1720 | address, arb_type, value, timeout_ns); | 1719 | address, arb_type, value, timeout_ns); |
| 1721 | 1720 | ||
| 1722 | // Validate input. | 1721 | // Validate input. |
| 1723 | if (Memory::IsKernelAddress(address)) { | 1722 | if (IsKernelAddress(address)) { |
| 1724 | LOG_ERROR(Kernel_SVC, "Attempting to wait on kernel address (address={:08X})", address); | 1723 | LOG_ERROR(Kernel_SVC, "Attempting to wait on kernel address (address={:08X})", address); |
| 1725 | return ResultInvalidCurrentMemory; | 1724 | return ResultInvalidCurrentMemory; |
| 1726 | } | 1725 | } |
| @@ -1765,7 +1764,7 @@ static ResultCode SignalToAddress(Core::System& system, VAddr address, Svc::Sign | |||
| 1765 | address, signal_type, value, count); | 1764 | address, signal_type, value, count); |
| 1766 | 1765 | ||
| 1767 | // Validate input. | 1766 | // Validate input. |
| 1768 | if (Memory::IsKernelAddress(address)) { | 1767 | if (IsKernelAddress(address)) { |
| 1769 | LOG_ERROR(Kernel_SVC, "Attempting to signal to a kernel address (address={:08X})", address); | 1768 | LOG_ERROR(Kernel_SVC, "Attempting to signal to a kernel address (address={:08X})", address); |
| 1770 | return ResultInvalidCurrentMemory; | 1769 | return ResultInvalidCurrentMemory; |
| 1771 | } | 1770 | } |
| @@ -1887,9 +1886,8 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1887 | return ResultInvalidCurrentMemory; | 1886 | return ResultInvalidCurrentMemory; |
| 1888 | } | 1887 | } |
| 1889 | 1888 | ||
| 1890 | const auto perms{static_cast<Memory::MemoryPermission>(permissions)}; | 1889 | const auto perms{static_cast<MemoryPermission>(permissions)}; |
| 1891 | if (perms > Memory::MemoryPermission::ReadAndWrite || | 1890 | if (perms > MemoryPermission::ReadWrite || perms == MemoryPermission::Write) { |
| 1892 | perms == Memory::MemoryPermission::Write) { | ||
| 1893 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", | 1891 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", |
| 1894 | permissions); | 1892 | permissions); |
| 1895 | return ResultInvalidMemoryPermissions; | 1893 | return ResultInvalidMemoryPermissions; |
| @@ -1903,7 +1901,8 @@ static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAd | |||
| 1903 | LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); | 1901 | LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); |
| 1904 | return ResultResourceLimitedExceeded; | 1902 | return ResultResourceLimitedExceeded; |
| 1905 | } | 1903 | } |
| 1906 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, perms); | 1904 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, |
| 1905 | static_cast<KMemoryPermission>(perms)); | ||
| 1907 | 1906 | ||
| 1908 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { | 1907 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { |
| 1909 | return reserve_result; | 1908 | return reserve_result; |