diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
index 2b6d4e4e9..b065e9c58 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
@@ -675,7 +675,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
                     KMemoryPermission.None,
                     MemoryAttribute.Mask,
                     MemoryAttribute.None,
-                    MemoryAttribute.IpcAndDeviceMapped,
+                    MemoryAttribute.IpcAndDeviceMapped | MemoryAttribute.PermissionLocked,
                     out MemoryState state,
                     out _,
                     out _);
@@ -687,7 +687,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
                     state,
                     KMemoryPermission.None,
                     KMemoryPermission.None,
-                    MemoryAttribute.Mask,
+                    MemoryAttribute.Mask & ~MemoryAttribute.PermissionLocked,
                     MemoryAttribute.None);
 
                 if (success)
@@ -913,19 +913,27 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
             return Result.Success;
         }
 
-        public Result SetMemoryAttribute(
-            ulong address,
-            ulong size,
-            MemoryAttribute attributeMask,
-            MemoryAttribute attributeValue)
+        public Result SetMemoryAttribute(ulong address, ulong size, MemoryAttribute attributeMask, MemoryAttribute attributeValue)
         {
             lock (_blockManager)
             {
+                MemoryState stateCheckMask = 0;
+
+                if (attributeMask.HasFlag(MemoryAttribute.Uncached))
+                {
+                    stateCheckMask = MemoryState.AttributeChangeAllowed;
+                }
+
+                if (attributeMask.HasFlag(MemoryAttribute.PermissionLocked))
+                {
+                    stateCheckMask |= MemoryState.PermissionLockAllowed;
+                }
+
                 if (CheckRange(
                     address,
                     size,
-                    MemoryState.AttributeChangeAllowed,
-                    MemoryState.AttributeChangeAllowed,
+                    stateCheckMask,
+                    stateCheckMask,
                     KMemoryPermission.None,
                     KMemoryPermission.None,
                     MemoryAttribute.BorrowedAndIpcMapped,
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs
index 36b1ec8c3..e0fa60fab 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryAttribute.cs
@@ -12,11 +12,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
         IpcMapped = 1 << 1,
         DeviceMapped = 1 << 2,
         Uncached = 1 << 3,
+        PermissionLocked = 1 << 4,
 
         IpcAndDeviceMapped = IpcMapped | DeviceMapped,
-
         BorrowedAndIpcMapped = Borrowed | IpcMapped,
-
         DeviceMappedAndUncached = DeviceMapped | Uncached,
     }
 }
diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs
index 273b58e5e..da6fac639 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryState.cs
@@ -5,35 +5,155 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
     [Flags]
     enum MemoryState : uint
     {
-        Unmapped = 0x00000000,
-        Io = 0x00002001,
-        Normal = 0x00042002,
-        CodeStatic = 0x00DC7E03,
-        CodeMutable = 0x03FEBD04,
-        Heap = 0x037EBD05,
-        SharedMemory = 0x00402006,
-        ModCodeStatic = 0x00DD7E08,
-        ModCodeMutable = 0x03FFBD09,
-        IpcBuffer0 = 0x005C3C0A,
-        Stack = 0x005C3C0B,
-        ThreadLocal = 0x0040200C,
-        TransferMemoryIsolated = 0x015C3C0D,
-        TransferMemory = 0x005C380E,
-        ProcessMemory = 0x0040380F,
-        Reserved = 0x00000010,
-        IpcBuffer1 = 0x005C3811,
-        IpcBuffer3 = 0x004C2812,
-        KernelStack = 0x00002013,
-        CodeReadOnly = 0x00402214,
-        CodeWritable = 0x00402015,
-        UserMask = 0xff,
-        Mask = 0xffffffff,
+        Unmapped = 0x0,
+        Io = Mapped | 0x1,
+        Normal = Mapped | QueryPhysicalAddressAllowed | 0x2,
+        CodeStatic = ForceReadWritableByDebugSyscalls |
+            IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            ProcessPermissionChangeAllowed |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            MapProcessAllowed |
+            LinearMapped |
+            0x3,
+        CodeMutable = PermissionChangeAllowed |
+            IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            MapAllowed |
+            TransferMemoryAllowed |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IpcBufferAllowed |
+            IsPoolAllocated |
+            MapProcessAllowed |
+            AttributeChangeAllowed |
+            CodeMemoryAllowed |
+            LinearMapped |
+            PermissionLockAllowed |
+            0x4,
+        Heap = PermissionChangeAllowed |
+            IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            MapAllowed |
+            TransferMemoryAllowed |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IpcBufferAllowed |
+            IsPoolAllocated |
+            AttributeChangeAllowed |
+            CodeMemoryAllowed |
+            LinearMapped |
+            0x5,
+        SharedMemory = Mapped | IsPoolAllocated | LinearMapped | 0x6,
+        ModCodeStatic = ForceReadWritableByDebugSyscalls |
+            IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            ProcessPermissionChangeAllowed |
+            UnmapProcessCodeMemoryAllowed |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            MapProcessAllowed |
+            LinearMapped |
+            0x8,
+        ModCodeMutable = PermissionChangeAllowed |
+            IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            MapAllowed |
+            UnmapProcessCodeMemoryAllowed |
+            TransferMemoryAllowed |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IpcBufferAllowed |
+            IsPoolAllocated |
+            MapProcessAllowed |
+            AttributeChangeAllowed |
+            CodeMemoryAllowed |
+            LinearMapped |
+            PermissionLockAllowed |
+            0x9,
+        IpcBuffer0 = IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            LinearMapped |
+            0xA,
+        Stack = IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            LinearMapped |
+            0xB,
+        ThreadLocal = Mapped | IsPoolAllocated | LinearMapped | 0xC,
+        TransferMemoryIsolated = IpcSendAllowedType0 |
+            IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            AttributeChangeAllowed |
+            LinearMapped |
+            0xD,
+        TransferMemory = IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            LinearMapped |
+            0xE,
+        ProcessMemory = IpcSendAllowedType3 | IpcSendAllowedType1 | Mapped | IsPoolAllocated | LinearMapped | 0xF,
+        Reserved = 0x10,
+        IpcBuffer1 = IpcSendAllowedType3 |
+            IpcSendAllowedType1 |
+            Mapped |
+            QueryPhysicalAddressAllowed |
+            MapDeviceAllowed |
+            MapDeviceAlignedAllowed |
+            IsPoolAllocated |
+            LinearMapped |
+            0x11,
+        IpcBuffer3 = IpcSendAllowedType3 | Mapped | QueryPhysicalAddressAllowed | MapDeviceAllowed | IsPoolAllocated | LinearMapped | 0x12,
+        KernelStack = Mapped | 0x13,
+        CodeReadOnly = ForceReadWritableByDebugSyscalls | Mapped | IsPoolAllocated | LinearMapped | 0x14,
+        CodeWritable = Mapped | IsPoolAllocated | LinearMapped | 0x15,
+        UserMask = 0xFF,
+        Mask = 0xFFFFFFFF,
 
         PermissionChangeAllowed = 1 << 8,
         ForceReadWritableByDebugSyscalls = 1 << 9,
         IpcSendAllowedType0 = 1 << 10,
         IpcSendAllowedType3 = 1 << 11,
         IpcSendAllowedType1 = 1 << 12,
+        Mapped = 1 << 13,
         ProcessPermissionChangeAllowed = 1 << 14,
         MapAllowed = 1 << 15,
         UnmapProcessCodeMemoryAllowed = 1 << 16,
@@ -46,5 +166,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
         MapProcessAllowed = 1 << 23,
         AttributeChangeAllowed = 1 << 24,
         CodeMemoryAllowed = 1 << 25,
+        LinearMapped = 1 << 26,
+        PermissionLockAllowed = 1 << 27,
     }
 }
diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
index e4f48da1b..b07f5194e 100644
--- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
+++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
@@ -949,8 +949,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
 
             MemoryAttribute attributes = attributeMask | attributeValue;
 
+            const MemoryAttribute SupportedAttributes = MemoryAttribute.Uncached | MemoryAttribute.PermissionLocked;
+
             if (attributes != attributeMask ||
-               (attributes | MemoryAttribute.Uncached) != MemoryAttribute.Uncached)
+               (attributes | SupportedAttributes) != SupportedAttributes)
+            {
+                return KernelResult.InvalidCombination;
+            }
+
+            // The permission locked attribute can't be unset.
+            if ((attributeMask & MemoryAttribute.PermissionLocked) != (attributeValue & MemoryAttribute.PermissionLocked))
             {
                 return KernelResult.InvalidCombination;
             }