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, cpufeature: Unbreak compile with gcc 3.x
  x86, pat: Fix memory leak in free_memtype
  x86, k8: Fix section mismatch for powernowk8_exit()
  lib/atomic64_test: fix missing include of linux/kernel.h
  x86: remove last traces of quicklist usage
  x86, setup: Phoenix BIOS fixup is needed on Dell Inspiron Mini 1012
  x86: "nosmp" command line option should force the system into UP mode
  arch/x86/pci: use kasprintf
  x86, apic: ack all pending irqs when crashed/on kexec
This commit is contained in:
Linus Torvalds 2010-05-30 09:06:13 -07:00
commit 021fad8b70
11 changed files with 93 additions and 26 deletions

View File

@ -332,6 +332,7 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
#endif #endif
} }
#if __GNUC__ >= 4
#define static_cpu_has(bit) \ #define static_cpu_has(bit) \
( \ ( \
__builtin_constant_p(boot_cpu_has(bit)) ? \ __builtin_constant_p(boot_cpu_has(bit)) ? \
@ -340,6 +341,12 @@ static __always_inline __pure bool __static_cpu_has(u8 bit)
__static_cpu_has(bit) : \ __static_cpu_has(bit) : \
boot_cpu_has(bit) \ boot_cpu_has(bit) \
) )
#else
/*
* gcc 3.x is too stupid to do the static test; fall back to dynamic.
*/
#define static_cpu_has(bit) boot_cpu_has(bit)
#endif
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */

View File

@ -51,6 +51,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/mce.h> #include <asm/mce.h>
#include <asm/kvm_para.h> #include <asm/kvm_para.h>
#include <asm/tsc.h>
unsigned int num_processors; unsigned int num_processors;
@ -1151,8 +1152,13 @@ static void __cpuinit lapic_setup_esr(void)
*/ */
void __cpuinit setup_local_APIC(void) void __cpuinit setup_local_APIC(void)
{ {
unsigned int value; unsigned int value, queued;
int i, j; int i, j, acked = 0;
unsigned long long tsc = 0, ntsc;
long long max_loops = cpu_khz;
if (cpu_has_tsc)
rdtscll(tsc);
if (disable_apic) { if (disable_apic) {
arch_disable_smp_support(); arch_disable_smp_support();
@ -1204,13 +1210,32 @@ void __cpuinit setup_local_APIC(void)
* the interrupt. Hence a vector might get locked. It was noticed * the interrupt. Hence a vector might get locked. It was noticed
* for timer irq (vector 0x31). Issue an extra EOI to clear ISR. * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
*/ */
for (i = APIC_ISR_NR - 1; i >= 0; i--) { do {
value = apic_read(APIC_ISR + i*0x10); queued = 0;
for (j = 31; j >= 0; j--) { for (i = APIC_ISR_NR - 1; i >= 0; i--)
if (value & (1<<j)) queued |= apic_read(APIC_IRR + i*0x10);
ack_APIC_irq();
for (i = APIC_ISR_NR - 1; i >= 0; i--) {
value = apic_read(APIC_ISR + i*0x10);
for (j = 31; j >= 0; j--) {
if (value & (1<<j)) {
ack_APIC_irq();
acked++;
}
}
} }
} if (acked > 256) {
printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n",
acked);
break;
}
if (cpu_has_tsc) {
rdtscll(ntsc);
max_loops = (cpu_khz << 10) - (ntsc - tsc);
} else
max_loops--;
} while (queued && max_loops > 0);
WARN_ON(max_loops <= 0);
/* /*
* Now that we are all set up, enable the APIC * Now that we are all set up, enable the APIC

View File

@ -1497,8 +1497,8 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
* simply keep the boost-disable flag in sync with the current global * simply keep the boost-disable flag in sync with the current global
* state. * state.
*/ */
static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action, static int cpb_notify(struct notifier_block *nb, unsigned long action,
void *hcpu) void *hcpu)
{ {
unsigned cpu = (long)hcpu; unsigned cpu = (long)hcpu;
u32 lo, hi; u32 lo, hi;
@ -1528,7 +1528,7 @@ static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action,
return NOTIFY_OK; return NOTIFY_OK;
} }
static struct notifier_block __cpuinitdata cpb_nb = { static struct notifier_block cpb_nb = {
.notifier_call = cpb_notify, .notifier_call = cpb_notify,
}; };

View File

@ -676,6 +676,17 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "DG45FC"), DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
}, },
}, },
/*
* The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so
* match on the product name.
*/
{
.callback = dmi_low_memory_corruption,
.ident = "Phoenix BIOS",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
},
},
#endif #endif
{} {}
}; };

View File

