Skip to content

Commit ff0e559

Browse files
committed
x86/cpu/intel: Detect TME keyid bits before setting MTRR mask registers
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-427.16.1.el9_4 commit-author Paolo Bonzini <[email protected]> commit 6890cb1 MKTME repurposes the high bit of physical address to key id for encryption key and, even though MAXPHYADDR in CPUID[0x80000008] remains the same, the valid bits in the MTRR mask register are based on the reduced number of physical address bits. detect_tme() in arch/x86/kernel/cpu/intel.c detects TME and subtracts it from the total usable physical bits, but it is called too late. Move the call to early_init_intel() so that it is called in setup_arch(), before MTRRs are setup. This fixes boot on TDX-enabled systems, which until now only worked with "disable_mtrr_cleanup". Without the patch, the values written to the MTRRs mask registers were 52-bit wide (e.g. 0x000fffff_80000800) and the writes failed; with the patch, the values are 46-bit wide, which matches the reduced MAXPHYADDR that is shown in /proc/cpuinfo. Reported-by: Zixi Chen <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Cc:[email protected] Link: https://lore.kernel.org/all/20240131230902.1867092-3-pbonzini%40redhat.com (cherry picked from commit 6890cb1) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 4eea368 commit ff0e559

File tree

1 file changed

+91
-87
lines changed

1 file changed

+91
-87
lines changed

arch/x86/kernel/cpu/intel.c

Lines changed: 91 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,90 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
181181
return false;
182182
}
183183

184+
#define MSR_IA32_TME_ACTIVATE 0x982
185+
186+
/* Helpers to access TME_ACTIVATE MSR */
187+
#define TME_ACTIVATE_LOCKED(x) (x & 0x1)
188+
#define TME_ACTIVATE_ENABLED(x) (x & 0x2)
189+
190+
#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */
191+
#define TME_ACTIVATE_POLICY_AES_XTS_128 0
192+
193+
#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */
194+
195+
#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */
196+
#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1
197+
198+
/* Values for mktme_status (SW only construct) */
199+
#define MKTME_ENABLED 0
200+
#define MKTME_DISABLED 1
201+
#define MKTME_UNINITIALIZED 2
202+
static int mktme_status = MKTME_UNINITIALIZED;
203+
204+
static void detect_tme_early(struct cpuinfo_x86 *c)
205+
{
206+
u64 tme_activate, tme_policy, tme_crypto_algs;
207+
int keyid_bits = 0, nr_keyids = 0;
208+
static u64 tme_activate_cpu0 = 0;
209+
210+
rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate);
211+
212+
if (mktme_status != MKTME_UNINITIALIZED) {
213+
if (tme_activate != tme_activate_cpu0) {
214+
/* Broken BIOS? */
215+
pr_err_once("x86/tme: configuration is inconsistent between CPUs\n");
216+
pr_err_once("x86/tme: MKTME is not usable\n");
217+
mktme_status = MKTME_DISABLED;
218+
219+
/* Proceed. We may need to exclude bits from x86_phys_bits. */
220+
}
221+
} else {
222+
tme_activate_cpu0 = tme_activate;
223+
}
224+
225+
if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) {
226+
pr_info_once("x86/tme: not enabled by BIOS\n");
227+
mktme_status = MKTME_DISABLED;
228+
return;
229+
}
230+
231+
if (mktme_status != MKTME_UNINITIALIZED)
232+
goto detect_keyid_bits;
233+
234+
pr_info("x86/tme: enabled by BIOS\n");
235+
236+
tme_policy = TME_ACTIVATE_POLICY(tme_activate);
237+
if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128)
238+
pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy);
239+
240+
tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate);
241+
if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) {
242+
pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n",
243+
tme_crypto_algs);
244+
mktme_status = MKTME_DISABLED;
245+
}
246+
detect_keyid_bits:
247+
keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
248+
nr_keyids = (1UL << keyid_bits) - 1;
249+
if (nr_keyids) {
250+
pr_info_once("x86/mktme: enabled by BIOS\n");
251+
pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids);
252+
} else {
253+
pr_info_once("x86/mktme: disabled by BIOS\n");
254+
}
255+
256+
if (mktme_status == MKTME_UNINITIALIZED) {
257+
/* MKTME is usable */
258+
mktme_status = MKTME_ENABLED;
259+
}
260+
261+
/*
262+
* KeyID bits effectively lower the number of physical address
263+
* bits. Update cpuinfo_x86::x86_phys_bits accordingly.
264+
*/
265+
c->x86_phys_bits -= keyid_bits;
266+
}
267+
184268
static void early_init_intel(struct cpuinfo_x86 *c)
185269
{
186270
u64 misc_enable;
@@ -332,6 +416,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
332416
*/
333417
if (detect_extended_topology_early(c) < 0)
334418
detect_ht_early(c);
419+
420+
/*
421+
* Adjust the number of physical bits early because it affects the
422+
* valid bits of the MTRR mask registers.
423+
*/
424+
if (cpu_has(c, X86_FEATURE_TME))
425+
detect_tme_early(c);
335426
}
336427

