Ring3: Added EL0 and PAN support for AARCH64.

This commit is contained in:
Mikhail Krichanov 2024-05-16 15:41:46 +03:00
parent bdd577e887
commit 6dc6cd62d4
10 changed files with 116 additions and 9 deletions

View File

@ -26,6 +26,7 @@
// ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions
#define AARCH64_MMFR1_VH (0xF << 8)
#define AARCH64_MMFR1_PAN (0xF << 20)
// ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions
#define AARCH64_PFR0_FP (0xF << 16)
@ -234,6 +235,16 @@ ArmReadCurrentEL (
VOID
);
VOID
ArmSetPan (
VOID
);
VOID
ArmClearPan (
VOID
);
UINTN
ArmWriteCptr (
IN UINT64 Cptr

View File

@ -134,6 +134,8 @@
#define TCR_EL1_AS_FIELD (36)
#define TCR_EL1_TBI0_FIELD (37)
#define TCR_EL1_TBI1_FIELD (38)
#define TCR_EL1_HPD0_FIELD (41)
#define TCR_EL1_HPD1_FIELD (42)
#define TCR_EL1_T0SZ_MASK (0x1FUL << TCR_EL1_T0SZ_FIELD)
#define TCR_EL1_EPD0_MASK (0x01UL << TCR_EL1_EPD0_FIELD)
#define TCR_EL1_IRGN0_MASK (0x03UL << TCR_EL1_IRGN0_FIELD)
@ -151,6 +153,8 @@
#define TCR_EL1_AS_MASK (0x01UL << TCR_EL1_AS_FIELD)
#define TCR_EL1_TBI0_MASK (0x01UL << TCR_EL1_TBI0_FIELD)
#define TCR_EL1_TBI1_MASK (0x01UL << TCR_EL1_TBI1_FIELD)
#define TCR_EL1_HPD0_MASK (0x01UL << TCR_EL1_HPD0_FIELD)
#define TCR_EL1_HPD1_MASK (0x01UL << TCR_EL1_HPD1_FIELD)
#define TCR_EL23_T0SZ_FIELD (0)
#define TCR_EL23_IRGN0_FIELD (8)

View File

@ -781,6 +781,18 @@ ArmHasVhe (
VOID
);
/**
Checks whether the CPU implements the Privileged Access Never.
@retval TRUE FEAT_PAN is implemented.
@retval FALSE FEAT_PAN is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasPan (
VOID
);
/**
Checks whether the CPU implements the Trace Buffer Extension.

View File

@ -120,6 +120,21 @@ ArmHasVhe (
return ((ArmReadIdAA64Mmfr1 () & AARCH64_MMFR1_VH) != 0);
}
/**
Checks whether the CPU implements the Privileged Access Never.
@retval TRUE FEAT_PAN is implemented.
@retval FALSE FEAT_PAN is not mplemented.
**/
BOOLEAN
EFIAPI
ArmHasPan (
VOID
)
{
return ((ArmReadIdAA64Mmfr1 () & AARCH64_MMFR1_PAN) != 0);
}
/**
Checks whether the CPU implements the Trace Buffer Extension.

View File

@ -464,6 +464,16 @@ ASM_FUNC(ArmReadCurrentEL)
mrs x0, CurrentEL
ret
// VOID ArmSetPan(VOID)
ASM_FUNC(ArmSetPan)
msr pan, #1
ret
// VOID ArmClearPan(VOID)
ASM_FUNC(ArmClearPan)
msr pan, #0
ret
// UINT32 ArmReadCntHctl(VOID)
ASM_FUNC(ArmReadCntHctl)
mrs x0, cnthctl_el2

View File

@ -451,14 +451,28 @@ GcdAttributeToPageAttribute (
}
}
if ((GcdAttributes & EFI_MEMORY_RO) != 0) {
PageAttributes |= TT_AP_NO_RO;
}
if ((GcdAttributes & EFI_MEMORY_RP) == 0) {
PageAttributes |= TT_AF;
}
if ((GcdAttributes & EFI_MEMORY_USER) != 0) {
PageAttributes |= TT_PXN_MASK;
if ((GcdAttributes & EFI_MEMORY_RO) != 0) {
PageAttributes |= TT_AP_RO_RO;
} else {
PageAttributes |= TT_AP_RW_RW;
}
} else {
PageAttributes |= TT_UXN_MASK;
if ((GcdAttributes & EFI_MEMORY_RO) != 0) {
PageAttributes |= TT_AP_NO_RO;
} else {
PageAttributes |= TT_AP_NO_RW;
}
}
return PageAttributes;
}

View File

@ -385,13 +385,27 @@ EfiAttributeToArmAttribute (
}
// Determine protection attributes
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
ArmAttributes |= TT_AP_NO_RO;
if ((EfiAttributes & EFI_MEMORY_USER) != 0) {
ArmAttributes |= TT_PXN_MASK;
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
ArmAttributes |= TT_AP_RO_RO;
} else {
ArmAttributes |= TT_AP_RW_RW;
}
} else {
ArmAttributes |= TT_UXN_MASK;
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
ArmAttributes |= TT_AP_NO_RO;
} else {
ArmAttributes |= TT_AP_NO_RW;
}
}
// Process eXecute Never attribute
if ((EfiAttributes & EFI_MEMORY_XP) != 0) {
ArmAttributes |= TT_PXN_MASK;
ArmAttributes |= TT_PXN_MASK | TT_UXN_MASK;
}
return ArmAttributes;

View File

@ -39,6 +39,7 @@ READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
APRIORI DXE {
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
}

View File

@ -787,7 +787,7 @@ DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-melf_
DEFINE GCC5_X64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error
DEFINE GCC5_ASM_FLAGS = DEF(GCC_ASM_FLAGS)
DEFINE GCC5_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -march=armv7-a
DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian
DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -mcpu=cortex-a76
DEFINE GCC5_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) -fstack-protector -mword-relocations
DEFINE GCC5_AARCH64_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small
DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--oformat=elf32-littlearm
@ -1291,7 +1291,7 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_
*_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto
*_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) -fuse-ld=lld
*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments
*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments -mcpu=cortex-a76
*_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN)
*_CLANGDWARF_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN)
*_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON)

View File

@ -5,6 +5,9 @@
**/
#include <Chipset/AArch64.h>
#include <Library/ArmLib.h>
#include "DxeMain.h"
VOID
@ -13,5 +16,28 @@ InitializeMsr (
VOID
)
{
UINTN Tcr;
//
// If HCR_EL2.NV is 1 and the current Exception level is EL1,
// then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2].
// CurrentEL == 1 -> HCR_EL2.NV == 0
//
// If stage 1 is enabled and stage 1 Base permissions use Direct permissions,
// then GCS access is not permitted and UnprivGCS and PrivGCS are not present.
//
// Disable Hierarchical permissions just in case.
//
Tcr = ArmGetTCR ();
Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK;
ArmSetTCR (Tcr);
if (ArmHasPan ()) {
//
// Enable Privileged Access Never feature.
//
ArmSetPan ();
} else {
DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n"));
ASSERT (FALSE);
}
}