Frederic Laing 7 лет назад
Родитель
Сommit
ba2cdcdc5a
1 измененных файлов с 39 добавлено и 3 удалено
  1. 39 3
      src/core/hle/kernel/svc.cpp

+ 39 - 3
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) {
 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<MemoryPermission>(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) {
 static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {