aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-07 06:05:21 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-07 06:05:25 -0400
commit6c009ecef8cca28c7c09eb16d0802e37915a76e1 (patch)
tree11c773f780186fdb9fbc9c80a73fb7c8426b1fba /arch/x86
parent98c2aaf8be5baf7193be37fb28bce8e7327158bc (diff)
parentd508afb437daee7cf07da085b635c44a4ebf9b38 (diff)
Merge branch 'linus' into perfcounters/core
Merge reason: need the upstream facility added by: 7f1e2ca: hrtimer: fix rq->lock inversion (again) Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/apic.h3
-rw-r--r--arch/x86/include/asm/io_apic.h11
-rw-r--r--arch/x86/kernel/apic/apic.c70
-rw-r--r--arch/x86/kernel/apic/io_apic.c140
5 files changed, 167 insertions, 59 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bcf4cae711b4..6da24fc6a09e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -253,6 +253,7 @@ config SMP
253config X86_X2APIC 253config X86_X2APIC
254 bool "Support x2apic" 254 bool "Support x2apic"
255 depends on X86_LOCAL_APIC && X86_64 255 depends on X86_LOCAL_APIC && X86_64
256 select INTR_REMAP
256 ---help--- 257 ---help---
257 This enables x2apic support on CPUs that have this feature. 258 This enables x2apic support on CPUs that have this feature.
258 259
@@ -1882,7 +1883,6 @@ config DMAR_FLOPPY_WA
1882config INTR_REMAP 1883config INTR_REMAP
1883 bool "Support for Interrupt Remapping (EXPERIMENTAL)" 1884 bool "Support for Interrupt Remapping (EXPERIMENTAL)"
1884 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL 1885 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
1885 select X86_X2APIC
1886 ---help--- 1886 ---help---
1887 Supports Interrupt remapping for IO-APIC and MSI devices. 1887 Supports Interrupt remapping for IO-APIC and MSI devices.
1888 To use x2apic mode in the CPU's which support x2APIC enhancements or 1888 To use x2apic mode in the CPU's which support x2APIC enhancements or
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index df8a300dfe6c..42f2f8377422 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -107,6 +107,9 @@ extern u32 native_safe_apic_wait_icr_idle(void);
107extern void native_apic_icr_write(u32 low, u32 id); 107extern void native_apic_icr_write(u32 low, u32 id);
108extern u64 native_apic_icr_read(void); 108extern u64 native_apic_icr_read(void);
109 109
110#define EIM_8BIT_APIC_ID 0
111#define EIM_32BIT_APIC_ID 1
112
110#ifdef CONFIG_X86_X2APIC 113#ifdef CONFIG_X86_X2APIC
111/* 114/*
112 * Make previous memory operations globally visible before 115 * Make previous memory operations globally visible before
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 373cc2bbcad2..9d826e436010 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -162,10 +162,13 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
162extern void ioapic_init_mappings(void); 162extern void ioapic_init_mappings(void);
163 163
164#ifdef CONFIG_X86_64 164#ifdef CONFIG_X86_64
165extern int save_IO_APIC_setup(void); 165extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
166extern void mask_IO_APIC_setup(void); 166extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
167extern void restore_IO_APIC_setup(void); 167extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
168extern void reinit_intr_remapped_IO_APIC(int); 168extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
169extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
170extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
171 struct IO_APIC_route_entry **ioapic_entries);
169#endif 172#endif
170 173
171extern void probe_nr_irqs_gsi(void); 174extern void probe_nr_irqs_gsi(void);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b0e5e712a7af..fb504f843e58 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1308,6 +1308,7 @@ void __init enable_IR_x2apic(void)
1308#ifdef CONFIG_INTR_REMAP 1308#ifdef CONFIG_INTR_REMAP
1309 int ret; 1309 int ret;
1310 unsigned long flags; 1310 unsigned long flags;
1311 struct IO_APIC_route_entry **ioapic_entries = NULL;
1311 1312
1312 if (!cpu_has_x2apic) 1313 if (!cpu_has_x2apic)
1313 return; 1314 return;
@@ -1338,17 +1339,23 @@ void __init enable_IR_x2apic(void)
1338 return; 1339 return;
1339 } 1340 }
1340 1341
1341 ret = save_IO_APIC_setup(); 1342 ioapic_entries = alloc_ioapic_entries();
1343 if (!ioapic_entries) {
1344 pr_info("Allocate ioapic_entries failed: %d\n", ret);
1345 goto end;
1346 }
1347
1348 ret = save_IO_APIC_setup(ioapic_entries);
1342 if (ret) { 1349 if (ret) {
1343 pr_info("Saving IO-APIC state failed: %d\n", ret); 1350 pr_info("Saving IO-APIC state failed: %d\n", ret);
1344 goto end; 1351 goto end;
1345 } 1352 }
1346 1353
1347 local_irq_save(flags); 1354 local_irq_save(flags);
1348 mask_IO_APIC_setup(); 1355 mask_IO_APIC_setup(ioapic_entries);
1349 mask_8259A(); 1356 mask_8259A();
1350 1357
1351 ret = enable_intr_remapping(1); 1358 ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
1352 1359
1353 if (ret && x2apic_preenabled) { 1360 if (ret && x2apic_preenabled) {
1354 local_irq_restore(flags); 1361 local_irq_restore(flags);
@@ -1368,9 +1375,9 @@ end_restore:
1368 /* 1375 /*
1369 * IR enabling failed 1376 * IR enabling failed
1370 */ 1377 */
1371 restore_IO_APIC_setup(); 1378 restore_IO_APIC_setup(ioapic_entries);
1372 else 1379 else
1373 reinit_intr_remapped_IO_APIC(x2apic_preenabled); 1380 reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
1374 1381
1375 unmask_8259A(); 1382 unmask_8259A();
1376 local_irq_restore(flags); 1383 local_irq_restore(flags);
@@ -1383,6 +1390,8 @@ end:
1383 pr_info("Enabled Interrupt-remapping\n"); 1390 pr_info("Enabled Interrupt-remapping\n");
1384 } else 1391 } else
1385 pr_err("Failed to enable Interrupt-remapping and x2apic\n"); 1392 pr_err("Failed to enable Interrupt-remapping and x2apic\n");
1393 if (ioapic_entries)
1394 free_ioapic_entries(ioapic_entries);
1386#else 1395#else
1387 if (!cpu_has_x2apic) 1396 if (!cpu_has_x2apic)
1388 return; 1397 return;
@@ -1958,6 +1967,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
1958 1967
1959 local_irq_save(flags); 1968 local_irq_save(flags);
1960 disable_local_APIC(); 1969 disable_local_APIC();
1970#ifdef CONFIG_INTR_REMAP
1971 if (intr_remapping_enabled)
1972 disable_intr_remapping();
1973#endif
1961 local_irq_restore(flags); 1974 local_irq_restore(flags);
1962 return 0; 1975 return 0;
1963} 1976}
@@ -1968,15 +1981,41 @@ static int lapic_resume(struct sys_device *dev)
1968 unsigned long flags; 1981 unsigned long flags;
1969 int maxlvt; 1982 int maxlvt;
1970 1983
1984#ifdef CONFIG_INTR_REMAP
1985 int ret;
1986 struct IO_APIC_route_entry **ioapic_entries = NULL;
1987
1971 if (!apic_pm_state.active) 1988 if (!apic_pm_state.active)
1972 return 0; 1989 return 0;
1973 1990
1974 maxlvt = lapic_get_maxlvt();
1975
1976 local_irq_save(flags); 1991 local_irq_save(flags);
1992 if (x2apic) {
1993 ioapic_entries = alloc_ioapic_entries();
1994 if (!ioapic_entries) {
1995 WARN(1, "Alloc ioapic_entries in lapic resume failed.");
1996 return -ENOMEM;
1997 }
1998
1999 ret = save_IO_APIC_setup(ioapic_entries);
2000 if (ret) {
2001 WARN(1, "Saving IO-APIC state failed: %d\n", ret);
2002 free_ioapic_entries(ioapic_entries);
2003 return ret;
2004 }
2005
2006 mask_IO_APIC_setup(ioapic_entries);
2007 mask_8259A();
2008 enable_x2apic();
2009 }
2010#else
2011 if (!apic_pm_state.active)
2012 return 0;
1977 2013
2014 local_irq_save(flags);
1978 if (x2apic) 2015 if (x2apic)
1979 enable_x2apic(); 2016 enable_x2apic();
2017#endif
2018
1980 else { 2019 else {
1981 /* 2020 /*
1982 * Make sure the APICBASE points to the right address 2021 * Make sure the APICBASE points to the right address
@@ -1990,6 +2029,7 @@ static int lapic_resume(struct sys_device *dev)
1990 wrmsr(MSR_IA32_APICBASE, l, h); 2029 wrmsr(MSR_IA32_APICBASE, l, h);
1991 } 2030 }
1992 2031
2032 maxlvt = lapic_get_maxlvt();
1993 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); 2033 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
1994 apic_write(APIC_ID, apic_pm_state.apic_id); 2034 apic_write(APIC_ID, apic_pm_state.apic_id);
1995 apic_write(APIC_DFR, apic_pm_state.apic_dfr); 2035 apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -2013,8 +2053,20 @@ static int lapic_resume(struct sys_device *dev)
2013 apic_write(APIC_ESR, 0); 2053 apic_write(APIC_ESR, 0);
2014 apic_read(APIC_ESR); 2054 apic_read(APIC_ESR);
2015 2055
2056#ifdef CONFIG_INTR_REMAP
2057 if (intr_remapping_enabled)
2058 reenable_intr_remapping(EIM_32BIT_APIC_ID);
2059
2060 if (x2apic) {
2061 unmask_8259A();
2062 restore_IO_APIC_setup(ioapic_entries);
2063 free_ioapic_entries(ioapic_entries);
2064 }
2065#endif
2066
2016 local_irq_restore(flags); 2067 local_irq_restore(flags);
2017 2068
2069
2018 return 0; 2070 return 0;
2019} 2071}
2020 2072
@@ -2052,7 +2104,9 @@ static int __init init_lapic_sysfs(void)
2052 error = sysdev_register(&device_lapic); 2104 error = sysdev_register(&device_lapic);
2053 return error; 2105 return error;
2054} 2106}
2055device_initcall(init_lapic_sysfs); 2107
2108/* local apic needs to resume before other devices access its registers. */
2109core_initcall(init_lapic_sysfs);
2056 2110
2057#else /* CONFIG_PM */ 2111#else /* CONFIG_PM */
2058 2112
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1bb5c6cee3eb..767fe7e46d68 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -851,63 +851,74 @@ __setup("pirq=", ioapic_pirq_setup);
851#endif /* CONFIG_X86_32 */ 851#endif /* CONFIG_X86_32 */
852 852
853#ifdef CONFIG_INTR_REMAP 853#ifdef CONFIG_INTR_REMAP
854/* I/O APIC RTE contents at the OS boot up */ 854struct IO_APIC_route_entry **alloc_ioapic_entries(void)
855static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; 855{
856 int apic;
857 struct IO_APIC_route_entry **ioapic_entries;
858
859 ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
860 GFP_ATOMIC);
861 if (!ioapic_entries)
862 return 0;
863
864 for (apic = 0; apic < nr_ioapics; apic++) {
865 ioapic_entries[apic] =
866 kzalloc(sizeof(struct IO_APIC_route_entry) *
867 nr_ioapic_registers[apic], GFP_ATOMIC);
868 if (!ioapic_entries[apic])
869 goto nomem;
870 }
871
872 return ioapic_entries;
873
874nomem:
875 while (--apic >= 0)
876 kfree(ioapic_entries[apic]);
877 kfree(ioapic_entries);
878
879 return 0;
880}
856 881
857/* 882/*
858 * Saves all the IO-APIC RTE's 883 * Saves all the IO-APIC RTE's
859 */ 884 */
860int save_IO_APIC_setup(void) 885int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
861{ 886{
862 union IO_APIC_reg_01 reg_01;
863 unsigned long flags;
864 int apic, pin; 887 int apic, pin;
865 888
866 /* 889 if (!ioapic_entries)
867 * The number of IO-APIC IRQ registers (== #pins): 890 return -ENOMEM;
868 */
869 for (apic = 0; apic < nr_ioapics; apic++) {
870 spin_lock_irqsave(&ioapic_lock, flags);
871 reg_01.raw = io_apic_read(apic, 1);
872 spin_unlock_irqrestore(&ioapic_lock, flags);
873 nr_ioapic_registers[apic] = reg_01.bits.entries+1;
874 }
875 891
876 for (apic = 0; apic < nr_ioapics; apic++) { 892 for (apic = 0; apic < nr_ioapics; apic++) {
877 early_ioapic_entries[apic] = 893 if (!ioapic_entries[apic])
878 kzalloc(sizeof(struct IO_APIC_route_entry) * 894 return -ENOMEM;
879 nr_ioapic_registers[apic], GFP_KERNEL);
880 if (!early_ioapic_entries[apic])
881 goto nomem;
882 }
883 895
884 for (apic = 0; apic < nr_ioapics; apic++)
885 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 896 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
886 early_ioapic_entries[apic][pin] = 897 ioapic_entries[apic][pin] =
887 ioapic_read_entry(apic, pin); 898 ioapic_read_entry(apic, pin);
899 }
888 900
889 return 0; 901 return 0;
890
891nomem:
892 while (apic >= 0)
893 kfree(early_ioapic_entries[apic--]);
894 memset(early_ioapic_entries, 0,
895 ARRAY_SIZE(early_ioapic_entries));
896
897 return -ENOMEM;
898} 902}
899 903
900void mask_IO_APIC_setup(void) 904/*
905 * Mask all IO APIC entries.
906 */
907void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
901{ 908{
902 int apic, pin; 909 int apic, pin;
903 910
911 if (!ioapic_entries)
912 return;
913
904 for (apic = 0; apic < nr_ioapics; apic++) { 914 for (apic = 0; apic < nr_ioapics; apic++) {
905 if (!early_ioapic_entries[apic]) 915 if (!ioapic_entries[apic])
906 break; 916 break;
917
907 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 918 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
908 struct IO_APIC_route_entry entry; 919 struct IO_APIC_route_entry entry;
909 920
910 entry = early_ioapic_entries[apic][pin]; 921 entry = ioapic_entries[apic][pin];
911 if (!entry.mask) { 922 if (!entry.mask) {
912 entry.mask = 1; 923 entry.mask = 1;
913 ioapic_write_entry(apic, pin, entry); 924 ioapic_write_entry(apic, pin, entry);
@@ -916,22 +927,30 @@ void mask_IO_APIC_setup(void)
916 } 927 }
917} 928}
918 929
919void restore_IO_APIC_setup(void) 930/*
931 * Restore IO APIC entries which was saved in ioapic_entries.
932 */
933int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
920{ 934{
921 int apic, pin; 935 int apic, pin;
922 936
937 if (!ioapic_entries)
938 return -ENOMEM;
939
923 for (apic = 0; apic < nr_ioapics; apic++) { 940 for (apic = 0; apic < nr_ioapics; apic++) {
924 if (!early_ioapic_entries[apic]) 941 if (!ioapic_entries[apic])
925 break; 942 return -ENOMEM;
943
926 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 944 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
927 ioapic_write_entry(apic, pin, 945 ioapic_write_entry(apic, pin,
928 early_ioapic_entries[apic][pin]); 946 ioapic_entries[apic][pin]);
929 kfree(early_ioapic_entries[apic]);
930 early_ioapic_entries[apic] = NULL;
931 } 947 }
948 return 0;
932} 949}
933 950
934void reinit_intr_remapped_IO_APIC(int intr_remapping) 951void reinit_intr_remapped_IO_APIC(int intr_remapping,
952 struct IO_APIC_route_entry **ioapic_entries)
953
935{ 954{
936 /* 955 /*
937 * for now plain restore of previous settings. 956 * for now plain restore of previous settings.
@@ -940,7 +959,17 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping)
940 * table entries. for now, do a plain restore, and wait for 959 * table entries. for now, do a plain restore, and wait for
941 * the setup_IO_APIC_irqs() to do proper initialization. 960 * the setup_IO_APIC_irqs() to do proper initialization.
942 */ 961 */
943 restore_IO_APIC_setup(); 962 restore_IO_APIC_setup(ioapic_entries);
963}
964
965void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
966{
967 int apic;
968
969 for (apic = 0; apic < nr_ioapics; apic++)
970 kfree(ioapic_entries[apic]);
971
972 kfree(ioapic_entries);
944} 973}
945#endif 974#endif
946 975
@@ -2495,7 +2524,7 @@ static void irq_complete_move(struct irq_desc **descp)
2495static inline void irq_complete_move(struct irq_desc **descp) {} 2524static inline void irq_complete_move(struct irq_desc **descp) {}
2496#endif 2525#endif
2497 2526
2498#ifdef CONFIG_INTR_REMAP 2527#ifdef CONFIG_X86_X2APIC
2499static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) 2528static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
2500{ 2529{
2501 int apic, pin; 2530 int apic, pin;
@@ -2540,7 +2569,6 @@ static void ack_x2apic_edge(unsigned int irq)
2540{ 2569{
2541 ack_x2APIC_irq(); 2570 ack_x2APIC_irq();
2542} 2571}
2543
2544#endif 2572#endif
2545 2573
2546static void ack_apic_edge(unsigned int irq) 2574static void ack_apic_edge(unsigned int irq)
@@ -2651,6 +2679,26 @@ static void ack_apic_level(unsigned int irq)
2651#endif 2679#endif
2652} 2680}
2653 2681
2682#ifdef CONFIG_INTR_REMAP
2683static void ir_ack_apic_edge(unsigned int irq)
2684{
2685#ifdef CONFIG_X86_X2APIC
2686 if (x2apic_enabled())
2687 return ack_x2apic_edge(irq);
2688#endif
2689 return ack_apic_edge(irq);
2690}
2691
2692static void ir_ack_apic_level(unsigned int irq)
2693{
2694#ifdef CONFIG_X86_X2APIC
2695 if (x2apic_enabled())
2696 return ack_x2apic_level(irq);
2697#endif
2698 return ack_apic_level(irq);
2699}
2700#endif /* CONFIG_INTR_REMAP */
2701
2654static struct irq_chip ioapic_chip __read_mostly = { 2702static struct irq_chip ioapic_chip __read_mostly = {
2655 .name = "IO-APIC", 2703 .name = "IO-APIC",
2656 .startup = startup_ioapic_irq, 2704 .startup = startup_ioapic_irq,
@@ -2670,8 +2718,8 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
2670 .mask = mask_IO_APIC_irq, 2718 .mask = mask_IO_APIC_irq,
2671 .unmask = unmask_IO_APIC_irq, 2719 .unmask = unmask_IO_APIC_irq,
2672#ifdef CONFIG_INTR_REMAP 2720#ifdef CONFIG_INTR_REMAP
2673 .ack = ack_x2apic_edge, 2721 .ack = ir_ack_apic_edge,
2674 .eoi = ack_x2apic_level, 2722 .eoi = ir_ack_apic_level,
2675#ifdef CONFIG_SMP 2723#ifdef CONFIG_SMP
2676 .set_affinity = set_ir_ioapic_affinity_irq, 2724 .set_affinity = set_ir_ioapic_affinity_irq,
2677#endif 2725#endif
@@ -3397,7 +3445,7 @@ static struct irq_chip msi_ir_chip = {
3397 .unmask = unmask_msi_irq, 3445 .unmask = unmask_msi_irq,
3398 .mask = mask_msi_irq, 3446 .mask = mask_msi_irq,
3399#ifdef CONFIG_INTR_REMAP 3447#ifdef CONFIG_INTR_REMAP
3400 .ack = ack_x2apic_edge, 3448 .ack = ir_ack_apic_edge,
3401#ifdef CONFIG_SMP 3449#ifdef CONFIG_SMP
3402 .set_affinity = ir_set_msi_irq_affinity, 3450 .set_affinity = ir_set_msi_irq_affinity,
3403#endif 3451#endif