diff options
| author | 2018-11-06 10:21:01 +0100 | |
|---|---|---|
| committer | 2018-11-06 10:21:01 +0100 | |
| commit | ba2cdcdc5ab0c671b78b9446728dc9de89592e5a (patch) | |
| tree | 4ebf53372fa93e5976e20fd6d8807402686ef4a3 | |
| parent | Stubbed SetMemoryPermission (diff) | |
| download | yuzu-ba2cdcdc5ab0c671b78b9446728dc9de89592e5a.tar.gz yuzu-ba2cdcdc5ab0c671b78b9446728dc9de89592e5a.tar.xz yuzu-ba2cdcdc5ab0c671b78b9446728dc9de89592e5a.zip | |
Implement SetMemoryPermission
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 56e7904a5..3b1612bad 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) { | |||
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { | 125 | static ResultCode SetMemoryPermission(VAddr addr, u64 size, u32 prot) { |
| 126 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, | 126 | LOG_TRACE(Kernel_SVC, "called, addr=0x{:X}, size=0x{:X}, prot=0x{:X}", addr, size, prot); |
| 127 | prot); | 127 | |
| 128 | return RESULT_SUCCESS; | 128 | if (!Common::Is4KBAligned(addr)) { |
| 129 | return ERR_INVALID_ADDRESS; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (size == 0 || !Common::Is4KBAligned(size)) { | ||
| 133 | return ERR_INVALID_SIZE; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (!IsValidAddressRange(addr, size)) { | ||
| 137 | return ERR_INVALID_ADDRESS_STATE; | ||
| 138 | } | ||
| 139 | |||
| 140 | const auto permission = static_cast<MemoryPermission>(prot); | ||
| 141 | if (permission != MemoryPermission::None && permission != MemoryPermission::Read && | ||
| 142 | permission != MemoryPermission::ReadWrite) { | ||
| 143 | return ERR_INVALID_MEMORY_PERMISSIONS; | ||
| 144 | } | ||
| 145 | |||
| 146 | auto* const current_process = Core::CurrentProcess(); | ||
| 147 | auto& vm_manager = current_process->VMManager(); | ||
| 148 | |||
| 149 | if (!IsInsideAddressSpace(vm_manager, addr, size)) { | ||
| 150 | return ERR_INVALID_ADDRESS_STATE; | ||
| 151 | } | ||
| 152 | |||
| 153 | const VMManager::VMAHandle iter = vm_manager.FindVMA(addr); | ||
| 154 | if (iter == vm_manager.vma_map.end()) { | ||
| 155 | return ERR_INVALID_ADDRESS_STATE; | ||
| 156 | } | ||
| 157 | |||
| 158 | LOG_WARNING(Kernel_SVC, "Uniformity check on protected memory is not implemented."); | ||
| 159 | // TODO: Performs a uniformity check to make sure only protected memory is changed (it doesn't | ||
| 160 | // make sense to allow changing permissions on kernel memory itself, etc). | ||
| 161 | |||
| 162 | const auto converted_permissions = SharedMemory::ConvertPermissions(permission); | ||
| 163 | |||
| 164 | return vm_manager.ReprotectRange(addr, size, converted_permissions); | ||
| 129 | } | 165 | } |
| 130 | 166 | ||
| 131 | static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { | 167 | static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) { |