Skip to content

Commit 6890cb1

Browse files
bonzinihansendc
authored andcommitted
x86/cpu/intel: Detect TME keyid bits before setting MTRR mask registers
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 <zixchen@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20240131230902.1867092-3-pbonzini%40redhat.com
1 parent 9a45819 commit 6890cb1

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
@@ -184,6 +184,90 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
184184
return false;
185185
}
186186

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

327418
static void bsp_init_intel(struct cpuinfo_x86 *c)
@@ -482,90 +573,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
482573
#endif
483574
}
484575

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

703710
init_ia32_feat_ctl(c);
704711

705-
if (cpu_has(c, X86_FEATURE_TME))
706-
detect_tme(c);
707-
708712
init_intel_misc_features(c);
709713

710714
split_lock_init();

0 commit comments

Comments
 (0)