On Tue, Oct 06, 2015 at 01:48:19PM +0100, Ard Biesheuvel wrote: > 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/XN or RO bits. > > For now, the 32-bit ARM versions remain unimplemented. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org> > --- > ArmPkg/Include/Library/ArmLib.h | 24 ++++++ > ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c | 90 ++++++++++++++++++++ > ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c | 36 ++++++++ > 3 files changed, 150 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 60f5cf188db3..011b529e8d6b 100644 > --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c > +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c > @@ -512,6 +512,96 @@ SetMemoryAttributes ( > return RETURN_SUCCESS; > } > > +STATIC > +RETURN_STATUS > +SetMemoryRegionAttribute ( > + 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) { > + Val = TT_PXN_MASK | TT_UXN_MASK; > + } else { > + Val = TT_XN_MASK; > + } > + > + return ArmSetMemoryRegionAttribute ( > + BaseAddress, > + Length, > + Val, > + ~TT_ADDRESS_MASK_BLOCK_ENTRY); > +} > + > +RETURN_STATUS > +ArmClearMemoryRegionNoExec ( > + IN EFI_PHYSICAL_ADDRESS BaseAddress, > + IN UINT64 Length > + ) > +{ > + UINT64 Mask; > + > + // XN maps to UXN in the EL1&0 translation regime > + Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK); > + > + return ArmSetMemoryRegionAttribute ( > + BaseAddress, > + Length, > + 0, > + 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
Provided you sort out the ArmSetMemoryRegionAttribute to SetMemoryRegionAttribute renaming before committing: Reviewed-by: Leif Lindholm <leif.lindh...@linaro.org> _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel