From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by mx.groups.io with SMTP id smtpd.web11.17196.1672935937730046540 for ; Thu, 05 Jan 2023 08:25:38 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=o4/3U0yy; spf=pass (domain: kernel.org, ip: 145.40.68.75, mailfrom: ardb@kernel.org) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id CF98FB81B35; Thu, 5 Jan 2023 16:25:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7C8BC433EF; Thu, 5 Jan 2023 16:25:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672935934; bh=1ALaaTuTxf4HQw+ZojbKTzJ3NV35C1xsOCOWG/2crbM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o4/3U0yyYegAZ/ZlAnhtvCRU6C8uI/TQaSnNb1pfsUR86vrh9yp5lJXykd0DHNmQa E0pQZFG0JWucHO61MU4i1r2wj11dwGUS6s5X+V//CWptmg2ANRMI5keVNLtRTtTJNA mmffK43cf91RkkK5mMzHSjImc9Y/1qlmEnhYNwJRXBrrAehkzbgCGHhAEgcCaF0VXo 4O6h9ny+lJDrPEaWQZufJdItJDsT5D+D9zsNWbv2+Y5kCIkkNWoh9euSixyaXRXPB5 6d6DamRdsgux+RFqkm1MXaJfoNQt6OqwwVibL1tYHh54LNJo0HWj0NgtpXDU1vsrOb uLofuQauHV4Jw== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: dann.frazier@canonical.com, Ard Biesheuvel Subject: [PATCH v2 2/2] ArmVirtPkg/ArmVirtQemu: Avoid early ID map on ThunderX Date: Thu, 5 Jan 2023 17:25:28 +0100 Message-Id: <20230105162528.1430368-2-ardb@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230105162528.1430368-1-ardb@kernel.org> References: <20230105162528.1430368-1-ardb@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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 --- ArmVirtPkg/ArmVirtQemu.dsc | 5 +++= ++ ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S | 15 +++= ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index f77443229e8e..5dd8b6104cca 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -31,6 +31,7 @@ [Defines] DEFINE SECURE_BOOT_ENABLE =3D FALSE=0D DEFINE TPM2_ENABLE =3D FALSE=0D DEFINE TPM2_CONFIG_ENABLE =3D FALSE=0D + DEFINE CAVIUM_ERRATUM_27456 =3D FALSE=0D =0D #=0D # Network definition=0D @@ -117,7 +118,11 @@ [LibraryClasses.common.UEFI_DRIVER] UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf=0D =0D [BuildOptions]=0D +!if $(CAVIUM_ERRATUM_27456) =3D=3D TRUE=0D + GCC:*_*_AARCH64_PP_FLAGS =3D -DCAVIUM_ERRATUM_27456=0D +!else=0D GCC:*_*_AARCH64_CC_XIPFLAGS =3D=3D=0D +!endif=0D =0D !include NetworkPkg/NetworkBuildOptions.dsc.inc=0D =0D diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelpe= r.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S index 1787d52fbf51..5ac7c732f6ec 100644 --- a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S @@ -42,6 +42,21 @@ =0D =0D ASM_FUNC(ArmPlatformPeiBootAction)=0D +#ifdef CAVIUM_ERRATUM_27456=0D + /*=0D + * On Cavium ThunderX, using non-global mappings that are executable at = EL1=0D + * results in I-cache corruption. So just avoid the early ID mapping the= re.=0D + *=0D + * MIDR implementor 0x43=0D + * MIDR part numbers 0xA1 0xA2 (but not 0xAF)=0D + */=0D + mrs x0, midr_el1 // read the MIDR into X0=0D + ubfx x1, x0, #24, #8 // grab implementor id=0D + ubfx x0, x0, #7, #9 // grab part number bits [11:3]=0D + cmp x1, #0x43 // compare implementor id=0D + ccmp x0, #0xA0 >> 3, #0, eq // compare part# bits [11:3]=0D + b.eq 0f=0D +#endif=0D mrs x0, CurrentEL // check current exception level=0D tbnz x0, #3, 0f // omit early ID map if above EL1=0D =0D --=20 2.39.0