From: Ard Biesheuvel Date: Wed, 22 Sep 2021 16:12:20 +0000 (+0200) Subject: ArmPkg/ArmMmuLib AARCH64: avoid EL0 accessible mappings X-Git-Tag: edk2-stable202202~19 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=017564d637e9c3051c2796d1d5b4d5df7179434c ArmPkg/ArmMmuLib AARCH64: avoid EL0 accessible mappings We never run any code at EL0, and so it would seem that any access permissions set for EL0 (via the AP[1] attribute in the page tables) are irrelevant. We currently set EL0 and EL1 permissions to the same value arbitrarily. However, this causes problems on hardware like the Apple M1 running the MacOS hypervisor framework, which enters EL1 with SCTLR_EL1.SPAN enabled, causing the Privileged Access Never (PAN) feature to be enabled on any exception taken to EL1, including the IRQ exceptions that handle our timer interrupt. When PAN is enabled, EL1 has no access to any mappings that are also accessible to EL0, causing the firmware to crash if it attempts to access such a mapping. Even though it is debatable whether or not SCTLR_EL1.SPAN should be disabled at entry or whether the firmware should put all UNKNOWN bits in all system registers in a consistent state (which it should), using EL0 permissions serves no purpose whatsoever so let's fix that regardless. Signed-off-by: Ard Biesheuvel Tested-by: Alexander Graf Acked-by: Leif Lindholm --- diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c index 8997b7f61f..8bb33046e7 100644 --- a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c +++ b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c @@ -305,7 +305,7 @@ EfiAttributeToArmAttribute ( // Determine protection attributes if ((EfiAttributes & EFI_MEMORY_RO) != 0) { - ArmAttributes |= TT_AP_RO_RO; + ArmAttributes |= TT_AP_NO_RO; } // Process eXecute Never attribute diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 89da40fd8e..4a0513392a 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -393,7 +393,7 @@ GcdAttributeToPageAttribute ( } if ((GcdAttributes & EFI_MEMORY_RO) != 0) { - PageAttributes |= TT_AP_RO_RO; + PageAttributes |= TT_AP_NO_RO; } return PageAttributes | TT_AF; @@ -492,7 +492,7 @@ ArmSetMemoryRegionReadOnly ( return SetMemoryRegionAttribute ( BaseAddress, Length, - TT_AP_RO_RO, + TT_AP_NO_RO, ~TT_ADDRESS_MASK_BLOCK_ENTRY ); } @@ -506,7 +506,7 @@ ArmClearMemoryRegionReadOnly ( return SetMemoryRegionAttribute ( BaseAddress, Length, - TT_AP_RW_RW, + TT_AP_NO_RW, ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK) ); }