mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
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:
commit
ec73adba51
@ -759,6 +759,7 @@ static struct sysdev_class mce_sysclass = {
|
||||
};
|
||||
|
||||
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? */
|
||||
#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_FROZEN:
|
||||
mce_create_device(cpu);
|
||||
if (threshold_cpu_callback)
|
||||
threshold_cpu_callback(action, cpu);
|
||||
break;
|
||||
case CPU_DEAD:
|
||||
case CPU_DEAD_FROZEN:
|
||||
if (threshold_cpu_callback)
|
||||
threshold_cpu_callback(action, cpu);
|
||||
mce_remove_device(cpu);
|
||||
break;
|
||||
}
|
||||
|
@ -628,6 +628,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
|
||||
deallocate_threshold_block(cpu, bank);
|
||||
|
||||
free_out:
|
||||
kobject_del(b->kobj);
|
||||
kobject_put(b->kobj);
|
||||
kfree(b);
|
||||
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 */
|
||||
static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
static void __cpuinit amd_64_threshold_cpu_callback(unsigned long action,
|
||||
unsigned int cpu)
|
||||
{
|
||||
/* cpu was unsigned int to begin with */
|
||||
unsigned int cpu = (unsigned long)hcpu;
|
||||
|
||||
if (cpu >= NR_CPUS)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
switch (action) {
|
||||
case CPU_ONLINE:
|
||||
@ -666,14 +664,8 @@ static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb,
|
||||
default:
|
||||
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)
|
||||
{
|
||||
unsigned lcpu = 0;
|
||||
@ -684,7 +676,7 @@ static __init int threshold_init_device(void)
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
register_hotcpu_notifier(&threshold_cpu_notifier);
|
||||
threshold_cpu_callback = amd_64_threshold_cpu_callback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
|
||||
mark_tsc_unstable("cpufreq changes");
|
||||
}
|
||||
|
||||
set_cyc2ns_scale(tsc_khz_ref, freq->cpu);
|
||||
set_cyc2ns_scale(tsc_khz, freq->cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -325,6 +325,10 @@ static struct notifier_block time_cpufreq_notifier_block = {
|
||||
|
||||
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_TRANSITION_NOTIFIER);
|
||||
return 0;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/topology.h>
|
||||
#include <linux/cpu.h>
|
||||
#include "pci.h"
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void)
|
||||
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 */
|
||||
|
||||
#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;
|
||||
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 */
|
||||
if (boot_cpu_data.x86 < 0x10)
|
||||
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;
|
||||
|
||||
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/errno.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <asm/pat.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/io_apic.h>
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
@ -77,6 +80,77 @@ pcibios_align_resource(void *data, struct resource *res,
|
||||
}
|
||||
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
|
||||
* 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);
|
||||
if (!r->start || !pr ||
|
||||
request_resource(pr, r) < 0) {
|
||||
if (check_platform(dev, r))
|
||||
continue;
|
||||
dev_err(&dev->dev, "BAR %d: can't "
|
||||
"allocate resource\n", idx);
|
||||
/*
|
||||
@ -171,6 +247,8 @@ static void __init pcibios_allocate_resources(int pass)
|
||||
r->flags, disabled, pass);
|
||||
pr = pci_find_parent_resource(dev, r);
|
||||
if (!pr || request_resource(pr, r) < 0) {
|
||||
if (check_platform(dev, r))
|
||||
continue;
|
||||
dev_err(&dev->dev, "BAR %d: can't "
|
||||
"allocate resource\n", idx);
|
||||
/* We'll assign a new address later */
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
|
||||
#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
|
||||
#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 */
|
||||
#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_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
|
||||
#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)
|
||||
# define cpu_has_invlpg 1
|
||||
|
@ -92,6 +92,7 @@ extern int mce_disabled;
|
||||
|
||||
void mce_log(struct mce *m);
|
||||
DECLARE_PER_CPU(struct sys_device, device_mce);
|
||||
extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
|
||||
|
||||
#ifdef CONFIG_X86_MCE_INTEL
|
||||
void mce_intel_feature_init(struct cpuinfo_x86 *c);
|
||||
|
Loading…
Reference in New Issue
Block a user