From ab7472345b9ce38cd2ca57bf1104be9576e0ef1e Mon Sep 17 00:00:00 2001 From: Frederic Laing Date: Sat, 3 Nov 2018 16:01:34 +0100 Subject: [PATCH 1/2] Stubbed SetMemoryPermission --- src/core/hle/kernel/svc.cpp | 8 +++++++- src/core/hle/kernel/svc_wrap.h | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c7c579aaf7..56e7904a51 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -122,6 +122,12 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { return RESULT_SUCCESS; } +static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { + LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, + prot); + return RESULT_SUCCESS; +} + static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}, size=0x{:X}, state0=0x{:X}, state1=0x{:X}", addr, @@ -1259,7 +1265,7 @@ struct FunctionDef { static const FunctionDef SVC_Table[] = { {0x00, nullptr, "Unknown"}, {0x01, SvcWrap, "SetHeapSize"}, - {0x02, nullptr, "SetMemoryPermission"}, + {0x02, SvcWrap, "SetMemoryPermission"}, {0x03, SvcWrap, "SetMemoryAttribute"}, {0x04, SvcWrap, "MapMemory"}, {0x05, SvcWrap, "UnmapMemory"}, diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index b09753c80d..233a99fb08 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -121,6 +121,11 @@ void SvcWrap() { FuncReturn(func(Param(0), Param(1), Param(2)).raw); } +template +void SvcWrap() { + FuncReturn(func(Param(0), Param(1), static_cast(Param(2))).raw); +} + template void SvcWrap() { FuncReturn( From ba2cdcdc5ab0c671b78b9446728dc9de89592e5a Mon Sep 17 00:00:00 2001 From: Frederic Laing <27208977+FreddyFunk@users.noreply.github.com> Date: Tue, 6 Nov 2018 10:21:01 +0100 Subject: [PATCH 2/2] Implement SetMemoryPermission --- src/core/hle/kernel/svc.cpp | 42 ++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 56e7904a51..3b1612badb 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -123,9 +123,45 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) { } static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { - LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, - prot); - return RESULT_SUCCESS; + LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); + + if (!Common::Is4KBAligned(addr)) { + return ERR_INVALID_ADDRESS; + } + + if (size == 0 || !Common::Is4KBAligned(size)) { + return ERR_INVALID_SIZE; + } + + if (!IsValidAddressRange(addr, size)) { + return ERR_INVALID_ADDRESS_STATE; + } + + const auto permission = static_cast(prot); + if (permission != MemoryPermission::None && permission != MemoryPermission::Read && + permission != MemoryPermission::ReadWrite) { + return ERR_INVALID_MEMORY_PERMISSIONS; + } + + auto* const current_process = Core::CurrentProcess(); + auto& vm_manager = current_process->VMManager(); + + if (!IsInsideAddressSpace(vm_manager, addr, size)) { + return ERR_INVALID_ADDRESS_STATE; + } + + const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); + if (iter == vm_manager.vma_map.end()) { + return ERR_INVALID_ADDRESS_STATE; + } + + LOG_WARNING(Kernel_SVC, "Uniformity check on protected memory is not implemented."); + // TODO: Performs a uniformity check to make sure only protected memory is changed (it doesn't + // make sense to allow changing permissions on kernel memory itself, etc). + + const auto converted_permissions = SharedMemory::ConvertPermissions(permission); + + return vm_manager.ReprotectRange(addr, size, converted_permissions); } static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {