Merge branches 'x86-urgent-for-linus' and 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: devicetree: Add missing early_init_dt_setup_initrd_arch stub
  x86: cpu-hotplug: Prevent softirq wakeup on wrong CPU

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  genirq: Prevent potential NULL dereference in irq_set_irq_wake()
This commit is contained in:
Linus Torvalds 2011-06-13 10:45:10 -07:00
commit 842c895d14
3 changed files with 27 additions and 0 deletions

View File

@ -13,6 +13,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/of_pci.h> #include <linux/of_pci.h>
#include <linux/initrd.h>
#include <asm/hpet.h> #include <asm/hpet.h>
#include <asm/irq_controller.h> #include <asm/irq_controller.h>
@ -98,6 +99,16 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
} }
#ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start,
unsigned long end)
{
initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end);
initrd_below_start_ok = 1;
}
#endif
void __init add_dtb(u64 data) void __init add_dtb(u64 data)
{ {
initial_dtb = data + offsetof(struct setup_data, data); initial_dtb = data + offsetof(struct setup_data, data);

View File

@ -285,6 +285,19 @@ notrace static void __cpuinit start_secondary(void *unused)
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
x86_platform.nmi_init(); x86_platform.nmi_init();
/*
* Wait until the cpu which brought this one up marked it
* online before enabling interrupts. If we don't do that then
* we can end up waking up the softirq thread before this cpu
* reached the active state, which makes the scheduler unhappy
* and schedule the softirq thread on the wrong cpu. This is
* only observable with forced threaded interrupts, but in
* theory it could also happen w/o them. It's just way harder
* to achieve.
*/
while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
cpu_relax();
/* enable local interrupts */ /* enable local interrupts */
local_irq_enable(); local_irq_enable();

View File

@ -491,6 +491,9 @@ int irq_set_irq_wake(unsigned int irq, unsigned int on)
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags); struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
int ret = 0; int ret = 0;
if (!desc)
return -EINVAL;
/* wakeup-capable irqs can be shared between drivers that /* wakeup-capable irqs can be shared between drivers that
* don't need to have the same sleep mode behaviors. * don't need to have the same sleep mode behaviors.
*/ */