@ -1215,9 +1215,17 @@ __init void prefill_possible_map(void)
if (!num_processors) if (!num_processors)
num_processors = 1; num_processors = 1;
if (setup_possible_cpus == -1) i = setup_max_cpus ?: 1;
possible = num_processors + disabled_cpus; if (setup_possible_cpus == -1) {
else possible = num_processors;
#ifdef CONFIG_HOTPLUG_CPU
if (setup_max_cpus)
possible += disabled_cpus;
#else
if (possible > i)
possible = i;
#endif
} else
possible = setup_possible_cpus; possible = setup_possible_cpus;
total_cpus = max_t(int, possible, num_processors + disabled_cpus); total_cpus = max_t(int, possible, num_processors + disabled_cpus);
@ -1230,11 +1238,23 @@ __init void prefill_possible_map(void)
possible = nr_cpu_ids; possible = nr_cpu_ids;
} }
#ifdef CONFIG_HOTPLUG_CPU
if (!setup_max_cpus)
#endif
if (possible > i) {
printk(KERN_WARNING
"%d Processors exceeds max_cpus limit of %u\n",
possible, setup_max_cpus);
possible = i;
}
printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
possible, max_t(int, possible - num_processors, 0)); possible, max_t(int, possible - num_processors, 0));
for (i = 0; i < possible; i++) for (i = 0; i < possible; i++)
set_cpu_possible(i, true); set_cpu_possible(i, true);
for (; i < NR_CPUS; i++)
set_cpu_possible(i, false);
nr_cpu_ids = possible; nr_cpu_ids = possible;
} }

View File

@ -336,6 +336,7 @@ int free_memtype(u64 start, u64 end)
{ {
int err = -EINVAL; int err = -EINVAL;
int is_range_ram; int is_range_ram;
struct memtype *entry;
if (!pat_enabled) if (!pat_enabled)
return 0; return 0;
@ -355,17 +356,20 @@ int free_memtype(u64 start, u64 end)
} }
spin_lock(&memtype_lock); spin_lock(&memtype_lock);
err = rbt_memtype_erase(start, end); entry = rbt_memtype_erase(start, end);
spin_unlock(&memtype_lock); spin_unlock(&memtype_lock);
if (err) { if (!entry) {
printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n", printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
current->comm, current->pid, start, end); current->comm, current->pid, start, end);
return -EINVAL;
} }
kfree(entry);
dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end); dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end);
return err; return 0;
} }

View File

@ -28,15 +28,15 @@ static inline char *cattr_name(unsigned long flags)
#ifdef CONFIG_X86_PAT #ifdef CONFIG_X86_PAT
extern int rbt_memtype_check_insert(struct memtype *new, extern int rbt_memtype_check_insert(struct memtype *new,
unsigned long *new_type); unsigned long *new_type);
extern int rbt_memtype_erase(u64 start, u64 end); extern struct memtype *rbt_memtype_erase(u64 start, u64 end);
extern struct memtype *rbt_memtype_lookup(u64 addr); extern struct memtype *rbt_memtype_lookup(u64 addr);
extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos); extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos);
#else #else
static inline int rbt_memtype_check_insert(struct memtype *new, static inline int rbt_memtype_check_insert(struct memtype *new,
unsigned long *new_type) unsigned long *new_type)
{ return 0; } { return 0; }
static inline int rbt_memtype_erase(u64 start, u64 end) static inline struct memtype *rbt_memtype_erase(u64 start, u64 end)
{ return 0; } { return NULL; }
static inline struct memtype *rbt_memtype_lookup(u64 addr) static inline struct memtype *rbt_memtype_lookup(u64 addr)
{ return NULL; } { return NULL; }
static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos) static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos)

View File

@ -231,16 +231,17 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
return err; return err;
} }
int rbt_memtype_erase(u64 start, u64 end) struct memtype *rbt_memtype_erase(u64 start, u64 end)
{ {
struct memtype *data; struct memtype *data;
data = memtype_rb_exact_match(&memtype_rbroot, start, end); data = memtype_rb_exact_match(&memtype_rbroot, start, end);
if (!data) if (!data)
return -EINVAL; goto out;
rb_erase(&data->rb, &memtype_rbroot); rb_erase(&data->rb, &memtype_rbroot);
return 0; out:
return data;
} }
struct memtype *rbt_memtype_lookup(u64 addr) struct memtype *rbt_memtype_lookup(u64 addr)

View File

@ -9,7 +9,6 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/quicklist.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>

View File

@ -207,10 +207,9 @@ get_current_resources(struct acpi_device *device, int busnum,
if (!info.res) if (!info.res)
goto res_alloc_fail; goto res_alloc_fail;
info.name = kmalloc(16, GFP_KERNEL); info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum);
if (!info.name) if (!info.name)
goto name_alloc_fail; goto name_alloc_fail;
sprintf(info.name, "PCI Bus %04x:%02x", domain, busnum);
info.res_num = 0; info.res_num = 0;
acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,

View File

@ -9,6 +9,7 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0)