]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Nov 2016 16:39:56 +0000 (08:39 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Nov 2016 16:39:56 +0000 (08:39 -0800)
Pull x86 fixes from Ingo Molnar:
 "Misc fixes:

   - fix an Intel/MID boot crash/hang bug

   - fix a cache topology mis-parsing bug on certain AMD CPUs

   - fix a virtualization firmware bug by adding a check+quirk
     workaround on the kernel side"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/cpu: Deal with broken firmware (VMWare/XEN)
  x86/cpu/AMD: Fix cpu_llc_id for AMD Fam17h systems
  x86/platform/intel-mid: Retrofit pci_platform_pm_ops ->get_state hook

arch/x86/include/asm/intel-mid.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/platform/intel-mid/pwr.c
drivers/pci/pci-mid.c

index 5b6753d1f7f4e35f8066e89555c715badc46ca23..49da9f497b908b676d9ec0c22c8646817bf1f52b 100644 (file)
@@ -17,6 +17,7 @@
 
 extern int intel_mid_pci_init(void);
 extern int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state);
+extern pci_power_t intel_mid_pci_get_power_state(struct pci_dev *pdev);
 
 extern void intel_mid_pwr_power_off(void);
 
index b81fe2d63e15751c2cb7e61fd10dc85cc7f906b0..1e81a37c034e7821580f5165eb4359e209ef7823 100644 (file)
@@ -347,7 +347,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
 #ifdef CONFIG_SMP
        unsigned bits;
        int cpu = smp_processor_id();
-       unsigned int socket_id, core_complex_id;
 
        bits = c->x86_coreid_bits;
        /* Low order bits define the core id (index of core in socket) */
@@ -365,10 +364,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
         if (c->x86 != 0x17 || !cpuid_edx(0x80000006))
                return;
 
-       socket_id       = (c->apicid >> bits) - 1;
-       core_complex_id = (c->apicid & ((1 << bits) - 1)) >> 3;
-
-       per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id;
+       per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
 #endif
 }
 
index 9bd910a7dd0abc0d994c6e50250c6d104550dc1e..cc9e980c68ec47b39a8c4ae7ad3497d3d94bd53d 100644 (file)
@@ -978,6 +978,35 @@ static void x86_init_cache_qos(struct cpuinfo_x86 *c)
        }
 }
 
+/*
+ * The physical to logical package id mapping is initialized from the
+ * acpi/mptables information. Make sure that CPUID actually agrees with
+ * that.
+ */
+static void sanitize_package_id(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+       unsigned int pkg, apicid, cpu = smp_processor_id();
+
+       apicid = apic->cpu_present_to_apicid(cpu);
+       pkg = apicid >> boot_cpu_data.x86_coreid_bits;
+
+       if (apicid != c->initial_apicid) {
+               pr_err(FW_BUG "CPU%u: APIC id mismatch. Firmware: %x CPUID: %x\n",
+                      cpu, apicid, c->initial_apicid);
+               c->initial_apicid = apicid;
+       }
+       if (pkg != c->phys_proc_id) {
+               pr_err(FW_BUG "CPU%u: Using firmware package id %u instead of %u\n",
+                      cpu, pkg, c->phys_proc_id);
+               c->phys_proc_id = pkg;
+       }
+       c->logical_proc_id = topology_phys_to_logical_pkg(pkg);
+#else
+       c->logical_proc_id = 0;
+#endif
+}
+
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
@@ -1103,8 +1132,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 #ifdef CONFIG_NUMA
        numa_add_cpu(smp_processor_id());
 #endif
-       /* The boot/hotplug time assigment got cleared, restore it */
-       c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id);
+       sanitize_package_id(c);
 }
 
 /*
index 5d3b45ad1c034d4ca922ccdd10ad7d2edb565384..67375dda451c1bec9fe900899dee5a5898882281 100644 (file)
@@ -272,6 +272,25 @@ int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
 }
 EXPORT_SYMBOL_GPL(intel_mid_pci_set_power_state);
 
+pci_power_t intel_mid_pci_get_power_state(struct pci_dev *pdev)
+{
+       struct mid_pwr *pwr = midpwr;
+       int id, reg, bit;
+       u32 power;
+
+       if (!pwr || !pwr->available)
+               return PCI_UNKNOWN;
+
+       id = intel_mid_pwr_get_lss_id(pdev);
+       if (id < 0)
+               return PCI_UNKNOWN;
+
+       reg = (id * LSS_PWS_BITS) / 32;
+       bit = (id * LSS_PWS_BITS) % 32;
+       power = mid_pwr_get_state(pwr, reg);
+       return (__force pci_power_t)((power >> bit) & 3);
+}
+
 void intel_mid_pwr_power_off(void)
 {
        struct mid_pwr *pwr = midpwr;
index 55f453de562ee63b8e53ab90cf6b671ef676c2a8..c7f3408e31487ef2db339233c61a4e66d15bb07d 100644 (file)
@@ -29,6 +29,11 @@ static int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
        return intel_mid_pci_set_power_state(pdev, state);
 }
 
+static pci_power_t mid_pci_get_power_state(struct pci_dev *pdev)
+{
+       return intel_mid_pci_get_power_state(pdev);
+}
+
 static pci_power_t mid_pci_choose_state(struct pci_dev *pdev)
 {
        return PCI_D3hot;
@@ -52,6 +57,7 @@ static bool mid_pci_need_resume(struct pci_dev *dev)
 static struct pci_platform_pm_ops mid_pci_platform_pm = {
        .is_manageable  = mid_pci_power_manageable,
        .set_state      = mid_pci_set_power_state,
+       .get_state      = mid_pci_get_power_state,
        .choose_state   = mid_pci_choose_state,
        .sleep_wake     = mid_pci_sleep_wake,
        .run_wake       = mid_pci_run_wake,