ArmVirtPkg/ArmVirtQemu: Avoid early ID map on ThunderX

The early ID map used by ArmVirtQemu uses ASID scoped non-global
mappings, as this allows us to switch to the permanent ID map seamlessly
without the need for explicit TLB maintenance.

However, this triggers a known erratum on ThunderX, which does not
tolerate non-global mappings that are executable at EL1, as this appears
to result in I-cache corruption. (Linux disables the KPTI based Meltdown
mitigation on ThunderX for the same reason)

So work around this, by detecting the CPU implementor and part number,
and proceeding without the early ID map if a ThunderX CPU is detected.

Note that this requires the C code to be built with strict alignment
again, as we may end up executing it with the MMU and caches off.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: dann frazier <dann.frazier@canonical.com>
This commit is contained in:
Ard Biesheuvel 2023-01-04 16:51:35 +01:00 committed by mergify[bot]
parent 5ee17c5418
commit ec54ce1f1a
2 changed files with 20 additions and 0 deletions

View File

@ -31,6 +31,7 @@
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE TPM2_ENABLE = FALSE
DEFINE TPM2_CONFIG_ENABLE = FALSE
DEFINE CAVIUM_ERRATUM_27456 = FALSE
#
# Network definition
@ -117,7 +118,11 @@
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
[BuildOptions]
!if $(CAVIUM_ERRATUM_27456) == TRUE
GCC:*_*_AARCH64_PP_FLAGS = -DCAVIUM_ERRATUM_27456
!else
GCC:*_*_AARCH64_CC_XIPFLAGS ==
!endif
!include NetworkPkg/NetworkBuildOptions.dsc.inc

View File

@ -42,6 +42,21 @@
ASM_FUNC(ArmPlatformPeiBootAction)
#ifdef CAVIUM_ERRATUM_27456
/*
* On Cavium ThunderX, using non-global mappings that are executable at EL1
* results in I-cache corruption. So just avoid the early ID mapping there.
*
* MIDR implementor 0x43
* MIDR part numbers 0xA1 0xA2 (but not 0xAF)
*/
mrs x0, midr_el1 // read the MIDR into X0
ubfx x1, x0, #24, #8 // grab implementor id
ubfx x0, x0, #7, #9 // grab part number bits [11:3]
cmp x1, #0x43 // compare implementor id
ccmp x0, #0xA0 >> 3, #0, eq // compare part# bits [11:3]
b.eq 0f
#endif
mrs x0, CurrentEL // check current exception level
tbnz x0, #3, 0f // omit early ID map if above EL1