diff options
Diffstat (limited to 'arch/x86/kernel/cpu/intel.c')
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index c3af167d0a70..b9693b80fc21 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -509,6 +509,90 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c) | |||
509 | } | 509 | } |
510 | } | 510 | } |
511 | 511 | ||
512 | #define MSR_IA32_TME_ACTIVATE 0x982 | ||
513 | |||
514 | /* Helpers to access TME_ACTIVATE MSR */ | ||
515 | #define TME_ACTIVATE_LOCKED(x) (x & 0x1) | ||
516 | #define TME_ACTIVATE_ENABLED(x) (x & 0x2) | ||
517 | |||
518 | #define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ | ||
519 | #define TME_ACTIVATE_POLICY_AES_XTS_128 0 | ||
520 | |||
521 | #define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ | ||
522 | |||
523 | #define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ | ||
524 | #define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 | ||
525 | |||
526 | /* Values for mktme_status (SW only construct) */ | ||
527 | #define MKTME_ENABLED 0 | ||
528 | #define MKTME_DISABLED 1 | ||
529 | #define MKTME_UNINITIALIZED 2 | ||
530 | static int mktme_status = MKTME_UNINITIALIZED; | ||
531 | |||
532 | static void detect_tme(struct cpuinfo_x86 *c) | ||
533 | { | ||
534 | u64 tme_activate, tme_policy, tme_crypto_algs; | ||
535 | int keyid_bits = 0, nr_keyids = 0; | ||
536 | static u64 tme_activate_cpu0 = 0; | ||
537 | |||
538 | rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); | ||
539 | |||
540 | if (mktme_status != MKTME_UNINITIALIZED) { | ||
541 | if (tme_activate != tme_activate_cpu0) { | ||
542 | /* Broken BIOS? */ | ||
543 | pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); | ||
544 | pr_err_once("x86/tme: MKTME is not usable\n"); | ||
545 | mktme_status = MKTME_DISABLED; | ||
546 | |||
547 | /* Proceed. We may need to exclude bits from x86_phys_bits. */ | ||
548 | } | ||
549 | } else { | ||
550 | tme_activate_cpu0 = tme_activate; | ||
551 | } | ||
552 | |||
553 | if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) { | ||
554 | pr_info_once("x86/tme: not enabled by BIOS\n"); | ||
555 | mktme_status = MKTME_DISABLED; | ||
556 | return; | ||
557 | } | ||
558 | |||
559 | if (mktme_status != MKTME_UNINITIALIZED) | ||
560 | goto detect_keyid_bits; | ||
561 | |||
562 | pr_info("x86/tme: enabled by BIOS\n"); | ||
563 | |||
564 | tme_policy = TME_ACTIVATE_POLICY(tme_activate); | ||
565 | if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128) | ||
566 | pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); | ||
567 | |||
568 | tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate); | ||
569 | if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { | ||
570 | pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", | ||
571 | tme_crypto_algs); | ||
572 | mktme_status = MKTME_DISABLED; | ||
573 | } | ||
574 | detect_keyid_bits: | ||
575 | keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate); | ||
576 | nr_keyids = (1UL << keyid_bits) - 1; | ||
577 | if (nr_keyids) { | ||
578 | pr_info_once("x86/mktme: enabled by BIOS\n"); | ||
579 | pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); | ||
580 | } else { | ||
581 | pr_info_once("x86/mktme: disabled by BIOS\n"); | ||
582 | } | ||
583 | |||
584 | if (mktme_status == MKTME_UNINITIALIZED) { | ||
585 | /* MKTME is usable */ | ||
586 | mktme_status = MKTME_ENABLED; | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * KeyID bits effectively lower the number of physical address | ||
591 | * bits. Update cpuinfo_x86::x86_phys_bits accordingly. | ||
592 | */ | ||
593 | c->x86_phys_bits -= keyid_bits; | ||
594 | } | ||
595 | |||
512 | static void init_intel_energy_perf(struct cpuinfo_x86 *c) | 596 | static void init_intel_energy_perf(struct cpuinfo_x86 *c) |
513 | { | 597 | { |
514 | u64 epb; | 598 | u64 epb; |
@@ -679,6 +763,9 @@ static void init_intel(struct cpuinfo_x86 *c) | |||
679 | if (cpu_has(c, X86_FEATURE_VMX)) | 763 | if (cpu_has(c, X86_FEATURE_VMX)) |
680 | detect_vmx_virtcap(c); | 764 | detect_vmx_virtcap(c); |
681 | 765 | ||
766 | if (cpu_has(c, X86_FEATURE_TME)) | ||
767 | detect_tme(c); | ||
768 | |||
682 | init_intel_energy_perf(c); | 769 | init_intel_energy_perf(c); |
683 | 770 | ||
684 | init_intel_misc_features(c); | 771 | init_intel_misc_features(c); |