Commit 8528d662 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

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
parents 5d69561b d49597fd
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
extern int intel_mid_pci_init(void); extern int intel_mid_pci_init(void);
extern int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state); 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); extern void intel_mid_pwr_power_off(void);
......
...@@ -347,7 +347,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c) ...@@ -347,7 +347,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
unsigned bits; unsigned bits;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
unsigned int socket_id, core_complex_id;
bits = c->x86_coreid_bits; bits = c->x86_coreid_bits;
/* Low order bits define the core id (index of core in socket) */ /* 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) ...@@ -365,10 +364,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
if (c->x86 != 0x17 || !cpuid_edx(0x80000006)) if (c->x86 != 0x17 || !cpuid_edx(0x80000006))
return; return;
socket_id = (c->apicid >> bits) - 1; per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
core_complex_id = (c->apicid & ((1 << bits) - 1)) >> 3;
per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id;
#endif #endif
} }
......
...@@ -978,6 +978,35 @@ static void x86_init_cache_qos(struct cpuinfo_x86 *c) ...@@ -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... * This does the hard work of actually picking apart the CPU stuff...
*/ */
...@@ -1103,8 +1132,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) ...@@ -1103,8 +1132,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
numa_add_cpu(smp_processor_id()); numa_add_cpu(smp_processor_id());
#endif #endif
/* The boot/hotplug time assigment got cleared, restore it */ sanitize_package_id(c);
c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id);
} }
/* /*
......
...@@ -272,6 +272,25 @@ int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state) ...@@ -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); 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) void intel_mid_pwr_power_off(void)
{ {
struct mid_pwr *pwr = midpwr; struct mid_pwr *pwr = midpwr;
......
...@@ -29,6 +29,11 @@ static int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state) ...@@ -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); 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) static pci_power_t mid_pci_choose_state(struct pci_dev *pdev)
{ {
return PCI_D3hot; return PCI_D3hot;
...@@ -52,6 +57,7 @@ static bool mid_pci_need_resume(struct pci_dev *dev) ...@@ -52,6 +57,7 @@ static bool mid_pci_need_resume(struct pci_dev *dev)
static struct pci_platform_pm_ops mid_pci_platform_pm = { static struct pci_platform_pm_ops mid_pci_platform_pm = {
.is_manageable = mid_pci_power_manageable, .is_manageable = mid_pci_power_manageable,
.set_state = mid_pci_set_power_state, .set_state = mid_pci_set_power_state,
.get_state = mid_pci_get_power_state,
.choose_state = mid_pci_choose_state, .choose_state = mid_pci_choose_state,
.sleep_wake = mid_pci_sleep_wake, .sleep_wake = mid_pci_sleep_wake,
.run_wake = mid_pci_run_wake, .run_wake = mid_pci_run_wake,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment