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>
---
ArmPkg/Drivers/CpuDxe/CpuDxe.h | 8 --
ArmPkg/Include/Library/ArmLib.h | 4 +
ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 91 ++++++++++++++------
3 files changed, 67 insertions(+), 36 deletions(-)
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
index d16abe400ef3..80c305d53dd1 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -39,14 +39,6 @@
#include <Protocol/LoadedImage.h>
-#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \
- EFI_MEMORY_WC | \
- EFI_MEMORY_WT | \
- EFI_MEMORY_WB | \
- EFI_MEMORY_UCE \
- )
-
-
/**
This function registers and enables the handler specified by InterruptHandler for a processor
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 19501efa991f..24ffe9f1aaa7 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -26,6 +26,10 @@
#error "Unknown chipset."
#endif
+#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | \
+ EFI_MEMORY_WT | EFI_MEMORY_WB | \
+ EFI_MEMORY_UCE)
+
/**
* The UEFI firmware must not use the ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_* attributes.
*
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
index 6aa970bc0514..9e0593ce598b 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
@@ -101,27 +101,6 @@ PageAttributeToGcdAttribute (
return GcdAttributes;
}
-ARM_MEMORY_REGION_ATTRIBUTES
-GcdAttributeToArmAttribute (
- IN UINT64 GcdAttributes
- )
-{
- switch (GcdAttributes & 0xFF) {
- case EFI_MEMORY_UC:
- return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
- case EFI_MEMORY_WC:
- return ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
- case EFI_MEMORY_WT:
- return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;
- case EFI_MEMORY_WB:
- return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
- default:
- DEBUG ((EFI_D_ERROR, "GcdAttributeToArmAttribute: 0x%lX attributes is not supported.\n", GcdAttributes));
- ASSERT (0);
- return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
- }
-}
-
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
@@ -425,6 +404,48 @@ FillTranslationTable (
);
}
+STATIC
+UINT64
+GcdAttributeToPageAttribute (
+ IN UINT64 GcdAttributes
+ )
+{
+ UINT64 PageAttributes;
+
+ switch (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) {
+ case EFI_MEMORY_UC:
+ PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY;
+ break;
+ case EFI_MEMORY_WC:
+ PageAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
+ break;
+ case EFI_MEMORY_WT:
+ PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE;
+ break;
+ case EFI_MEMORY_WB:
+ PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;
+ break;
+ default:
+ PageAttributes = TT_ATTR_INDX_MASK;
+ break;
+ }
+
+ if ((GcdAttributes & EFI_MEMORY_XP) != 0 ||
+ (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) == EFI_MEMORY_UC) {
+ if (ArmReadCurrentEL () == AARCH64_EL2) {
+ PageAttributes |= TT_XN_MASK;
+ } else {
+ PageAttributes |= TT_UXN_MASK | TT_PXN_MASK;
+ }
+ }
+
+ if ((GcdAttributes & EFI_MEMORY_RO) != 0) {
+ PageAttributes |= TT_AP_RO_RO;
+ }
+
+ return PageAttributes | TT_AF;
+}
+
RETURN_STATUS
SetMemoryAttributes (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
@@ -434,17 +455,31 @@ SetMemoryAttributes (
)
{
RETURN_STATUS Status;
- ARM_MEMORY_REGION_DESCRIPTOR MemoryRegion;
UINT64 *TranslationTable;
-
- MemoryRegion.PhysicalBase = BaseAddress;
- MemoryRegion.VirtualBase = BaseAddress;
- MemoryRegion.Length = Length;
- MemoryRegion.Attributes = GcdAttributeToArmAttribute (Attributes);
+ UINT64 PageAttributes;
+ UINT64 PageAttributeMask;
+
+ PageAttributes = GcdAttributeToPageAttribute (Attributes);
+ PageAttributeMask = 0;
+
+ if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) {
+ //
+ // No memory type was set in Attributes, so we are going to update the
+ // permissions only.
+ //
+ PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK;
+ PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK |
+ TT_PXN_MASK | TT_XN_MASK);
+ }
TranslationTable = ArmGetTTBR0BaseAddress ();
- Status = FillTranslationTable (TranslationTable, &MemoryRegion);
+ Status = UpdateRegionMapping (
+ TranslationTable,
+ BaseAddress,
+ Length,
+ PageAttributes,
+ PageAttributeMask);
if (RETURN_ERROR (Status)) {
return Status;
}
--
2.7.4
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
On Wed, Feb 15, 2017 at 05:11:56PM +0000, Ard Biesheuvel wrote: > 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> (This diff is also a lot less confusing :) > --- > ArmPkg/Drivers/CpuDxe/CpuDxe.h | 8 -- > ArmPkg/Include/Library/ArmLib.h | 4 + > ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 91 ++++++++++++++------ > 3 files changed, 67 insertions(+), 36 deletions(-) > > diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h > index d16abe400ef3..80c305d53dd1 100644 > --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h > +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h > @@ -39,14 +39,6 @@ > #include <Protocol/LoadedImage.h> > > > -#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \ > - EFI_MEMORY_WC | \ > - EFI_MEMORY_WT | \ > - EFI_MEMORY_WB | \ > - EFI_MEMORY_UCE \ > - ) > - > - > /** > This function registers and enables the handler specified by InterruptHandler for a processor > interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the > diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h > index 19501efa991f..24ffe9f1aaa7 100644 > --- a/ArmPkg/Include/Library/ArmLib.h > +++ b/ArmPkg/Include/Library/ArmLib.h > @@ -26,6 +26,10 @@ > #error "Unknown chipset." > #endif > > +#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | \ > + EFI_MEMORY_WT | EFI_MEMORY_WB | \ > + EFI_MEMORY_UCE) > + > /** > * The UEFI firmware must not use the ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_* attributes. > * > diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c > index 6aa970bc0514..9e0593ce598b 100644 > --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c > +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c > @@ -101,27 +101,6 @@ PageAttributeToGcdAttribute ( > return GcdAttributes; > } > > -ARM_MEMORY_REGION_ATTRIBUTES > -GcdAttributeToArmAttribute ( > - IN UINT64 GcdAttributes > - ) > -{ > - switch (GcdAttributes & 0xFF) { > - case EFI_MEMORY_UC: > - return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; > - case EFI_MEMORY_WC: > - return ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED; > - case EFI_MEMORY_WT: > - return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH; > - case EFI_MEMORY_WB: > - return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; > - default: > - DEBUG ((EFI_D_ERROR, "GcdAttributeToArmAttribute: 0x%lX attributes is not supported.\n", GcdAttributes)); > - ASSERT (0); > - return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; > - } > -} > - > #define MIN_T0SZ 16 > #define BITS_PER_LEVEL 9 > > @@ -425,6 +404,48 @@ FillTranslationTable ( > ); > } > > +STATIC > +UINT64 > +GcdAttributeToPageAttribute ( > + IN UINT64 GcdAttributes > + ) > +{ > + UINT64 PageAttributes; > + > + switch (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) { > + case EFI_MEMORY_UC: > + PageAttributes = TT_ATTR_INDX_DEVICE_MEMORY; > + break; > + case EFI_MEMORY_WC: > + PageAttributes = TT_ATTR_INDX_MEMORY_NON_CACHEABLE; > + break; > + case EFI_MEMORY_WT: > + PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE; > + break; > + case EFI_MEMORY_WB: > + PageAttributes = TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE; > + break; > + default: > + PageAttributes = TT_ATTR_INDX_MASK; > + break; > + } > + > + if ((GcdAttributes & EFI_MEMORY_XP) != 0 || > + (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) == EFI_MEMORY_UC) { > + if (ArmReadCurrentEL () == AARCH64_EL2) { > + PageAttributes |= TT_XN_MASK; > + } else { > + PageAttributes |= TT_UXN_MASK | TT_PXN_MASK; > + } > + } > + > + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { > + PageAttributes |= TT_AP_RO_RO; > + } > + > + return PageAttributes | TT_AF; > +} > + > RETURN_STATUS > SetMemoryAttributes ( > IN EFI_PHYSICAL_ADDRESS BaseAddress, > @@ -434,17 +455,31 @@ SetMemoryAttributes ( > ) > { > RETURN_STATUS Status; > - ARM_MEMORY_REGION_DESCRIPTOR MemoryRegion; > UINT64 *TranslationTable; > - > - MemoryRegion.PhysicalBase = BaseAddress; > - MemoryRegion.VirtualBase = BaseAddress; > - MemoryRegion.Length = Length; > - MemoryRegion.Attributes = GcdAttributeToArmAttribute (Attributes); > + UINT64 PageAttributes; > + UINT64 PageAttributeMask; > + > + PageAttributes = GcdAttributeToPageAttribute (Attributes); > + PageAttributeMask = 0; > + > + if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) { > + // > + // No memory type was set in Attributes, so we are going to update the > + // permissions only. > + // > + PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK; > + PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK | > + TT_PXN_MASK | TT_XN_MASK); > + } > > TranslationTable = ArmGetTTBR0BaseAddress (); > > - Status = FillTranslationTable (TranslationTable, &MemoryRegion); > + Status = UpdateRegionMapping ( > + TranslationTable, > + BaseAddress, > + Length, > + PageAttributes, > + PageAttributeMask); > if (RETURN_ERROR (Status)) { > return Status; > } > -- > 2.7.4 > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.