x86/CPU: Move x86_cpuinfo::x86_max_cores assignment to detect_num_cpu_cores()
[linux-2.6-microblaze.git] / arch / x86 / kernel / cpu / intel.c
index c3af167..6c414e2 100644 (file)
@@ -453,24 +453,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
 #endif
 }
 
-/*
- * find out the number of processor cores on the die
- */
-static int intel_num_cpu_cores(struct cpuinfo_x86 *c)
-{
-       unsigned int eax, ebx, ecx, edx;
-
-       if (!IS_ENABLED(CONFIG_SMP) || c->cpuid_level < 4)
-               return 1;
-
-       /* Intel has a non-standard dependency on %ecx for this CPUID level. */
-       cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
-       if (eax & 0x1f)
-               return (eax >> 26) + 1;
-       else
-               return 1;
-}
-
 static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
 {
        /* Intel VMX MSR indicated features */
@@ -509,6 +491,90 @@ static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
        }
 }
 
+#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 = MKTME_UNINITIALIZED;
+
+static void detect_tme(struct cpuinfo_x86 *c)
+{
+       u64 tme_activate, tme_policy, tme_crypto_algs;
+       int keyid_bits = 0, nr_keyids = 0;
+       static u64 tme_activate_cpu0 = 0;
+
+       rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate);
+
+       if (mktme_status != MKTME_UNINITIALIZED) {
+               if (tme_activate != 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 = MKTME_DISABLED;
+
+                       /* Proceed. We may need to exclude bits from x86_phys_bits. */
+               }
+       } else {
+               tme_activate_cpu0 = tme_activate;
+       }
+
+       if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) {
+               pr_info_once("x86/tme: not enabled by BIOS\n");
+               mktme_status = MKTME_DISABLED;
+               return;
+       }
+
+       if (mktme_status != MKTME_UNINITIALIZED)
+               goto detect_keyid_bits;
+
+       pr_info("x86/tme: enabled by BIOS\n");
+
+       tme_policy = TME_ACTIVATE_POLICY(tme_activate);
+       if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128)
+               pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy);
+
+       tme_crypto_algs = 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 = MKTME_DISABLED;
+       }
+detect_keyid_bits:
+       keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate);
+       nr_keyids = (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 == MKTME_UNINITIALIZED) {
+               /* MKTME is usable */
+               mktme_status = MKTME_ENABLED;
+       }
+
+       /*
+        * KeyID bits effectively lower the number of physical address
+        * bits.  Update cpuinfo_x86::x86_phys_bits accordingly.
+        */
+       c->x86_phys_bits -= keyid_bits;
+}
+
 static void init_intel_energy_perf(struct cpuinfo_x86 *c)
 {
        u64 epb;
@@ -569,8 +635,6 @@ static void init_intel_misc_features(struct cpuinfo_x86 *c)
 
 static void init_intel(struct cpuinfo_x86 *c)
 {
-       unsigned int l2 = 0;
-
        early_init_intel(c);
 
        intel_workarounds(c);
@@ -587,19 +651,13 @@ static void init_intel(struct cpuinfo_x86 *c)
                 * let's use the legacy cpuid vector 0x1 and 0x4 for topology
                 * detection.
                 */
-               c->x86_max_cores = intel_num_cpu_cores(c);
+               detect_num_cpu_cores(c);
 #ifdef CONFIG_X86_32
                detect_ht(c);
 #endif
        }
 
-       l2 = init_intel_cacheinfo(c);
-
-       /* Detect legacy cache sizes if init_intel_cacheinfo did not */
-       if (l2 == 0) {
-               cpu_detect_cache_sizes(c);
-               l2 = c->x86_cache_size;
-       }
+       init_intel_cacheinfo(c);
 
        if (c->cpuid_level > 9) {
                unsigned eax = cpuid_eax(10);
@@ -612,7 +670,8 @@ static void init_intel(struct cpuinfo_x86 *c)
                set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
 
        if (boot_cpu_has(X86_FEATURE_DS)) {
-               unsigned int l1;
+               unsigned int l1, l2;
+
                rdmsr(MSR_IA32_MISC_ENABLE, l1, l2);
                if (!(l1 & (1<<11)))
                        set_cpu_cap(c, X86_FEATURE_BTS);
@@ -640,6 +699,7 @@ static void init_intel(struct cpuinfo_x86 *c)
         * Dixon is NOT a Celeron.
         */
        if (c->x86 == 6) {
+               unsigned int l2 = c->x86_cache_size;
                char *p = NULL;
 
                switch (c->x86_model) {
@@ -679,6 +739,9 @@ static void init_intel(struct cpuinfo_x86 *c)
        if (cpu_has(c, X86_FEATURE_VMX))
                detect_vmx_virtcap(c);
 
+       if (cpu_has(c, X86_FEATURE_TME))
+               detect_tme(c);
+
        init_intel_energy_perf(c);
 
        init_intel_misc_features(c);