aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
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/kernel/apic
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/kernel/apic')
-rw-r--r--arch/x86/kernel/apic/apic.c70
-rw-r--r--arch/x86/kernel/apic/io_apic.c140
2 files changed, 156 insertions, 54 deletions
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