Use the refactored UpdateRegionMapping () to traverse the translation tables, splitting block entries along the way if required, and apply a mask + or on each to set or clear the PXN/UXN or RO bits.
For now, the 32-bit ARM versions remain unimplemented. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <[email protected]> --- ArmPkg/Include/Library/ArmLib.h | 24 ++++++ ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c | 86 ++++++++++++++++++++ ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c | 36 ++++++++ 3 files changed, 146 insertions(+) diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h index c83a5a7f1b3c..b4768841bd9d 100644 --- a/ArmPkg/Include/Library/ArmLib.h +++ b/ArmPkg/Include/Library/ArmLib.h @@ -661,4 +661,28 @@ ArmUnsetCpuActlrBit ( IN UINTN Bits ); +RETURN_STATUS +ArmSetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +RETURN_STATUS +ArmClearMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +RETURN_STATUS +ArmSetMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +RETURN_STATUS +ArmClearMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + #endif // __ARM_LIB__ diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c index e7320e543c7f..8c6d3328adf7 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c @@ -510,6 +510,92 @@ SetMemoryAttributes ( return RETURN_SUCCESS; } +STATIC +RETURN_STATUS +ArmSetMemoryRegionAttribute ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN UINT64 BlockEntryMask + ) +{ + RETURN_STATUS Status; + UINT64 *RootTable; + + RootTable = ArmGetTTBR0BaseAddress (); + + Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask); + if (RETURN_ERROR (Status)) { + return Status; + } + + // Invalidate all TLB entries so changes are synced + ArmInvalidateTlb (); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +ArmSetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + UINT64 Val; + + if (ArmReadCurrentEL () == AARCH64_EL1) { + // The PXN bit may only be set for the EL1&0 translation regime. + Val = TT_PXN_MASK | TT_UXN_MASK; + } else { + Val = TT_UXN_MASK; + } + + return ArmSetMemoryRegionAttribute ( + BaseAddress, + Length, + Val, + ~TT_ADDRESS_MASK_BLOCK_ENTRY); +} + +RETURN_STATUS +ArmClearMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmSetMemoryRegionAttribute ( + BaseAddress, + Length, + 0, + ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_UXN_MASK)); +} + +RETURN_STATUS +ArmSetMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmSetMemoryRegionAttribute ( + BaseAddress, + Length, + TT_AP_RO_RO, + ~TT_ADDRESS_MASK_BLOCK_ENTRY); +} + +RETURN_STATUS +ArmClearMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmSetMemoryRegionAttribute ( + BaseAddress, + Length, + TT_AP_NO_RO, + ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK)); +} + RETURN_STATUS EFIAPI ArmConfigureMmu ( diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c index d035ff3caa40..1287dfb1a9bb 100644 --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c @@ -301,3 +301,39 @@ ArmConfigureMmu ( ArmEnableMmu(); return RETURN_SUCCESS; } + +RETURN_STATUS +ArmSetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +ArmClearMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +ArmSetMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +ArmClearMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return RETURN_UNSUPPORTED; +} -- 1.9.1 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

