mirror of
				https://github.com/ryujinx-mirror/ryujinx.git
				synced 2025-11-04 03:18:58 -06:00 
			
		
		
		
	LightningJit: Disable some cache ops and CTR_EL0 access on Windows Arm (#6326)
* LightningJit: Disable some cache ops and CTR_EL0 access on Windows Arm * Format whitespace * Delete unused code * Fix typo Co-authored-by: riperiperi <rhy3756547@hotmail.com> --------- Co-authored-by: riperiperi <rhy3756547@hotmail.com>
This commit is contained in:
		@@ -1106,6 +1106,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64
 | 
				
			|||||||
                case InstName.Mrs:
 | 
					                case InstName.Mrs:
 | 
				
			||||||
                case InstName.MsrImm:
 | 
					                case InstName.MsrImm:
 | 
				
			||||||
                case InstName.MsrReg:
 | 
					                case InstName.MsrReg:
 | 
				
			||||||
 | 
					                case InstName.Sysl:
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								src/Ryujinx.Cpu/LightningJit/Arm64/SysUtils.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/Ryujinx.Cpu/LightningJit/Arm64/SysUtils.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ryujinx.Cpu.LightningJit.Arm64
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static class SysUtils
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static (uint, uint, uint, uint) UnpackOp1CRnCRmOp2(uint encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            uint op1 = (encoding >> 16) & 7;
 | 
				
			||||||
 | 
					            uint crn = (encoding >> 12) & 0xf;
 | 
				
			||||||
 | 
					            uint crm = (encoding >> 8) & 0xf;
 | 
				
			||||||
 | 
					            uint op2 = (encoding >> 5) & 7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return (op1, crn, crm, op2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool IsCacheInstEl0(uint encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            (uint op1, uint crn, uint crm, uint op2) = UnpackOp1CRnCRmOp2(encoding);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ((op1 << 11) | (crn << 7) | (crm << 3) | op2) switch
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                0b011_0111_0100_001 => true, // DC ZVA
 | 
				
			||||||
 | 
					                0b011_0111_1010_001 => true, // DC CVAC
 | 
				
			||||||
 | 
					                0b011_0111_1100_001 => true, // DC CVAP
 | 
				
			||||||
 | 
					                0b011_0111_1011_001 => true, // DC CVAU
 | 
				
			||||||
 | 
					                0b011_0111_1110_001 => true, // DC CIVAC
 | 
				
			||||||
 | 
					                0b011_0111_0101_001 => true, // IC IVAU
 | 
				
			||||||
 | 
					                _ => false,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool IsCacheInstUciTrapped(uint encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            (uint op1, uint crn, uint crm, uint op2) = UnpackOp1CRnCRmOp2(encoding);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ((op1 << 11) | (crn << 7) | (crm << 3) | op2) switch
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                0b011_0111_1010_001 => true, // DC CVAC
 | 
				
			||||||
 | 
					                0b011_0111_1100_001 => true, // DC CVAP
 | 
				
			||||||
 | 
					                0b011_0111_1011_001 => true, // DC CVAU
 | 
				
			||||||
 | 
					                0b011_0111_1110_001 => true, // DC CIVAC
 | 
				
			||||||
 | 
					                0b011_0111_0101_001 => true, // IC IVAU
 | 
				
			||||||
 | 
					                _ => false,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -257,7 +257,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                (name, flags, AddressForm addressForm) = InstTable.GetInstNameAndFlags(encoding, cpuPreset.Version, cpuPreset.Features);
 | 
					                (name, flags, AddressForm addressForm) = InstTable.GetInstNameAndFlags(encoding, cpuPreset.Version, cpuPreset.Features);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (name.IsPrivileged())
 | 
					                if (name.IsPrivileged() || (name == InstName.Sys && IsPrivilegedSys(encoding)))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    name = InstName.UdfPermUndef;
 | 
					                    name = InstName.UdfPermUndef;
 | 
				
			||||||
                    flags = InstFlags.None;
 | 
					                    flags = InstFlags.None;
 | 
				
			||||||
@@ -341,6 +341,11 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
 | 
				
			|||||||
            return new(startAddress, address, insts, !isTruncated && !name.IsException(), isTruncated, isLoopEnd);
 | 
					            return new(startAddress, address, insts, !isTruncated && !name.IsException(), isTruncated, isLoopEnd);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static bool IsPrivilegedSys(uint encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return !SysUtils.IsCacheInstEl0(encoding);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static bool IsMrsNzcv(uint encoding)
 | 
					        private static bool IsMrsNzcv(uint encoding)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return (encoding & ~0x1fu) == 0xd53b4200u;
 | 
					            return (encoding & ~0x1fu) == 0xd53b4200u;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,14 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public static void RewriteSysInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
 | 
					        public static void RewriteSysInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            // TODO: Handle IC instruction, it should invalidate the JIT cache.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (InstEmitSystem.IsCacheInstForbidden(encoding))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // Current OS does not allow cache maintenance instructions from user mode, just do nothing.
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            int rtIndex = RegisterUtils.ExtractRt(encoding);
 | 
					            int rtIndex = RegisterUtils.ExtractRt(encoding);
 | 
				
			||||||
            if (rtIndex == RegisterUtils.ZrIndex)
 | 
					            if (rtIndex == RegisterUtils.ZrIndex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
 | 
				
			|||||||
                    asm.LdrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrEl0Offset);
 | 
					                    asm.LdrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrEl0Offset);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if ((encoding & ~0x1f) == 0xd53b0020 && IsAppleOS()) // mrs x0, ctr_el0
 | 
					            else if ((encoding & ~0x1f) == 0xd53b0020 && IsCtrEl0AccessForbidden()) // mrs x0, ctr_el0
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                uint rd = encoding & 0x1f;
 | 
					                uint rd = encoding & 0x1f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -115,7 +115,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if ((encoding & ~0x1f) == 0xd53b0020 && IsAppleOS()) // mrs x0, ctr_el0
 | 
					            else if ((encoding & ~0x1f) == 0xd53b0020 && IsCtrEl0AccessForbidden()) // mrs x0, ctr_el0
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -127,9 +127,16 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static bool IsAppleOS()
 | 
					        private static bool IsCtrEl0AccessForbidden()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return OperatingSystem.IsMacOS() || OperatingSystem.IsIOS();
 | 
					            // Only Linux allows accessing CTR_EL0 from user mode.
 | 
				
			||||||
 | 
					            return OperatingSystem.IsWindows() || OperatingSystem.IsMacOS() || OperatingSystem.IsIOS();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool IsCacheInstForbidden(uint encoding)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Windows does not allow the cache maintenance instructions to be used from user mode.
 | 
				
			||||||
 | 
					            return OperatingSystem.IsWindows() && SysUtils.IsCacheInstUciTrapped(encoding);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static bool NeedsContextStoreLoad(InstName name)
 | 
					        public static bool NeedsContextStoreLoad(InstName name)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user