提交 6924a467 编写于 作者: L Linus Torvalds

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

Pull x86/apic changes from Ingo Molnar:
 "Smaller fixes"

* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/ioapic: Check attr against the previous setting when programmed more than once
  x86/ioapic/kcrash: Prevent crash_kexec() from deadlocking on ioapic_lock
  x86/acpi: Fix incorrect sanity check in acpi_register_lapic()
...@@ -715,4 +715,6 @@ static inline void exiting_ack_irq(void) ...@@ -715,4 +715,6 @@ static inline void exiting_ack_irq(void)
ack_APIC_irq(); ack_APIC_irq();
} }
extern void ioapic_zap_locks(void);
#endif /* _ASM_X86_APIC_H */ #endif /* _ASM_X86_APIC_H */
...@@ -199,7 +199,7 @@ static void acpi_register_lapic(int id, u8 enabled) ...@@ -199,7 +199,7 @@ static void acpi_register_lapic(int id, u8 enabled)
{ {
unsigned int ver = 0; unsigned int ver = 0;
if (id >= (MAX_LOCAL_APIC-1)) { if (id >= MAX_LOCAL_APIC) {
printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
return; return;
} }
...@@ -1120,6 +1120,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) ...@@ -1120,6 +1120,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
int ioapic; int ioapic;
int ioapic_pin; int ioapic_pin;
struct io_apic_irq_attr irq_attr; struct io_apic_irq_attr irq_attr;
int ret;
if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
return gsi; return gsi;
...@@ -1149,7 +1150,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) ...@@ -1149,7 +1150,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1); polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
if (ret < 0)
gsi = INT_MIN;
return gsi; return gsi;
} }
......
...@@ -1534,6 +1534,11 @@ void intel_ir_io_apic_print_entries(unsigned int apic, ...@@ -1534,6 +1534,11 @@ void intel_ir_io_apic_print_entries(unsigned int apic,
} }
} }
void ioapic_zap_locks(void)
{
raw_spin_lock_init(&ioapic_lock);
}
__apicdebuginit(void) print_IO_APIC(int ioapic_idx) __apicdebuginit(void) print_IO_APIC(int ioapic_idx)
{ {
union IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
...@@ -3375,12 +3380,15 @@ int io_apic_setup_irq_pin_once(unsigned int irq, int node, ...@@ -3375,12 +3380,15 @@ int io_apic_setup_irq_pin_once(unsigned int irq, int node,
{ {
unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin; unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin;
int ret; int ret;
struct IO_APIC_route_entry orig_entry;
/* Avoid redundant programming */ /* Avoid redundant programming */
if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) { if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) {
pr_debug("Pin %d-%d already programmed\n", pr_debug("Pin %d-%d already programmed\n", mpc_ioapic_id(ioapic_idx), pin);
mpc_ioapic_id(ioapic_idx), pin); orig_entry = ioapic_read_entry(attr->ioapic, pin);
return 0; if (attr->trigger == orig_entry.trigger && attr->polarity == orig_entry.polarity)
return 0;
return -EBUSY;
} }
ret = io_apic_setup_irq_pin(irq, node, attr); ret = io_apic_setup_irq_pin(irq, node, attr);
if (!ret) if (!ret)
......
...@@ -128,7 +128,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs) ...@@ -128,7 +128,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
cpu_emergency_svm_disable(); cpu_emergency_svm_disable();
lapic_shutdown(); lapic_shutdown();
#if defined(CONFIG_X86_IO_APIC) #ifdef CONFIG_X86_IO_APIC
/* Prevent crash_kexec() from deadlocking on ioapic_lock. */
ioapic_zap_locks();
disable_IO_APIC(); disable_IO_APIC();
#endif #endif
#ifdef CONFIG_HPET_TIMER #ifdef CONFIG_HPET_TIMER
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册