diff options
| -rw-r--r-- | arch/x86/include/asm/io_apic.h | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/apic.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 34 |
3 files changed, 31 insertions, 17 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index ffcd08f96e47..373cc2bbcad2 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
| @@ -162,7 +162,8 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq); | |||
| 162 | extern void ioapic_init_mappings(void); | 162 | extern void ioapic_init_mappings(void); |
| 163 | 163 | ||
| 164 | #ifdef CONFIG_X86_64 | 164 | #ifdef CONFIG_X86_64 |
| 165 | extern int save_mask_IO_APIC_setup(void); | 165 | extern int save_IO_APIC_setup(void); |
| 166 | extern void mask_IO_APIC_setup(void); | ||
| 166 | extern void restore_IO_APIC_setup(void); | 167 | extern void restore_IO_APIC_setup(void); |
| 167 | extern void reinit_intr_remapped_IO_APIC(int); | 168 | extern void reinit_intr_remapped_IO_APIC(int); |
| 168 | #endif | 169 | #endif |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 699f8cf76bbb..85eb8e100818 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -1334,15 +1334,16 @@ void __init enable_IR_x2apic(void) | |||
| 1334 | return; | 1334 | return; |
| 1335 | } | 1335 | } |
| 1336 | 1336 | ||
| 1337 | local_irq_save(flags); | 1337 | ret = save_IO_APIC_setup(); |
| 1338 | mask_8259A(); | ||
| 1339 | |||
| 1340 | ret = save_mask_IO_APIC_setup(); | ||
| 1341 | if (ret) { | 1338 | if (ret) { |
| 1342 | pr_info("Saving IO-APIC state failed: %d\n", ret); | 1339 | pr_info("Saving IO-APIC state failed: %d\n", ret); |
| 1343 | goto end; | 1340 | goto end; |
| 1344 | } | 1341 | } |
| 1345 | 1342 | ||
| 1343 | local_irq_save(flags); | ||
| 1344 | mask_IO_APIC_setup(); | ||
| 1345 | mask_8259A(); | ||
| 1346 | |||
| 1346 | ret = enable_intr_remapping(1); | 1347 | ret = enable_intr_remapping(1); |
| 1347 | 1348 | ||
| 1348 | if (ret && x2apic_preenabled) { | 1349 | if (ret && x2apic_preenabled) { |
| @@ -1367,10 +1368,10 @@ end_restore: | |||
| 1367 | else | 1368 | else |
| 1368 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); | 1369 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); |
| 1369 | 1370 | ||
| 1370 | end: | ||
| 1371 | unmask_8259A(); | 1371 | unmask_8259A(); |
| 1372 | local_irq_restore(flags); | 1372 | local_irq_restore(flags); |
| 1373 | 1373 | ||
| 1374 | end: | ||
| 1374 | if (!ret) { | 1375 | if (!ret) { |
| 1375 | if (!x2apic_preenabled) | 1376 | if (!x2apic_preenabled) |
| 1376 | pr_info("Enabled x2apic and interrupt-remapping\n"); | 1377 | pr_info("Enabled x2apic and interrupt-remapping\n"); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index cf27795c641c..ff1759a1128e 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -853,9 +853,9 @@ __setup("pirq=", ioapic_pirq_setup); | |||
| 853 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; | 853 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; |
| 854 | 854 | ||
| 855 | /* | 855 | /* |
| 856 | * Saves and masks all the unmasked IO-APIC RTE's | 856 | * Saves all the IO-APIC RTE's |
| 857 | */ | 857 | */ |
| 858 | int save_mask_IO_APIC_setup(void) | 858 | int save_IO_APIC_setup(void) |
| 859 | { | 859 | { |
| 860 | union IO_APIC_reg_01 reg_01; | 860 | union IO_APIC_reg_01 reg_01; |
| 861 | unsigned long flags; | 861 | unsigned long flags; |
| @@ -880,16 +880,9 @@ int save_mask_IO_APIC_setup(void) | |||
| 880 | } | 880 | } |
| 881 | 881 | ||
| 882 | for (apic = 0; apic < nr_ioapics; apic++) | 882 | for (apic = 0; apic < nr_ioapics; apic++) |
| 883 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 883 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) |
| 884 | struct IO_APIC_route_entry entry; | 884 | early_ioapic_entries[apic][pin] = |
| 885 | |||
| 886 | entry = early_ioapic_entries[apic][pin] = | ||
| 887 | ioapic_read_entry(apic, pin); | 885 | ioapic_read_entry(apic, pin); |
| 888 | if (!entry.mask) { | ||
| 889 | entry.mask = 1; | ||
| 890 | ioapic_write_entry(apic, pin, entry); | ||
| 891 | } | ||
| 892 | } | ||
| 893 | 886 | ||
| 894 | return 0; | 887 | return 0; |
| 895 | 888 | ||
| @@ -902,6 +895,25 @@ nomem: | |||
| 902 | return -ENOMEM; | 895 | return -ENOMEM; |
| 903 | } | 896 | } |
| 904 | 897 | ||
| 898 | void mask_IO_APIC_setup(void) | ||
| 899 | { | ||
| 900 | int apic, pin; | ||
| 901 | |||
| 902 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
| 903 | if (!early_ioapic_entries[apic]) | ||
| 904 | break; | ||
| 905 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | ||
| 906 | struct IO_APIC_route_entry entry; | ||
| 907 | |||
| 908 | entry = early_ioapic_entries[apic][pin]; | ||
| 909 | if (!entry.mask) { | ||
| 910 | entry.mask = 1; | ||
| 911 | ioapic_write_entry(apic, pin, entry); | ||
| 912 | } | ||
| 913 | } | ||
| 914 | } | ||
| 915 | } | ||
| 916 | |||
| 905 | void restore_IO_APIC_setup(void) | 917 | void restore_IO_APIC_setup(void) |
| 906 | { | 918 | { |
| 907 | int apic, pin; | 919 | int apic, pin; |
