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
This commit is contained in:
@@ -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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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 = {
|
|||||||
|
|
||||||
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;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
postcore_initcall(enable_pci_io_ecs);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
postcore_initcall(amd_postcore_init);
|
||||||
|
@@ -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,
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
#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];
|
|||||||
#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;
|
|||||||
|
|
||||||
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);
|
||||||
|
Reference in New Issue
Block a user