Skip to content

Commit cb06d8e

Browse files
kirylIngo Molnar
authored andcommitted
x86/tme: Detect if TME and MKTME is activated by BIOS
IA32_TME_ACTIVATE MSR (0x982) can be used to check if BIOS has enabled TME and MKTME. It includes which encryption policy/algorithm is selected for TME or available for MKTME. For MKTME, the MSR also enumerates how many KeyIDs are available. We would need to exclude KeyID bits from physical address bits. detect_tme() would adjust cpuinfo_x86::x86_phys_bits accordingly. We have to do this even if we are not going to use KeyID bits ourself. VM guests still have to know that these bits are not usable for physical address. Signed-off-by: Kirill A. Shutemov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Kai Huang <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Tom Lendacky <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 3c76db7 commit cb06d8e

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

arch/x86/kernel/cpu/intel.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,93 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
510510
}
511511
}
512512

513+
#define MSR_IA32_TME_ACTIVATE 0x982
514+
515+
/* Helpers to access TME_ACTIVATE MSR */
516+
#define TME_ACTIVATE_LOCKED(x) (x & 0x1)
517+
#define TME_ACTIVATE_ENABLED(x) (x & 0x2)
518+
519+
#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */
520+
#define TME_ACTIVATE_POLICY_AES_XTS_128 0
521+
522+
#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */
523+
524+
#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */
525+
#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1
526+
527+
/* Values for mktme_status (SW only construct) */
528+
#define MKTME_ENABLED 0
529+
#define MKTME_DISABLED 1
530+
#define MKTME_UNINITIALIZED 2
531+
static int mktme_status = MKTME_UNINITIALIZED;
532+
533+
static void detect_tme(struct cpuinfo_x86 *c)
534+
{
535+
u64 tme_activate, tme_policy, tme_crypto_algs;
536+
int keyid_bits = 0, nr_keyids = 0;
537+
static u64 tme_activate_cpu0 = 0;
538+
539+
rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate);
540+
541+
if (mktme_status != MKTME_UNINITIALIZED) {
542+
if (tme_activate != tme_activate_cpu0) {
543+
/* Broken BIOS? */
544+
pr_err_once("x86/tme: configuation is inconsistent between CPUs\n");
545+
pr_err_once("x86/tme: MKTME is not usable\n");
546+
mktme_status = MKTME_DISABLED;
547+
548+
/* Proceed. We may need to exclude bits from x86_phys_bits. */
549+
}
550+
} else {
551+
tme_activate_cpu0 = tme_activate;
552+
}
553+
554+
if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) {
555+
pr_info_once("x86/tme: not enabled by BIOS\n");
556+
mktme_status = MKTME_DISABLED;
557+
return;
558+
}
559+
560+
if (mktme_status != MKTME_UNINITIALIZED)
561+
goto detect_keyid_bits;
562+
563+
pr_info("x86/tme: enabled by BIOS\n");
564+
565+
tme_policy = TME_ACTIVATE_POLICY(tme_activate);
566+
if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128)
567+
pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy);
568+
569+
tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate);
570+
if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) {
571+
pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n",
572+
tme_crypto_algs);
573+
mktme_status = MKTME_DISABLED;
574+
}
575+
detect_keyid_bits:
576+
keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
577+
nr_keyids = (1UL << keyid_bits) - 1;
578+
if (nr_keyids) {
579+
pr_info_once("x86/mktme: enabled by BIOS\n");
580+
pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids);
581+
} else {
582+
pr_info_once("x86/mktme: disabled by BIOS\n");
583+
}
584+
585+
if (mktme_status == MKTME_UNINITIALIZED) {
586+
/* MKTME is usable */
587+
mktme_status = MKTME_ENABLED;
588+
}
589+
590+
/*
591+
* Exclude KeyID bits from physical address bits.
592+
*
593+
* We have to do this even if we are not going to use KeyID bits
594+
* ourself. VM guests still have to know that these bits are not usable
595+
* for physical address.
596+
*/
597+
c->x86_phys_bits -= keyid_bits;
598+
}
599+
513600
static void init_intel_energy_perf(struct cpuinfo_x86 *c)
514601
{
515602
u64 epb;
@@ -680,6 +767,9 @@ static void init_intel(struct cpuinfo_x86 *c)
680767
if (cpu_has(c, X86_FEATURE_VMX))
681768
detect_vmx_virtcap(c);
682769

770+
if (cpu_has(c, X86_FEATURE_TME))
771+
detect_tme(c);
772+
683773
init_intel_energy_perf(c);
684774

685775
init_intel_misc_features(c);

0 commit comments

Comments
 (0)