From nobody Fri Dec 19 18:47:11 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AC90CE7A86 for ; Fri, 22 Sep 2023 22:17:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230074AbjIVWR0 (ORCPT ); Fri, 22 Sep 2023 18:17:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229469AbjIVWRX (ORCPT ); Fri, 22 Sep 2023 18:17:23 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF76D19A for ; Fri, 22 Sep 2023 15:17:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695421036; x=1726957036; h=from:to:subject:date:message-id:mime-version; bh=IixbLIeMZZwYQb2hTR/zQYYMPvopwFtoJhCtUePjgz0=; b=YptUOuFpymrJ7dmp5a0CycK8C2NxqFoYn3T9PrlbeuU4QvRK7dBqTRCj 5bn0SZKDxtZl0nZ0yGJYPl6j/yNXU31gGoL583FyiYWFEtRGGl/wITqxN 2LhLTA6vYFdpey8pAlYwMHQ/ngTMQcdUKtBsgA2IiY83c4PLqN614/xc1 XLyUdPWDTRDfZAhmDUea8ewbQjlBNt3XN1osHGJ3LF9fy69IxgqJqHkAl qS7HYBcQC3VjchQsXncn7LIQM387yJYsmz4ldbn/dBy0R+ZpnV09T8/zh EEXgbnuMtXTebHQld+UrlJgzXtVg1u1bfaHvAUQnWmQyBrwbfi141z5Gn g==; X-IronPort-AV: E=McAfee;i="6600,9927,10841"; a="467248276" X-IronPort-AV: E=Sophos;i="6.03,169,1694761200"; d="scan'208";a="467248276" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2023 15:17:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10841"; a="921330208" X-IronPort-AV: E=Sophos;i="6.03,169,1694761200"; d="scan'208";a="921330208" Received: from tchuang-mobl1.amr.corp.intel.com (HELO jcompost-mobl.amr.corp.intel.com) ([10.212.85.229]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2023 15:17:15 -0700 From: "Compostella, Jeremy" To: , Subject: [PATCH] x86/cpu/intel: Fix MTRR verification for TME enabled platforms Date: Fri, 22 Sep 2023 15:17:14 -0700 Message-ID: <87v8c1ua39.fsf@jcompost-mobl.amr.corp.intel.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) Organization: Intel Corporation - 2200 Mission College Blvd. Santa Clara, CA 95052. USA MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On TME enabled platform, BIOS publishes MTRR taking into account Total Memory Encryption (TME) reserved bits. generic_get_mtrr() performs a sanity check of the MTRRs relying on the `phys_hi_rsvd' variable which is set using the cpuinfo_x86 structure `x86_phys_bits' field. But at the time the generic_get_mtrr() function is ran the `x86_phys_bits' has not been updated by detect_tme() when TME is enabled. Since the x86_phys_bits does not reflect yet the real maximal physical address size yet generic_get_mtrr() complains by logging the following messages. mtrr: your BIOS has configured an incorrect mask, fixing it. mtrr: your BIOS has configured an incorrect mask, fixing it. [...] For `x86_phys_bits' to be updated before generic_get_mtrr() runs, this patch moves the detect_tme() call from init_intel() to early_init_intel(). Signed-off-by: Jeremy Compostella --- arch/x86/kernel/cpu/intel.c | 174 ++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index be4045628fd3..34c54432bf00 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -184,6 +184,90 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *= c) return false; } =20 +#define MSR_IA32_TME_ACTIVATE 0x982 + +/* Helpers to access TME_ACTIVATE MSR */ +#define TME_ACTIVATE_LOCKED(x) (x & 0x1) +#define TME_ACTIVATE_ENABLED(x) (x & 0x2) + +#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ +#define TME_ACTIVATE_POLICY_AES_XTS_128 0 + +#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ + +#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ +#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 + +/* Values for mktme_status (SW only construct) */ +#define MKTME_ENABLED 0 +#define MKTME_DISABLED 1 +#define MKTME_UNINITIALIZED 2 +static int mktme_status =3D MKTME_UNINITIALIZED; + +static void detect_tme(struct cpuinfo_x86 *c) +{ + u64 tme_activate, tme_policy, tme_crypto_algs; + int keyid_bits =3D 0, nr_keyids =3D 0; + static u64 tme_activate_cpu0 =3D 0; + + rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); + + if (mktme_status !=3D MKTME_UNINITIALIZED) { + if (tme_activate !=3D tme_activate_cpu0) { + /* Broken BIOS? */ + pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); + pr_err_once("x86/tme: MKTME is not usable\n"); + mktme_status =3D MKTME_DISABLED; + + /* Proceed. We may need to exclude bits from x86_phys_bits. */ + } + } else { + tme_activate_cpu0 =3D tme_activate; + } + + if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activ= ate)) { + pr_info_once("x86/tme: not enabled by BIOS\n"); + mktme_status =3D MKTME_DISABLED; + return; + } + + if (mktme_status !=3D MKTME_UNINITIALIZED) + goto detect_keyid_bits; + + pr_info("x86/tme: enabled by BIOS\n"); + + tme_policy =3D TME_ACTIVATE_POLICY(tme_activate); + if (tme_policy !=3D TME_ACTIVATE_POLICY_AES_XTS_128) + pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); + + tme_crypto_algs =3D TME_ACTIVATE_CRYPTO_ALGS(tme_activate); + if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { + pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", + tme_crypto_algs); + mktme_status =3D MKTME_DISABLED; + } +detect_keyid_bits: + keyid_bits =3D TME_ACTIVATE_KEYID_BITS(tme_activate); + nr_keyids =3D (1UL << keyid_bits) - 1; + if (nr_keyids) { + pr_info_once("x86/mktme: enabled by BIOS\n"); + pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); + } else { + pr_info_once("x86/mktme: disabled by BIOS\n"); + } + + if (mktme_status =3D=3D MKTME_UNINITIALIZED) { + /* MKTME is usable */ + mktme_status =3D MKTME_ENABLED; + } + + /* + * KeyID bits effectively lower the number of physical address + * bits. Update cpuinfo_x86::x86_phys_bits accordingly. + */ + c->x86_phys_bits -=3D keyid_bits; +} + static void early_init_intel(struct cpuinfo_x86 *c) { u64 misc_enable; @@ -335,6 +419,9 @@ static void early_init_intel(struct cpuinfo_x86 *c) */ if (detect_extended_topology_early(c) < 0) detect_ht_early(c); + + if (cpu_has(c, X86_FEATURE_TME)) + detect_tme(c); } =20 static void bsp_init_intel(struct cpuinfo_x86 *c) @@ -495,90 +582,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c) #endif } =20 -#define MSR_IA32_TME_ACTIVATE 0x982 - -/* Helpers to access TME_ACTIVATE MSR */ -#define TME_ACTIVATE_LOCKED(x) (x & 0x1) -#define TME_ACTIVATE_ENABLED(x) (x & 0x2) - -#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ -#define TME_ACTIVATE_POLICY_AES_XTS_128 0 - -#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ - -#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ -#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 - -/* Values for mktme_status (SW only construct) */ -#define MKTME_ENABLED 0 -#define MKTME_DISABLED 1 -#define MKTME_UNINITIALIZED 2 -static int mktme_status =3D MKTME_UNINITIALIZED; - -static void detect_tme(struct cpuinfo_x86 *c) -{ - u64 tme_activate, tme_policy, tme_crypto_algs; - int keyid_bits =3D 0, nr_keyids =3D 0; - static u64 tme_activate_cpu0 =3D 0; - - rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); - - if (mktme_status !=3D MKTME_UNINITIALIZED) { - if (tme_activate !=3D tme_activate_cpu0) { - /* Broken BIOS? */ - pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); - pr_err_once("x86/tme: MKTME is not usable\n"); - mktme_status =3D MKTME_DISABLED; - - /* Proceed. We may need to exclude bits from x86_phys_bits. */ - } - } else { - tme_activate_cpu0 =3D tme_activate; - } - - if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activ= ate)) { - pr_info_once("x86/tme: not enabled by BIOS\n"); - mktme_status =3D MKTME_DISABLED; - return; - } - - if (mktme_status !=3D MKTME_UNINITIALIZED) - goto detect_keyid_bits; - - pr_info("x86/tme: enabled by BIOS\n"); - - tme_policy =3D TME_ACTIVATE_POLICY(tme_activate); - if (tme_policy !=3D TME_ACTIVATE_POLICY_AES_XTS_128) - pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); - - tme_crypto_algs =3D TME_ACTIVATE_CRYPTO_ALGS(tme_activate); - if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { - pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", - tme_crypto_algs); - mktme_status =3D MKTME_DISABLED; - } -detect_keyid_bits: - keyid_bits =3D TME_ACTIVATE_KEYID_BITS(tme_activate); - nr_keyids =3D (1UL << keyid_bits) - 1; - if (nr_keyids) { - pr_info_once("x86/mktme: enabled by BIOS\n"); - pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); - } else { - pr_info_once("x86/mktme: disabled by BIOS\n"); - } - - if (mktme_status =3D=3D MKTME_UNINITIALIZED) { - /* MKTME is usable */ - mktme_status =3D MKTME_ENABLED; - } - - /* - * KeyID bits effectively lower the number of physical address - * bits. Update cpuinfo_x86::x86_phys_bits accordingly. - */ - c->x86_phys_bits -=3D keyid_bits; -} - static void init_cpuid_fault(struct cpuinfo_x86 *c) { u64 msr; @@ -715,9 +718,6 @@ static void init_intel(struct cpuinfo_x86 *c) =20 init_ia32_feat_ctl(c); =20 - if (cpu_has(c, X86_FEATURE_TME)) - detect_tme(c); - init_intel_misc_features(c); =20 split_lock_init(); --=20 2.40.1