Revision: 18587
http://sourceforge.net/p/edk2/code/18587
Author: abiesheuvel
Date: 2015-10-08 18:52:16 +0000 (Thu, 08 Oct 2015)
Log Message:
-----------
ArmPkg/ArmLib MMU: add functions to set/clear RO and XN bits on regions
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 <[email protected]>
Reviewed-by: Leif Lindholm <[email protected]>
Modified Paths:
--------------
trunk/edk2/ArmPkg/Include/Library/ArmLib.h
trunk/edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
trunk/edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
Modified: trunk/edk2/ArmPkg/Include/Library/ArmLib.h
===================================================================
--- trunk/edk2/ArmPkg/Include/Library/ArmLib.h 2015-10-08 18:52:06 UTC (rev
18586)
+++ trunk/edk2/ArmPkg/Include/Library/ArmLib.h 2015-10-08 18:52:16 UTC (rev
18587)
@@ -661,4 +661,28 @@
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__
Modified: trunk/edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c 2015-10-08
18:52:06 UTC (rev 18586)
+++ trunk/edk2/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c 2015-10-08
18:52:16 UTC (rev 18587)
@@ -512,7 +512,97 @@
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 SetMemoryRegionAttribute (
+ 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 SetMemoryRegionAttribute (
+ BaseAddress,
+ Length,
+ 0,
+ Mask);
+}
+
+RETURN_STATUS
+ArmSetMemoryRegionReadOnly (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ return SetMemoryRegionAttribute (
+ BaseAddress,
+ Length,
+ TT_AP_RO_RO,
+ ~TT_ADDRESS_MASK_BLOCK_ENTRY);
+}
+
+RETURN_STATUS
+ArmClearMemoryRegionReadOnly (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ return SetMemoryRegionAttribute (
+ BaseAddress,
+ Length,
+ TT_AP_NO_RO,
+ ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK));
+}
+
+RETURN_STATUS
EFIAPI
ArmConfigureMmu (
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
Modified: trunk/edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
===================================================================
--- trunk/edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c 2015-10-08 18:52:06 UTC
(rev 18586)
+++ trunk/edk2/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c 2015-10-08 18:52:16 UTC
(rev 18587)
@@ -301,3 +301,39 @@
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;
+}
------------------------------------------------------------------------------
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits