From 815819767c5794624e3e7bc2bebcabe8ea4de0f6 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 7 Nov 2023 13:24:10 -0300 Subject: Force all exclusive memory accesses to be ordered on AppleHv (#5898) * Implement reprotect method on virtual memory manager (currently stubbed) * Force all exclusive memory accesses to be ordered on AppleHv * Format whitespace * Fix test build * Fix comment copy/paste * Fix wrong bit for isLoad * Update src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs Co-authored-by: riperiperi --------- Co-authored-by: riperiperi --- .../HOS/Kernel/Memory/KMemoryPermission.cs | 46 ++++++++++++++++++++++ src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs | 10 +++-- .../HOS/Kernel/Memory/KPageTableBase.cs | 6 +-- .../HOS/Kernel/Memory/MemoryPermission.cs | 20 ---------- 4 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryPermission.cs delete mode 100644 src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs (limited to 'src/Ryujinx.HLE/HOS/Kernel/Memory') diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryPermission.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryPermission.cs new file mode 100644 index 00000000..32734574 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryPermission.cs @@ -0,0 +1,46 @@ +using Ryujinx.Memory; +using System; + +namespace Ryujinx.HLE.HOS.Kernel.Memory +{ + [Flags] + enum KMemoryPermission : uint + { + None = 0, + UserMask = Read | Write | Execute, + Mask = uint.MaxValue, + + Read = 1 << 0, + Write = 1 << 1, + Execute = 1 << 2, + DontCare = 1 << 28, + + ReadAndWrite = Read | Write, + ReadAndExecute = Read | Execute, + } + + static class KMemoryPermissionExtensions + { + public static MemoryPermission Convert(this KMemoryPermission permission) + { + MemoryPermission output = MemoryPermission.None; + + if (permission.HasFlag(KMemoryPermission.Read)) + { + output = MemoryPermission.Read; + } + + if (permission.HasFlag(KMemoryPermission.Write)) + { + output |= MemoryPermission.Write; + } + + if (permission.HasFlag(KMemoryPermission.Execute)) + { + output |= MemoryPermission.Execute; + } + + return output; + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs index dcfc8f4f..4cd3e6fd 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTable.cs @@ -203,15 +203,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory /// protected override Result Reprotect(ulong address, ulong pagesCount, KMemoryPermission permission) { - // TODO. + _cpuMemory.Reprotect(address, pagesCount * PageSize, permission.Convert()); + return Result.Success; } /// - protected override Result ReprotectWithAttributes(ulong address, ulong pagesCount, KMemoryPermission permission) + protected override Result ReprotectAndFlush(ulong address, ulong pagesCount, KMemoryPermission permission) { - // TODO. - return Result.Success; + // TODO: Flush JIT cache. + + return Reprotect(address, pagesCount, permission); } /// diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs index 2b00f802..2b6d4e4e 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs @@ -1255,7 +1255,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory if ((oldPermission & KMemoryPermission.Execute) != 0) { - result = ReprotectWithAttributes(address, pagesCount, permission); + result = ReprotectAndFlush(address, pagesCount, permission); } else { @@ -3036,13 +3036,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory protected abstract Result Reprotect(ulong address, ulong pagesCount, KMemoryPermission permission); /// - /// Changes the permissions of a given virtual memory region. + /// Changes the permissions of a given virtual memory region, while also flushing the cache. /// /// Virtual address of the region to have the permission changes /// Number of pages to have their permissions changed /// New permission /// Result of the permission change operation - protected abstract Result ReprotectWithAttributes(ulong address, ulong pagesCount, KMemoryPermission permission); + protected abstract Result ReprotectAndFlush(ulong address, ulong pagesCount, KMemoryPermission permission); /// /// Alerts the memory tracking that a given region has been read from or written to. diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs deleted file mode 100644 index 068cdbb8..00000000 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/MemoryPermission.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace Ryujinx.HLE.HOS.Kernel.Memory -{ - [Flags] - enum KMemoryPermission : uint - { - None = 0, - UserMask = Read | Write | Execute, - Mask = uint.MaxValue, - - Read = 1 << 0, - Write = 1 << 1, - Execute = 1 << 2, - DontCare = 1 << 28, - - ReadAndWrite = Read | Write, - ReadAndExecute = Read | Execute, - } -} -- cgit v1.2.3