]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmLib MMU: add functions to set/clear RO and XN bits on regions
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Thu, 8 Oct 2015 18:52:16 +0000 (18:52 +0000)
committerabiesheuvel <abiesheuvel@Edk2>
Thu, 8 Oct 2015 18:52:16 +0000 (18:52 +0000)
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.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18587 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Include/Library/ArmLib.h
ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c

index c83a5a7f1b3c74ba889a24a6c67d5a133c8e51a1..b4768841bd9daf107f8365631efdf47cfd030cec 100644 (file)
@@ -661,4 +661,28 @@ ArmUnsetCpuActlrBit (
   IN  UINTN    Bits\r
   );\r
 \r
+RETURN_STATUS\r
+ArmSetMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+RETURN_STATUS\r
+ArmClearMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+RETURN_STATUS\r
+ArmSetMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
+RETURN_STATUS\r
+ArmClearMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  );\r
+\r
 #endif // __ARM_LIB__\r
index 60f5cf188db31d376c40677171b97c3dd40de075..e40c09ae9685cdc8416b2e345a4e89f115a4dc00 100644 (file)
@@ -512,6 +512,96 @@ SetMemoryAttributes (
   return RETURN_SUCCESS;\r
 }\r
 \r
+STATIC\r
+RETURN_STATUS\r
+SetMemoryRegionAttribute (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length,\r
+  IN  UINT64                    Attributes,\r
+  IN  UINT64                    BlockEntryMask\r
+  )\r
+{\r
+  RETURN_STATUS                Status;\r
+  UINT64                       *RootTable;\r
+\r
+  RootTable = ArmGetTTBR0BaseAddress ();\r
+\r
+  Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask);\r
+  if (RETURN_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // Invalidate all TLB entries so changes are synced\r
+  ArmInvalidateTlb ();\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+RETURN_STATUS\r
+ArmSetMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  UINT64    Val;\r
+\r
+  if (ArmReadCurrentEL () == AARCH64_EL1) {\r
+    Val = TT_PXN_MASK | TT_UXN_MASK;\r
+  } else {\r
+    Val = TT_XN_MASK;\r
+  }\r
+\r
+  return SetMemoryRegionAttribute (\r
+           BaseAddress,\r
+           Length,\r
+           Val,\r
+           ~TT_ADDRESS_MASK_BLOCK_ENTRY);\r
+}\r
+\r
+RETURN_STATUS\r
+ArmClearMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  UINT64 Mask;\r
+\r
+  // XN maps to UXN in the EL1&0 translation regime\r
+  Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK);\r
+\r
+  return SetMemoryRegionAttribute (\r
+           BaseAddress,\r
+           Length,\r
+           0,\r
+           Mask);\r
+}\r
+\r
+RETURN_STATUS\r
+ArmSetMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  return SetMemoryRegionAttribute (\r
+           BaseAddress,\r
+           Length,\r
+           TT_AP_RO_RO,\r
+           ~TT_ADDRESS_MASK_BLOCK_ENTRY);\r
+}\r
+\r
+RETURN_STATUS\r
+ArmClearMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  return SetMemoryRegionAttribute (\r
+           BaseAddress,\r
+           Length,\r
+           TT_AP_NO_RO,\r
+           ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK));\r
+}\r
+\r
 RETURN_STATUS\r
 EFIAPI\r
 ArmConfigureMmu (\r
index d035ff3caa404b64017f412482f8305d8068e288..1287dfb1a9bbe70009815b450c0ea3fe46af80ad 100644 (file)
@@ -301,3 +301,39 @@ ArmConfigureMmu (
   ArmEnableMmu();\r
   return RETURN_SUCCESS;\r
 }\r
+\r
+RETURN_STATUS\r
+ArmSetMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+RETURN_STATUS\r
+ArmClearMemoryRegionNoExec (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+RETURN_STATUS\r
+ArmSetMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r
+\r
+RETURN_STATUS\r
+ArmClearMemoryRegionReadOnly (\r
+  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,\r
+  IN  UINT64                    Length\r
+  )\r
+{\r
+  return RETURN_UNSUPPORTED;\r
+}\r