Commit ec73adba authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-fixes-for-linus' of...

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

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: add X86_FEATURE_XMM4_2 definitions
  x86: fix cpufreq + sched_clock() regression
  x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet against BAR, v3
  x86: do not enable TSC notifier if we don't need it
  x86 MCE: Fix CPU hotplug problem with multiple multicore AMD CPUs
  x86: fix: make PCI ECS for AMD CPUs hotplug capable
  x86: fix: do not run code in amd_bus.c on non-AMD CPUs
parents cc556c5c 2a61812a
...@@ -759,6 +759,7 @@ static struct sysdev_class mce_sysclass = { ...@@ -759,6 +759,7 @@ static struct sysdev_class mce_sysclass = {
}; };
DEFINE_PER_CPU(struct sys_device, device_mce); DEFINE_PER_CPU(struct sys_device, device_mce);
void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu) __cpuinitdata;
/* Why are there no generic functions for this? */ /* Why are there no generic functions for this? */
#define ACCESSOR(name, var, start) \ #define ACCESSOR(name, var, start) \
...@@ -883,9 +884,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, ...@@ -883,9 +884,13 @@ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb,
case CPU_ONLINE: case CPU_ONLINE:
case CPU_ONLINE_FROZEN: case CPU_ONLINE_FROZEN:
mce_create_device(cpu); mce_create_device(cpu);
if (threshold_cpu_callback)
threshold_cpu_callback(action, cpu);
break; break;
case CPU_DEAD: case CPU_DEAD:
case CPU_DEAD_FROZEN: case CPU_DEAD_FROZEN:
if (threshold_cpu_callback)
threshold_cpu_callback(action, cpu);
mce_remove_device(cpu); mce_remove_device(cpu);
break; break;
} }
......
...@@ -628,6 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank) ...@@ -628,6 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
deallocate_threshold_block(cpu, bank); deallocate_threshold_block(cpu, bank);
free_out: free_out:
kobject_del(b->kobj);
kobject_put(b->kobj); kobject_put(b->kobj);
kfree(b); kfree(b);
per_cpu(threshold_banks, cpu)[bank] = NULL; per_cpu(threshold_banks, cpu)[bank] = NULL;
...@@ -645,14 +646,11 @@ static void threshold_remove_device(unsigned int cpu) ...@@ -645,14 +646,11 @@ static void threshold_remove_device(unsigned int cpu)
} }
/* get notified when a cpu comes on/off */ /* get notified when a cpu comes on/off */
static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, static void __cpuinit amd_64_threshold_cpu_callback(unsigned long action,
unsigned long action, void *hcpu) unsigned int cpu)
{ {
/* cpu was unsigned int to begin with */
unsigned int cpu = (unsigned long)hcpu;
if (cpu >= NR_CPUS) if (cpu >= NR_CPUS)
goto out; return;
switch (action) { switch (action) {
case CPU_ONLINE: case CPU_ONLINE:
...@@ -666,14 +664,8 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, ...@@ -666,14 +664,8 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
default: default:
break; break;
} }
out:
return NOTIFY_OK;
} }
static struct notifier_block threshold_cpu_notifier __cpuinitdata = {
.notifier_call = threshold_cpu_callback,
};
static __init int threshold_init_device(void) static __init int threshold_init_device(void)
{ {
unsigned lcpu = 0; unsigned lcpu = 0;
...@@ -684,7 +676,7 @@ static __init int threshold_init_device(void) ...@@ -684,7 +676,7 @@ static __init int threshold_init_device(void)
if (err) if (err)
return err; return err;
} }
register_hotcpu_notifier(&threshold_cpu_notifier); threshold_cpu_callback = amd_64_threshold_cpu_callback;
return 0; return 0;
} }
......
...@@ -314,7 +314,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, ...@@ -314,7 +314,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
mark_tsc_unstable("cpufreq changes"); mark_tsc_unstable("cpufreq changes");
} }
set_cyc2ns_scale(tsc_khz_ref, freq->cpu); set_cyc2ns_scale(tsc_khz, freq->cpu);
return 0; return 0;
} }
...@@ -325,6 +325,10 @@ static struct notifier_block time_cpufreq_notifier_block = { ...@@ -325,6 +325,10 @@ static struct notifier_block time_cpufreq_notifier_block = {
static int __init cpufreq_tsc(void) static int __init cpufreq_tsc(void)
{ {
if (!cpu_has_tsc)
return 0;
if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
return 0;
cpufreq_register_notifier(&time_cpufreq_notifier_block, cpufreq_register_notifier(&time_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER); CPUFREQ_TRANSITION_NOTIFIER);
return 0; return 0;
......
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/topology.h> #include <linux/topology.h>
#include <linux/cpu.h>
#include "pci.h" #include "pci.h"
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
...@@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void) ...@@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void)
return 0; return 0;
} }
postcore_initcall(early_fill_mp_bus_info); #else /* !CONFIG_X86_64 */
#endif static int __init early_fill_mp_bus_info(void) { return 0; }
#endif /* !CONFIG_X86_64 */
/* common 32/64 bit code */ /* common 32/64 bit code */
#define ENABLE_CF8_EXT_CFG (1ULL << 46) #define ENABLE_CF8_EXT_CFG (1ULL << 46)
static void enable_pci_io_ecs_per_cpu(void *unused) static void enable_pci_io_ecs(void *unused)
{ {
u64 reg; u64 reg;
rdmsrl(MSR_AMD64_NB_CFG, reg); rdmsrl(MSR_AMD64_NB_CFG, reg);
...@@ -573,14 +576,51 @@ static void enable_pci_io_ecs_per_cpu(void *unused) ...@@ -573,14 +576,51 @@ static void enable_pci_io_ecs_per_cpu(void *unused)
} }
} }
static int __init enable_pci_io_ecs(void) static int __cpuinit amd_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{ {
int cpu = (long)hcpu;
switch(action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0);
break;
default:
break;
}
return NOTIFY_OK;
}
static struct notifier_block __cpuinitdata amd_cpu_notifier = {
.notifier_call = amd_cpu_notify,
};
static int __init pci_io_ecs_init(void)
{
int cpu;
/* assume all cpus from fam10h have IO ECS */ /* assume all cpus from fam10h have IO ECS */
if (boot_cpu_data.x86 < 0x10) if (boot_cpu_data.x86 < 0x10)
return 0; return 0;
on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1);
register_cpu_notifier(&amd_cpu_notifier);
for_each_online_cpu(cpu)
amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
(void *)(long)cpu);
pci_probe |= PCI_HAS_IO_ECS; pci_probe |= PCI_HAS_IO_ECS;
return 0;
}
static int __init amd_postcore_init(void)
{
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return 0;
early_fill_mp_bus_info();
pci_io_ecs_init();
return 0; return 0;
} }
postcore_initcall(enable_pci_io_ecs); postcore_initcall(amd_postcore_init);
...@@ -31,8 +31,11 @@ ...@@ -31,8 +31,11 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/acpi.h>
#include <asm/pat.h> #include <asm/pat.h>
#include <asm/hpet.h>
#include <asm/io_apic.h>
#include "pci.h" #include "pci.h"
...@@ -77,6 +80,77 @@ pcibios_align_resource(void *data, struct resource *res, ...@@ -77,6 +80,77 @@ pcibios_align_resource(void *data, struct resource *res,
} }
EXPORT_SYMBOL(pcibios_align_resource); EXPORT_SYMBOL(pcibios_align_resource);
static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
{
unsigned long base;
unsigned long size;
int i;
base = res->start;
size = (res->start == 0 && res->end == res->start) ? 0 :
(res->end - res->start + 1);
if (!base || !size)
return 0;
#ifdef CONFIG_HPET_TIMER
/* for hpet */
if (base == hpet_address && (res->flags & IORESOURCE_MEM)) {
dev_info(&dev->dev, "BAR has HPET at %08lx-%08lx\n",
base, base + size - 1);
return 1;
}
#endif
#ifdef CONFIG_X86_IO_APIC
for (i = 0; i < nr_ioapics; i++) {
unsigned long ioapic_phys = mp_ioapics[i].mp_apicaddr;
if (base == ioapic_phys && (res->flags & IORESOURCE_MEM)) {
dev_info(&dev->dev, "BAR has ioapic at %08lx-%08lx\n",
base, base + size - 1);
return 1;
}
}
#endif
#ifdef CONFIG_PCI_MMCONFIG
for (i = 0; i < pci_mmcfg_config_num; i++) {
unsigned long addr;
addr = pci_mmcfg_config[i].address;
if (base == addr && (res->flags & IORESOURCE_MEM)) {
dev_info(&dev->dev, "BAR has MMCONFIG at %08lx-%08lx\n",
base, base + size - 1);
return 1;
}
}
#endif
return 0;
}
static int check_platform(struct pci_dev *dev, struct resource *res)
{
struct resource *root = NULL;
/*
* forcibly insert it into the
* resource tree
*/
if (res->flags & IORESOURCE_MEM)
root = &iomem_resource;
else if (res->flags & IORESOURCE_IO)
root = &ioport_resource;
if (root && check_res_with_valid(dev, res)) {
insert_resource(root, res);
return 1;
}
return 0;
}
/* /*
* Handle resources of PCI devices. If the world were perfect, we could * Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't. * just allocate all the resource regions and do nothing more. It isn't.
...@@ -128,6 +202,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) ...@@ -128,6 +202,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
pr = pci_find_parent_resource(dev, r); pr = pci_find_parent_resource(dev, r);
if (!r->start || !pr || if (!r->start || !pr ||
request_resource(pr, r) < 0) { request_resource(pr, r) < 0) {
if (check_platform(dev, r))
continue;
dev_err(&dev->dev, "BAR %d: can't " dev_err(&dev->dev, "BAR %d: can't "
"allocate resource\n", idx); "allocate resource\n", idx);
/* /*
...@@ -171,6 +247,8 @@ static void __init pcibios_allocate_resources(int pass) ...@@ -171,6 +247,8 @@ static void __init pcibios_allocate_resources(int pass)
r->flags, disabled, pass); r->flags, disabled, pass);
pr = pci_find_parent_resource(dev, r); pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0) { if (!pr || request_resource(pr, r) < 0) {
if (check_platform(dev, r))
continue;
dev_err(&dev->dev, "BAR %d: can't " dev_err(&dev->dev, "BAR %d: can't "
"allocate resource\n", idx); "allocate resource\n", idx);
/* We'll assign a new address later */ /* We'll assign a new address later */
......
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ #define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ #define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */ #define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */
#define X86_FEATURE_XMM4_2 (4*32+20) /* Streaming SIMD Extensions-4.2 */
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ #define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
...@@ -189,6 +190,7 @@ extern const char * const x86_power_flags[32]; ...@@ -189,6 +190,7 @@ extern const char * const x86_power_flags[32];
#define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES) #define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES)
#define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
#define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT) #define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT)
#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2)
#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64) #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
# define cpu_has_invlpg 1 # define cpu_has_invlpg 1
......
...@@ -92,6 +92,7 @@ extern int mce_disabled; ...@@ -92,6 +92,7 @@ extern int mce_disabled;
void mce_log(struct mce *m); void mce_log(struct mce *m);
DECLARE_PER_CPU(struct sys_device, device_mce); DECLARE_PER_CPU(struct sys_device, device_mce);
extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
#ifdef CONFIG_X86_MCE_INTEL #ifdef CONFIG_X86_MCE_INTEL
void mce_intel_feature_init(struct cpuinfo_x86 *c); void mce_intel_feature_init(struct cpuinfo_x86 *c);
......
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