337428
static void bsp_init_intel(struct cpuinfo_x86 *c)
@@ -492,90 +583,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
492583
#endif
493584
}
494585

495-
#define MSR_IA32_TME_ACTIVATE 0x982
496-
497-
/* Helpers to access TME_ACTIVATE MSR */
498-
#define TME_ACTIVATE_LOCKED(x) (x & 0x1)
499-
#define TME_ACTIVATE_ENABLED(x) (x & 0x2)
500-
501-
#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */
502-
#define TME_ACTIVATE_POLICY_AES_XTS_128 0
503-
504-
#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */
505-
506-
#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */
507-
#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1
508-
509-
/* Values for mktme_status (SW only construct) */
510-
#define MKTME_ENABLED 0
511-
#define MKTME_DISABLED 1
512-
#define MKTME_UNINITIALIZED 2
513-
static int mktme_status = MKTME_UNINITIALIZED;
514-
515-
static void detect_tme(struct cpuinfo_x86 *c)
516-
{
517-
u64 tme_activate, tme_policy, tme_crypto_algs;
518-
int keyid_bits = 0, nr_keyids = 0;
519-
static u64 tme_activate_cpu0 = 0;
520-
521-
rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate);
522-
523-
if (mktme_status != MKTME_UNINITIALIZED) {
524-
if (tme_activate != tme_activate_cpu0) {
525-
/* Broken BIOS? */
526-
pr_err_once("x86/tme: configuration is inconsistent between CPUs\n");
527-
pr_err_once("x86/tme: MKTME is not usable\n");
528-
mktme_status = MKTME_DISABLED;
529-
530-
/* Proceed. We may need to exclude bits from x86_phys_bits. */
531-
}
532-
} else {
533-
tme_activate_cpu0 = tme_activate;
534-
}
535-
536-
if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) {
537-
pr_info_once("x86/tme: not enabled by BIOS\n");
538-
mktme_status = MKTME_DISABLED;
539-
return;
540-
}
541-
542-
if (mktme_status != MKTME_UNINITIALIZED)
543-
goto detect_keyid_bits;
544-
545-
pr_info("x86/tme: enabled by BIOS\n");
546-
547-
tme_policy = TME_ACTIVATE_POLICY(tme_activate);
548-
if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128)
549-
pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy);
550-
551-
tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate);
552-
if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) {
553-
pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n",
554-
tme_crypto_algs);
555-
mktme_status = MKTME_DISABLED;
556-
}
557-
detect_keyid_bits:
558-
keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
559-
nr_keyids = (1UL << keyid_bits) - 1;
560-
if (nr_keyids) {
561-
pr_info_once("x86/mktme: enabled by BIOS\n");
562-
pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids);
563-
} else {
564-
pr_info_once("x86/mktme: disabled by BIOS\n");
565-
}
566-
567-
if (mktme_status == MKTME_UNINITIALIZED) {
568-
/* MKTME is usable */
569-
mktme_status = MKTME_ENABLED;
570-
}
571-
572-
/*
573-
* KeyID bits effectively lower the number of physical address
574-
* bits. Update cpuinfo_x86::x86_phys_bits accordingly.
575-
*/
576-
c->x86_phys_bits -= keyid_bits;
577-
}
578-
579586
static void init_cpuid_fault(struct cpuinfo_x86 *c)
580587
{
581588
u64 msr;
@@ -712,9 +719,6 @@ static void init_intel(struct cpuinfo_x86 *c)
712719

713720
init_ia32_feat_ctl(c);
714721

715-
if (cpu_has(c, X86_FEATURE_TME))
716-
detect_tme(c);
717-
718722
init_intel_misc_features(c);
719723

720724
split_lock_init();

0 commit comments

Comments
 (0)