]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmMmuLib: AARCH64: add support for modifying only permissions
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 15 Feb 2017 17:11:56 +0000 (17:11 +0000)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 21 Feb 2017 17:23:03 +0000 (17:23 +0000)
Since the new DXE page protection for PE/COFF images may invoke
EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes() with only permission
attributes set, add support for this in the AARCH64 MMU code.

Move the EFI_MEMORY_CACHETYPE_MASK macro to a shared location between
CpuDxe and ArmMmuLib so we don't have to introduce yet another
definition.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
ArmPkg/Drivers/CpuDxe/CpuDxe.h
ArmPkg/Include/Library/ArmLib.h
ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c

index d16abe400ef3c5c9a5a912de54abbe0311367d9d..80c305d53dd124394590dfa21a69e64f6c46b527 100644 (file)
 #include <Protocol/LoadedImage.h>\r
 \r
 \r
-#define EFI_MEMORY_CACHETYPE_MASK     (EFI_MEMORY_UC  | \\r
-                                       EFI_MEMORY_WC  | \\r
-                                       EFI_MEMORY_WT  | \\r
-                                       EFI_MEMORY_WB  | \\r
-                                       EFI_MEMORY_UCE   \\r
-                                       )\r
-\r
-\r
 /**\r
   This function registers and enables the handler specified by InterruptHandler for a processor\r
   interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the\r
index 19501efa991f5da6f2fbfb85271c5c74388bb99e..24ffe9f1aaa7d5c54bc585ec9ddde5269f3dd40e 100644 (file)
  #error "Unknown chipset."\r
 #endif\r
 \r
+#define EFI_MEMORY_CACHETYPE_MASK   (EFI_MEMORY_UC | EFI_MEMORY_WC | \\r
+                                     EFI_MEMORY_WT | EFI_MEMORY_WB | \\r
+                                     EFI_MEMORY_UCE)\r
+\r
 /**\r
  * The UEFI firmware must not use the ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_* attributes.\r
  *\r
index 6aa970bc0514e6a73f4aee08a4885980f6a90d7d..9e0593ce598bd74aa37ddf446efe2088af27b61e 100644 (file)
@@ -101,27 +101,6 @@ PageAttributeToGcdAttribute (
   return GcdAttributes;\r
 }\r
 \r
-ARM_MEMORY_REGION_ATTRIBUTES\r
-GcdAttributeToArmAttribute (\r
-  IN UINT64 GcdAttributes\r
-  )\r
-{\r
-  switch (GcdAttributes & 0xFF) {\r
-  case EFI_MEMORY_UC:\r
-    return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;\r
-  case EFI_MEMORY_WC:\r
-    return ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;\r
-  case EFI_MEMORY_WT:\r
-    return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;\r
-  case EFI_MEMORY_WB:\r
-    return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;\r
-  default:\r
-    DEBUG ((EFI_D_ERROR, "GcdAttributeToArmAttribute: 0x%lX attributes is not supported.\n", GcdAttributes));\r
-    ASSERT (0);\r
-    return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;\r
-  }\r
-}\r
-\r
 #define MIN_T0SZ        16\r
 #define BITS_PER_LEVEL  9\r
 \r
@@ -425,6 +404,48 @@ FillTranslationTable (
            );\r
 }\r
 \r
+STATIC\r
+UINT64\r
+GcdAttributeToPageAttribute (\r
+  IN UINT64 GcdAttributes\r
+  )\r
+{\r
+  UINT64 PageAttributes;\r
+\r
+  switch (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) {\r
+  case EFI_MEMORY_UC:\r
+    PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY;\r
+    break;\r
+  case EFI_MEMORY_WC:\r
+    PageAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;\r
+    break;\r
+  case EFI_MEMORY_WT:\r
+    PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE;\r
+    break;\r
+  case EFI_MEMORY_WB:\r
+    PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;\r
+    break;\r
+  default:\r
+    PageAttributes = TT_ATTR_INDX_MASK;\r
+    break;\r
+  }\r
+\r
+  if ((GcdAttributes & EFI_MEMORY_XP) != 0 ||\r
+      (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) == EFI_MEMORY_UC) {\r
+    if (ArmReadCurrentEL () == AARCH64_EL2) {\r
+      PageAttributes |= TT_XN_MASK;\r
+    } else {\r
+      PageAttributes |= TT_UXN_MASK | TT_PXN_MASK;\r
+    }\r
+  }\r
+\r
+  if ((GcdAttributes & EFI_MEMORY_RO) != 0) {\r
+    PageAttributes |= TT_AP_RO_RO;\r
+  }\r
+\r
+  return PageAttributes | TT_AF;\r
+}\r
+\r
 RETURN_STATUS\r
 SetMemoryAttributes (\r
   IN EFI_PHYSICAL_ADDRESS      BaseAddress,\r
@@ -434,17 +455,31 @@ SetMemoryAttributes (
   )\r
 {\r
   RETURN_STATUS                Status;\r
-  ARM_MEMORY_REGION_DESCRIPTOR MemoryRegion;\r
   UINT64                      *TranslationTable;\r
-\r
-  MemoryRegion.PhysicalBase = BaseAddress;\r
-  MemoryRegion.VirtualBase = BaseAddress;\r
-  MemoryRegion.Length = Length;\r
-  MemoryRegion.Attributes = GcdAttributeToArmAttribute (Attributes);\r
+  UINT64                       PageAttributes;\r
+  UINT64                       PageAttributeMask;\r
+\r
+  PageAttributes = GcdAttributeToPageAttribute (Attributes);\r
+  PageAttributeMask = 0;\r
+\r
+  if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) {\r
+    //\r
+    // No memory type was set in Attributes, so we are going to update the\r
+    // permissions only.\r
+    //\r
+    PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK;\r
+    PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK |\r
+                          TT_PXN_MASK | TT_XN_MASK);\r
+  }\r
 \r
   TranslationTable = ArmGetTTBR0BaseAddress ();\r
 \r
-  Status = FillTranslationTable (TranslationTable, &MemoryRegion);\r
+  Status = UpdateRegionMapping (\r
+             TranslationTable,\r
+             BaseAddress,\r
+             Length,\r
+             PageAttributes,\r
+             PageAttributeMask);\r
   if (RETURN_ERROR (Status)) {\r
     return Status;\r
   }\r