diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-04 11:39:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-04 11:39:05 -0400 |
commit | 6924a4672dd07dbe11d76fe597d17a092434232f (patch) | |
tree | ab533f30241e9b4ce8bce0d4d08a37c4fffeb71e | |
parent | ac3c1c4f1c77190408162aee559c655090597072 (diff) | |
parent | 25aa2957973d361081ac6c8b6e5a0d9d7a83fef6 (diff) |
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()
-rw-r--r-- | arch/x86/include/asm/apic.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/crash.c | 4 |
4 files changed, 21 insertions, 6 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index f8119b582c3c..1d2091a226bc 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -715,4 +715,6 @@ static inline void exiting_ack_irq(void) | |||
715 | ack_APIC_irq(); | 715 | ack_APIC_irq(); |
716 | } | 716 | } |
717 | 717 | ||
718 | extern void ioapic_zap_locks(void); | ||
719 | |||
718 | #endif /* _ASM_X86_APIC_H */ | 720 | #endif /* _ASM_X86_APIC_H */ |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 2627a81253ee..81aa73b8ecf5 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -199,7 +199,7 @@ static void acpi_register_lapic(int id, u8 enabled) | |||
199 | { | 199 | { |
200 | unsigned int ver = 0; | 200 | unsigned int ver = 0; |
201 | 201 | ||
202 | if (id >= (MAX_LOCAL_APIC-1)) { | 202 | if (id >= MAX_LOCAL_APIC) { |
203 | printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); | 203 | printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); |
204 | return; | 204 | return; |
205 | } | 205 | } |
@@ -1120,6 +1120,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
1120 | int ioapic; | 1120 | int ioapic; |
1121 | int ioapic_pin; | 1121 | int ioapic_pin; |
1122 | struct io_apic_irq_attr irq_attr; | 1122 | struct io_apic_irq_attr irq_attr; |
1123 | int ret; | ||
1123 | 1124 | ||
1124 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) | 1125 | if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) |
1125 | return gsi; | 1126 | return gsi; |
@@ -1149,7 +1150,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
1149 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, | 1150 | set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, |
1150 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, | 1151 | trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, |
1151 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); | 1152 | polarity == ACPI_ACTIVE_HIGH ? 0 : 1); |
1152 | io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); | 1153 | ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); |
1154 | if (ret < 0) | ||
1155 | gsi = INT_MIN; | ||
1153 | 1156 | ||
1154 | return gsi; | 1157 | return gsi; |
1155 | } | 1158 | } |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 9ed796ccc32c..e63a5bd2a78f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1534,6 +1534,11 @@ void intel_ir_io_apic_print_entries(unsigned int apic, | |||
1534 | } | 1534 | } |
1535 | } | 1535 | } |
1536 | 1536 | ||
1537 | void ioapic_zap_locks(void) | ||
1538 | { | ||
1539 | raw_spin_lock_init(&ioapic_lock); | ||
1540 | } | ||
1541 | |||
1537 | __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | 1542 | __apicdebuginit(void) print_IO_APIC(int ioapic_idx) |
1538 | { | 1543 | { |
1539 | union IO_APIC_reg_00 reg_00; | 1544 | union IO_APIC_reg_00 reg_00; |
@@ -3375,12 +3380,15 @@ int io_apic_setup_irq_pin_once(unsigned int irq, int node, | |||
3375 | { | 3380 | { |
3376 | unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin; | 3381 | unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin; |
3377 | int ret; | 3382 | int ret; |
3383 | struct IO_APIC_route_entry orig_entry; | ||
3378 | 3384 | ||
3379 | /* Avoid redundant programming */ | 3385 | /* Avoid redundant programming */ |
3380 | if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) { | 3386 | if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) { |
3381 | pr_debug("Pin %d-%d already programmed\n", | 3387 | pr_debug("Pin %d-%d already programmed\n", mpc_ioapic_id(ioapic_idx), pin); |
3382 | mpc_ioapic_id(ioapic_idx), pin); | 3388 | orig_entry = ioapic_read_entry(attr->ioapic, pin); |
3383 | return 0; | 3389 | if (attr->trigger == orig_entry.trigger && attr->polarity == orig_entry.polarity) |
3390 | return 0; | ||
3391 | return -EBUSY; | ||
3384 | } | 3392 | } |
3385 | ret = io_apic_setup_irq_pin(irq, node, attr); | 3393 | ret = io_apic_setup_irq_pin(irq, node, attr); |
3386 | if (!ret) | 3394 | if (!ret) |
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 74467feb4dc5..e0e0841eef45 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c | |||
@@ -128,7 +128,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs) | |||
128 | cpu_emergency_svm_disable(); | 128 | cpu_emergency_svm_disable(); |
129 | 129 | ||
130 | lapic_shutdown(); | 130 | lapic_shutdown(); |
131 | #if defined(CONFIG_X86_IO_APIC) | 131 | #ifdef CONFIG_X86_IO_APIC |
132 | /* Prevent crash_kexec() from deadlocking on ioapic_lock. */ | ||
133 | ioapic_zap_locks(); | ||
132 | disable_IO_APIC(); | 134 | disable_IO_APIC(); |
133 | #endif | 135 | #endif |
134 | #ifdef CONFIG_HPET_TIMER | 136 | #ifdef CONFIG_HPET_TIMER |