diff options
| -rw-r--r-- | arch/x86/Kconfig.cpu | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/apic_32.c | 75 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 23 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/intel.c | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/p4.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/io_apic_32.c | 14 | ||||
| -rw-r--r-- | arch/x86/kernel/ipi.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/nmi.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/paravirt.c | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 49 | ||||
| -rw-r--r-- | arch/x86/kernel/vmi_32.c | 1 | ||||
| -rw-r--r-- | arch/x86/lguest/boot.c | 1 | ||||
| -rw-r--r-- | arch/x86/xen/enlighten.c | 1 | ||||
| -rw-r--r-- | include/asm-x86/apic.h | 24 | ||||
| -rw-r--r-- | include/asm-x86/cpufeature.h | 1 | ||||
| -rw-r--r-- | include/asm-x86/mach-bigsmp/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/mach-default/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/mach-es7000/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/mach-summit/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/paravirt.h | 6 |
20 files changed, 96 insertions, 144 deletions
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index abff1b84ed5b..54b8c02c71e6 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu | |||
| @@ -362,10 +362,6 @@ config X86_ALIGNMENT_16 | |||
| 362 | def_bool y | 362 | def_bool y |
| 363 | depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 | 363 | depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
| 364 | 364 | ||
| 365 | config X86_GOOD_APIC | ||
| 366 | def_bool y | ||
| 367 | depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64 | ||
| 368 | |||
| 369 | config X86_INTEL_USERCOPY | 365 | config X86_INTEL_USERCOPY |
| 370 | def_bool y | 366 | def_bool y |
| 371 | depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 | 367 | depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 |
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index a437d027f20b..2bc1186cc95a 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
| @@ -177,7 +177,7 @@ void __cpuinit enable_NMI_through_LVT0(void) | |||
| 177 | /* Level triggered for 82489DX */ | 177 | /* Level triggered for 82489DX */ |
| 178 | if (!lapic_is_integrated()) | 178 | if (!lapic_is_integrated()) |
| 179 | v |= APIC_LVT_LEVEL_TRIGGER; | 179 | v |= APIC_LVT_LEVEL_TRIGGER; |
| 180 | apic_write_around(APIC_LVT0, v); | 180 | apic_write(APIC_LVT0, v); |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /** | 183 | /** |
| @@ -212,9 +212,6 @@ int lapic_get_maxlvt(void) | |||
| 212 | * this function twice on the boot CPU, once with a bogus timeout | 212 | * this function twice on the boot CPU, once with a bogus timeout |
| 213 | * value, second time for real. The other (noncalibrating) CPUs | 213 | * value, second time for real. The other (noncalibrating) CPUs |
| 214 | * call this function only once, with the real, calibrated value. | 214 | * call this function only once, with the real, calibrated value. |
| 215 | * | ||
| 216 | * We do reads before writes even if unnecessary, to get around the | ||
| 217 | * P5 APIC double write bug. | ||
| 218 | */ | 215 | */ |
| 219 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | 216 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) |
| 220 | { | 217 | { |
| @@ -229,18 +226,18 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | |||
| 229 | if (!irqen) | 226 | if (!irqen) |
| 230 | lvtt_value |= APIC_LVT_MASKED; | 227 | lvtt_value |= APIC_LVT_MASKED; |
| 231 | 228 | ||
| 232 | apic_write_around(APIC_LVTT, lvtt_value); | 229 | apic_write(APIC_LVTT, lvtt_value); |
| 233 | 230 | ||
| 234 | /* | 231 | /* |
| 235 | * Divide PICLK by 16 | 232 | * Divide PICLK by 16 |
| 236 | */ | 233 | */ |
| 237 | tmp_value = apic_read(APIC_TDCR); | 234 | tmp_value = apic_read(APIC_TDCR); |
| 238 | apic_write_around(APIC_TDCR, (tmp_value | 235 | apic_write(APIC_TDCR, |
| 239 | & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | 236 | (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | |
| 240 | | APIC_TDR_DIV_16); | 237 | APIC_TDR_DIV_16); |
| 241 | 238 | ||
| 242 | if (!oneshot) | 239 | if (!oneshot) |
| 243 | apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); | 240 | apic_write(APIC_TMICT, clocks / APIC_DIVISOR); |
| 244 | } | 241 | } |
| 245 | 242 | ||
| 246 | /* | 243 | /* |
| @@ -249,7 +246,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | |||
| 249 | static int lapic_next_event(unsigned long delta, | 246 | static int lapic_next_event(unsigned long delta, |
| 250 | struct clock_event_device *evt) | 247 | struct clock_event_device *evt) |
| 251 | { | 248 | { |
| 252 | apic_write_around(APIC_TMICT, delta); | 249 | apic_write(APIC_TMICT, delta); |
| 253 | return 0; | 250 | return 0; |
| 254 | } | 251 | } |
| 255 | 252 | ||
| @@ -278,7 +275,7 @@ static void lapic_timer_setup(enum clock_event_mode mode, | |||
| 278 | case CLOCK_EVT_MODE_SHUTDOWN: | 275 | case CLOCK_EVT_MODE_SHUTDOWN: |
| 279 | v = apic_read(APIC_LVTT); | 276 | v = apic_read(APIC_LVTT); |
| 280 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | 277 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
| 281 | apic_write_around(APIC_LVTT, v); | 278 | apic_write(APIC_LVTT, v); |
| 282 | break; | 279 | break; |
| 283 | case CLOCK_EVT_MODE_RESUME: | 280 | case CLOCK_EVT_MODE_RESUME: |
| 284 | /* Nothing to do here */ | 281 | /* Nothing to do here */ |
| @@ -693,44 +690,44 @@ void clear_local_APIC(void) | |||
| 693 | */ | 690 | */ |
| 694 | if (maxlvt >= 3) { | 691 | if (maxlvt >= 3) { |
| 695 | v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ | 692 | v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ |
| 696 | apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED); | 693 | apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); |
| 697 | } | 694 | } |
| 698 | /* | 695 | /* |
| 699 | * Careful: we have to set masks only first to deassert | 696 | * Careful: we have to set masks only first to deassert |
| 700 | * any level-triggered sources. | 697 | * any level-triggered sources. |
| 701 | */ | 698 | */ |
| 702 | v = apic_read(APIC_LVTT); | 699 | v = apic_read(APIC_LVTT); |
| 703 | apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); | 700 | apic_write(APIC_LVTT, v | APIC_LVT_MASKED); |
| 704 | v = apic_read(APIC_LVT0); | 701 | v = apic_read(APIC_LVT0); |
| 705 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); | 702 | apic_write(APIC_LVT0, v | APIC_LVT_MASKED); |
| 706 | v = apic_read(APIC_LVT1); | 703 | v = apic_read(APIC_LVT1); |
| 707 | apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED); | 704 | apic_write(APIC_LVT1, v | APIC_LVT_MASKED); |
| 708 | if (maxlvt >= 4) { | 705 | if (maxlvt >= 4) { |
| 709 | v = apic_read(APIC_LVTPC); | 706 | v = apic_read(APIC_LVTPC); |
| 710 | apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED); | 707 | apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); |
| 711 | } | 708 | } |
| 712 | 709 | ||
| 713 | /* lets not touch this if we didn't frob it */ | 710 | /* lets not touch this if we didn't frob it */ |
| 714 | #ifdef CONFIG_X86_MCE_P4THERMAL | 711 | #ifdef CONFIG_X86_MCE_P4THERMAL |
| 715 | if (maxlvt >= 5) { | 712 | if (maxlvt >= 5) { |
| 716 | v = apic_read(APIC_LVTTHMR); | 713 | v = apic_read(APIC_LVTTHMR); |
| 717 | apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED); | 714 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); |
| 718 | } | 715 | } |
| 719 | #endif | 716 | #endif |
| 720 | /* | 717 | /* |
| 721 | * Clean APIC state for other OSs: | 718 | * Clean APIC state for other OSs: |
| 722 | */ | 719 | */ |
| 723 | apic_write_around(APIC_LVTT, APIC_LVT_MASKED); | 720 | apic_write(APIC_LVTT, APIC_LVT_MASKED); |
| 724 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED); | 721 | apic_write(APIC_LVT0, APIC_LVT_MASKED); |
| 725 | apic_write_around(APIC_LVT1, APIC_LVT_MASKED); | 722 | apic_write(APIC_LVT1, APIC_LVT_MASKED); |
| 726 | if (maxlvt >= 3) | 723 | if (maxlvt >= 3) |
| 727 | apic_write_around(APIC_LVTERR, APIC_LVT_MASKED); | 724 | apic_write(APIC_LVTERR, APIC_LVT_MASKED); |
| 728 | if (maxlvt >= 4) | 725 | if (maxlvt >= 4) |
| 729 | apic_write_around(APIC_LVTPC, APIC_LVT_MASKED); | 726 | apic_write(APIC_LVTPC, APIC_LVT_MASKED); |
| 730 | 727 | ||
| 731 | #ifdef CONFIG_X86_MCE_P4THERMAL | 728 | #ifdef CONFIG_X86_MCE_P4THERMAL |
| 732 | if (maxlvt >= 5) | 729 | if (maxlvt >= 5) |
| 733 | apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED); | 730 | apic_write(APIC_LVTTHMR, APIC_LVT_MASKED); |
| 734 | #endif | 731 | #endif |
| 735 | /* Integrated APIC (!82489DX) ? */ | 732 | /* Integrated APIC (!82489DX) ? */ |
| 736 | if (lapic_is_integrated()) { | 733 | if (lapic_is_integrated()) { |
| @@ -756,7 +753,7 @@ void disable_local_APIC(void) | |||
| 756 | */ | 753 | */ |
| 757 | value = apic_read(APIC_SPIV); | 754 | value = apic_read(APIC_SPIV); |
| 758 | value &= ~APIC_SPIV_APIC_ENABLED; | 755 | value &= ~APIC_SPIV_APIC_ENABLED; |
| 759 | apic_write_around(APIC_SPIV, value); | 756 | apic_write(APIC_SPIV, value); |
| 760 | 757 | ||
| 761 | /* | 758 | /* |
| 762 | * When LAPIC was disabled by the BIOS and enabled by the kernel, | 759 | * When LAPIC was disabled by the BIOS and enabled by the kernel, |
| @@ -865,8 +862,8 @@ void __init sync_Arb_IDs(void) | |||
| 865 | apic_wait_icr_idle(); | 862 | apic_wait_icr_idle(); |
| 866 | 863 | ||
| 867 | apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); | 864 | apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); |
| 868 | apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | 865 | apic_write(APIC_ICR, |
| 869 | | APIC_DM_INIT); | 866 | APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | APIC_DM_INIT); |
| 870 | } | 867 | } |
| 871 | 868 | ||
| 872 | /* | 869 | /* |
| @@ -902,16 +899,16 @@ void __init init_bsp_APIC(void) | |||
| 902 | else | 899 | else |
| 903 | value |= APIC_SPIV_FOCUS_DISABLED; | 900 | value |= APIC_SPIV_FOCUS_DISABLED; |
| 904 | value |= SPURIOUS_APIC_VECTOR; | 901 | value |= SPURIOUS_APIC_VECTOR; |
| 905 | apic_write_around(APIC_SPIV, value); | 902 | apic_write(APIC_SPIV, value); |
| 906 | 903 | ||
| 907 | /* | 904 | /* |
| 908 | * Set up the virtual wire mode. | 905 | * Set up the virtual wire mode. |
| 909 | */ | 906 | */ |
| 910 | apic_write_around(APIC_LVT0, APIC_DM_EXTINT); | 907 | apic_write(APIC_LVT0, APIC_DM_EXTINT); |
| 911 | value = APIC_DM_NMI; | 908 | value = APIC_DM_NMI; |
| 912 | if (!lapic_is_integrated()) /* 82489DX */ | 909 | if (!lapic_is_integrated()) /* 82489DX */ |
| 913 | value |= APIC_LVT_LEVEL_TRIGGER; | 910 | value |= APIC_LVT_LEVEL_TRIGGER; |
| 914 | apic_write_around(APIC_LVT1, value); | 911 | apic_write(APIC_LVT1, value); |
| 915 | } | 912 | } |
| 916 | 913 | ||
| 917 | static void __cpuinit lapic_setup_esr(void) | 914 | static void __cpuinit lapic_setup_esr(void) |
| @@ -926,7 +923,7 @@ static void __cpuinit lapic_setup_esr(void) | |||
| 926 | 923 | ||
| 927 | /* enables sending errors */ | 924 | /* enables sending errors */ |
| 928 | value = ERROR_APIC_VECTOR; | 925 | value = ERROR_APIC_VECTOR; |
| 929 | apic_write_around(APIC_LVTERR, value); | 926 | apic_write(APIC_LVTERR, value); |
| 930 | /* | 927 | /* |
| 931 | * spec says clear errors after enabling vector. | 928 | * spec says clear errors after enabling vector. |
| 932 | */ | 929 | */ |
| @@ -989,7 +986,7 @@ void __cpuinit setup_local_APIC(void) | |||
| 989 | */ | 986 | */ |
| 990 | value = apic_read(APIC_TASKPRI); | 987 | value = apic_read(APIC_TASKPRI); |
| 991 | value &= ~APIC_TPRI_MASK; | 988 | value &= ~APIC_TPRI_MASK; |
| 992 | apic_write_around(APIC_TASKPRI, value); | 989 | apic_write(APIC_TASKPRI, value); |
| 993 | 990 | ||
| 994 | /* | 991 | /* |
| 995 | * After a crash, we no longer service the interrupts and a pending | 992 | * After a crash, we no longer service the interrupts and a pending |
| @@ -1047,7 +1044,7 @@ void __cpuinit setup_local_APIC(void) | |||
| 1047 | * Set spurious IRQ vector | 1044 | * Set spurious IRQ vector |
| 1048 | */ | 1045 | */ |
| 1049 | value |= SPURIOUS_APIC_VECTOR; | 1046 | value |= SPURIOUS_APIC_VECTOR; |
| 1050 | apic_write_around(APIC_SPIV, value); | 1047 | apic_write(APIC_SPIV, value); |
| 1051 | 1048 | ||
| 1052 | /* | 1049 | /* |
| 1053 | * Set up LVT0, LVT1: | 1050 | * Set up LVT0, LVT1: |
| @@ -1069,7 +1066,7 @@ void __cpuinit setup_local_APIC(void) | |||
| 1069 | apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", | 1066 | apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", |
| 1070 | smp_processor_id()); | 1067 | smp_processor_id()); |
| 1071 | } | 1068 | } |
| 1072 | apic_write_around(APIC_LVT0, value); | 1069 | apic_write(APIC_LVT0, value); |
| 1073 | 1070 | ||
| 1074 | /* | 1071 | /* |
| 1075 | * only the BP should see the LINT1 NMI signal, obviously. | 1072 | * only the BP should see the LINT1 NMI signal, obviously. |
| @@ -1080,7 +1077,7 @@ void __cpuinit setup_local_APIC(void) | |||
| 1080 | value = APIC_DM_NMI | APIC_LVT_MASKED; | 1077 | value = APIC_DM_NMI | APIC_LVT_MASKED; |
| 1081 | if (!integrated) /* 82489DX */ | 1078 | if (!integrated) /* 82489DX */ |
| 1082 | value |= APIC_LVT_LEVEL_TRIGGER; | 1079 | value |= APIC_LVT_LEVEL_TRIGGER; |
| 1083 | apic_write_around(APIC_LVT1, value); | 1080 | apic_write(APIC_LVT1, value); |
| 1084 | } | 1081 | } |
| 1085 | 1082 | ||
| 1086 | void __cpuinit end_local_APIC_setup(void) | 1083 | void __cpuinit end_local_APIC_setup(void) |
| @@ -1091,7 +1088,7 @@ void __cpuinit end_local_APIC_setup(void) | |||
| 1091 | /* Disable the local apic timer */ | 1088 | /* Disable the local apic timer */ |
| 1092 | value = apic_read(APIC_LVTT); | 1089 | value = apic_read(APIC_LVTT); |
| 1093 | value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | 1090 | value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
| 1094 | apic_write_around(APIC_LVTT, value); | 1091 | apic_write(APIC_LVTT, value); |
| 1095 | 1092 | ||
| 1096 | setup_apic_nmi_watchdog(NULL); | 1093 | setup_apic_nmi_watchdog(NULL); |
| 1097 | apic_pm_activate(); | 1094 | apic_pm_activate(); |
| @@ -1419,7 +1416,7 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
| 1419 | value &= ~APIC_VECTOR_MASK; | 1416 | value &= ~APIC_VECTOR_MASK; |
| 1420 | value |= APIC_SPIV_APIC_ENABLED; | 1417 | value |= APIC_SPIV_APIC_ENABLED; |
| 1421 | value |= 0xf; | 1418 | value |= 0xf; |
| 1422 | apic_write_around(APIC_SPIV, value); | 1419 | apic_write(APIC_SPIV, value); |
| 1423 | 1420 | ||
| 1424 | if (!virt_wire_setup) { | 1421 | if (!virt_wire_setup) { |
| 1425 | /* | 1422 | /* |
| @@ -1432,10 +1429,10 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
| 1432 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); | 1429 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); |
| 1433 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | 1430 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; |
| 1434 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); | 1431 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); |
| 1435 | apic_write_around(APIC_LVT0, value); | 1432 | apic_write(APIC_LVT0, value); |
| 1436 | } else { | 1433 | } else { |
| 1437 | /* Disable LVT0 */ | 1434 | /* Disable LVT0 */ |
| 1438 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED); | 1435 | apic_write(APIC_LVT0, APIC_LVT_MASKED); |
| 1439 | } | 1436 | } |
| 1440 | 1437 | ||
| 1441 | /* | 1438 | /* |
| @@ -1449,7 +1446,7 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
| 1449 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); | 1446 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); |
| 1450 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | 1447 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; |
| 1451 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); | 1448 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); |
| 1452 | apic_write_around(APIC_LVT1, value); | 1449 | apic_write(APIC_LVT1, value); |
| 1453 | } | 1450 | } |
| 1454 | } | 1451 | } |
| 1455 | 1452 | ||
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 1b1c56bb338f..c9b58a806e85 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
| @@ -131,13 +131,7 @@ static void __init check_popad(void) | |||
| 131 | * (for due to lack of "invlpg" and working WP on a i386) | 131 | * (for due to lack of "invlpg" and working WP on a i386) |
| 132 | * - In order to run on anything without a TSC, we need to be | 132 | * - In order to run on anything without a TSC, we need to be |
| 133 | * compiled for a i486. | 133 | * compiled for a i486. |
| 134 | * - In order to support the local APIC on a buggy Pentium machine, | 134 | */ |
| 135 | * we need to be compiled with CONFIG_X86_GOOD_APIC disabled, | ||
| 136 | * which happens implicitly if compiled for a Pentium or lower | ||
| 137 | * (unless an advanced selection of CPU features is used) as an | ||
| 138 | * otherwise config implies a properly working local APIC without | ||
| 139 | * the need to do extra reads from the APIC. | ||
| 140 | */ | ||
| 141 | 135 | ||
| 142 | static void __init check_config(void) | 136 | static void __init check_config(void) |
| 143 | { | 137 | { |
| @@ -151,21 +145,6 @@ static void __init check_config(void) | |||
| 151 | if (boot_cpu_data.x86 == 3) | 145 | if (boot_cpu_data.x86 == 3) |
| 152 | panic("Kernel requires i486+ for 'invlpg' and other features"); | 146 | panic("Kernel requires i486+ for 'invlpg' and other features"); |
| 153 | #endif | 147 | #endif |
| 154 | |||
| 155 | /* | ||
| 156 | * If we were told we had a good local APIC, check for buggy Pentia, | ||
| 157 | * i.e. all B steppings and the C2 stepping of P54C when using their | ||
| 158 | * integrated APIC (see 11AP erratum in "Pentium Processor | ||
| 159 | * Specification Update"). | ||
| 160 | */ | ||
| 161 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC) | ||
| 162 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL | ||
| 163 | && cpu_has_apic | ||
| 164 | && boot_cpu_data.x86 == 5 | ||
| 165 | && boot_cpu_data.x86_model == 2 | ||
| 166 | && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) | ||
| 167 | panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); | ||
| 168 | #endif | ||
| 169 | } | 148 | } |
| 170 | 149 | ||
| 171 | 150 | ||
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 70609efdf1da..b75f2569b8f8 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
| @@ -227,6 +227,16 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
| 227 | if (cpu_has_bts) | 227 | if (cpu_has_bts) |
| 228 | ds_init_intel(c); | 228 | ds_init_intel(c); |
| 229 | 229 | ||
| 230 | /* | ||
| 231 | * See if we have a good local APIC by checking for buggy Pentia, | ||
| 232 | * i.e. all B steppings and the C2 stepping of P54C when using their | ||
| 233 | * integrated APIC (see 11AP erratum in "Pentium Processor | ||
| 234 | * Specification Update"). | ||
| 235 | */ | ||
| 236 | if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 && | ||
| 237 | (c->x86_mask < 0x6 || c->x86_mask == 0xb)) | ||
| 238 | set_cpu_cap(c, X86_FEATURE_11AP); | ||
| 239 | |||
| 230 | #ifdef CONFIG_X86_NUMAQ | 240 | #ifdef CONFIG_X86_NUMAQ |
| 231 | numaq_tsc_disable(); | 241 | numaq_tsc_disable(); |
| 232 | #endif | 242 | #endif |
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c index eef001ad3bde..9b60fce09f75 100644 --- a/arch/x86/kernel/cpu/mcheck/p4.c +++ b/arch/x86/kernel/cpu/mcheck/p4.c | |||
| @@ -102,7 +102,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) | |||
| 102 | /* The temperature transition interrupt handler setup */ | 102 | /* The temperature transition interrupt handler setup */ |
| 103 | h = THERMAL_APIC_VECTOR; /* our delivery vector */ | 103 | h = THERMAL_APIC_VECTOR; /* our delivery vector */ |
| 104 | h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */ | 104 | h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */ |
| 105 | apic_write_around(APIC_LVTTHMR, h); | 105 | apic_write(APIC_LVTTHMR, h); |
| 106 | 106 | ||
| 107 | rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); | 107 | rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); |
| 108 | wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h); | 108 | wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h); |
| @@ -114,7 +114,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) | |||
| 114 | wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h); | 114 | wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h); |
| 115 | 115 | ||
| 116 | l = apic_read(APIC_LVTTHMR); | 116 | l = apic_read(APIC_LVTTHMR); |
| 117 | apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); | 117 | apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); |
| 118 | printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); | 118 | printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); |
| 119 | 119 | ||
| 120 | /* enable thermal throttle processing */ | 120 | /* enable thermal throttle processing */ |
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c index 558abf4c796a..eabaf9244f5b 100644 --- a/arch/x86/kernel/io_apic_32.c +++ b/arch/x86/kernel/io_apic_32.c | |||
| @@ -756,7 +756,7 @@ void send_IPI_self(int vector) | |||
| 756 | /* | 756 | /* |
| 757 | * Send the IPI. The write to APIC_ICR fires this off. | 757 | * Send the IPI. The write to APIC_ICR fires this off. |
| 758 | */ | 758 | */ |
| 759 | apic_write_around(APIC_ICR, cfg); | 759 | apic_write(APIC_ICR, cfg); |
| 760 | } | 760 | } |
| 761 | #endif /* !CONFIG_SMP */ | 761 | #endif /* !CONFIG_SMP */ |
| 762 | 762 | ||
| @@ -2030,7 +2030,7 @@ static void mask_lapic_irq(unsigned int irq) | |||
| 2030 | unsigned long v; | 2030 | unsigned long v; |
| 2031 | 2031 | ||
| 2032 | v = apic_read(APIC_LVT0); | 2032 | v = apic_read(APIC_LVT0); |
| 2033 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); | 2033 | apic_write(APIC_LVT0, v | APIC_LVT_MASKED); |
| 2034 | } | 2034 | } |
| 2035 | 2035 | ||
| 2036 | static void unmask_lapic_irq(unsigned int irq) | 2036 | static void unmask_lapic_irq(unsigned int irq) |
| @@ -2038,7 +2038,7 @@ static void unmask_lapic_irq(unsigned int irq) | |||
| 2038 | unsigned long v; | 2038 | unsigned long v; |
| 2039 | 2039 | ||
| 2040 | v = apic_read(APIC_LVT0); | 2040 | v = apic_read(APIC_LVT0); |
| 2041 | apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); | 2041 | apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); |
| 2042 | } | 2042 | } |
| 2043 | 2043 | ||
| 2044 | static struct irq_chip lapic_chip __read_mostly = { | 2044 | static struct irq_chip lapic_chip __read_mostly = { |
| @@ -2168,7 +2168,7 @@ static inline void __init check_timer(void) | |||
| 2168 | * The AEOI mode will finish them in the 8259A | 2168 | * The AEOI mode will finish them in the 8259A |
| 2169 | * automatically. | 2169 | * automatically. |
| 2170 | */ | 2170 | */ |
| 2171 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); | 2171 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); |
| 2172 | init_8259A(1); | 2172 | init_8259A(1); |
| 2173 | timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); | 2173 | timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); |
| 2174 | 2174 | ||
| @@ -2256,7 +2256,7 @@ static inline void __init check_timer(void) | |||
| 2256 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 2256 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
| 2257 | 2257 | ||
| 2258 | lapic_register_intr(0, vector); | 2258 | lapic_register_intr(0, vector); |
| 2259 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 2259 | apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
| 2260 | enable_8259A_irq(0); | 2260 | enable_8259A_irq(0); |
| 2261 | 2261 | ||
| 2262 | if (timer_irq_works()) { | 2262 | if (timer_irq_works()) { |
| @@ -2264,14 +2264,14 @@ static inline void __init check_timer(void) | |||
| 2264 | goto out; | 2264 | goto out; |
| 2265 | } | 2265 | } |
| 2266 | disable_8259A_irq(0); | 2266 | disable_8259A_irq(0); |
| 2267 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); | 2267 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); |
| 2268 | printk(" failed.\n"); | 2268 | printk(" failed.\n"); |
| 2269 | 2269 | ||
| 2270 | printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); | 2270 | printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); |
| 2271 | 2271 | ||
| 2272 | init_8259A(0); | 2272 | init_8259A(0); |
| 2273 | make_8259A_irq(0); | 2273 | make_8259A_irq(0); |
| 2274 | apic_write_around(APIC_LVT0, APIC_DM_EXTINT); | 2274 | apic_write(APIC_LVT0, APIC_DM_EXTINT); |
| 2275 | 2275 | ||
| 2276 | unlock_ExtINT_logic(); | 2276 | unlock_ExtINT_logic(); |
| 2277 | 2277 | ||
diff --git a/arch/x86/kernel/ipi.c b/arch/x86/kernel/ipi.c index 9d98cda39ad9..3f7537b669d3 100644 --- a/arch/x86/kernel/ipi.c +++ b/arch/x86/kernel/ipi.c | |||
| @@ -70,7 +70,7 @@ void __send_IPI_shortcut(unsigned int shortcut, int vector) | |||
| 70 | /* | 70 | /* |
| 71 | * Send the IPI. The write to APIC_ICR fires this off. | 71 | * Send the IPI. The write to APIC_ICR fires this off. |
| 72 | */ | 72 | */ |
| 73 | apic_write_around(APIC_ICR, cfg); | 73 | apic_write(APIC_ICR, cfg); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | void send_IPI_self(int vector) | 76 | void send_IPI_self(int vector) |
| @@ -98,7 +98,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector) | |||
| 98 | * prepare target chip field | 98 | * prepare target chip field |
| 99 | */ | 99 | */ |
| 100 | cfg = __prepare_ICR2(mask); | 100 | cfg = __prepare_ICR2(mask); |
| 101 | apic_write_around(APIC_ICR2, cfg); | 101 | apic_write(APIC_ICR2, cfg); |
| 102 | 102 | ||
| 103 | /* | 103 | /* |
| 104 | * program the ICR | 104 | * program the ICR |
| @@ -108,7 +108,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector) | |||
| 108 | /* | 108 | /* |
| 109 | * Send the IPI. The write to APIC_ICR fires this off. | 109 | * Send the IPI. The write to APIC_ICR fires this off. |
| 110 | */ | 110 | */ |
| 111 | apic_write_around(APIC_ICR, cfg); | 111 | apic_write(APIC_ICR, cfg); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /* | 114 | /* |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index ec024b3baad0..384b49fed598 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
| @@ -263,7 +263,7 @@ late_initcall(init_lapic_nmi_sysfs); | |||
| 263 | 263 | ||
| 264 | static void __acpi_nmi_enable(void *__unused) | 264 | static void __acpi_nmi_enable(void *__unused) |
| 265 | { | 265 | { |
| 266 | apic_write_around(APIC_LVT0, APIC_DM_NMI); | 266 | apic_write(APIC_LVT0, APIC_DM_NMI); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | /* | 269 | /* |
| @@ -277,7 +277,7 @@ void acpi_nmi_enable(void) | |||
| 277 | 277 | ||
| 278 | static void __acpi_nmi_disable(void *__unused) | 278 | static void __acpi_nmi_disable(void *__unused) |
| 279 | { | 279 | { |
| 280 | apic_write_around(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); | 280 | apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | /* | 283 | /* |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index e0f571d58c19..5d7326a60b7c 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
| @@ -361,7 +361,6 @@ struct pv_cpu_ops pv_cpu_ops = { | |||
| 361 | struct pv_apic_ops pv_apic_ops = { | 361 | struct pv_apic_ops pv_apic_ops = { |
| 362 | #ifdef CONFIG_X86_LOCAL_APIC | 362 | #ifdef CONFIG_X86_LOCAL_APIC |
| 363 | .apic_write = native_apic_write, | 363 | .apic_write = native_apic_write, |
| 364 | .apic_write_atomic = native_apic_write_atomic, | ||
| 365 | .apic_read = native_apic_read, | 364 | .apic_read = native_apic_read, |
| 366 | .setup_boot_clock = setup_boot_APIC_clock, | 365 | .setup_boot_clock = setup_boot_APIC_clock, |
| 367 | .setup_secondary_clock = setup_secondary_APIC_clock, | 366 | .setup_secondary_clock = setup_secondary_APIC_clock, |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 687376ab07e8..f251f5c38823 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -546,8 +546,8 @@ static inline void __inquire_remote_apic(int apicid) | |||
| 546 | printk(KERN_CONT | 546 | printk(KERN_CONT |
| 547 | "a previous APIC delivery may have failed\n"); | 547 | "a previous APIC delivery may have failed\n"); |
| 548 | 548 | ||
| 549 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); | 549 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); |
| 550 | apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); | 550 | apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]); |
| 551 | 551 | ||
| 552 | timeout = 0; | 552 | timeout = 0; |
| 553 | do { | 553 | do { |
| @@ -579,11 +579,11 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | |||
| 579 | int maxlvt; | 579 | int maxlvt; |
| 580 | 580 | ||
| 581 | /* Target chip */ | 581 | /* Target chip */ |
| 582 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); | 582 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); |
| 583 | 583 | ||
| 584 | /* Boot on the stack */ | 584 | /* Boot on the stack */ |
| 585 | /* Kick the second */ | 585 | /* Kick the second */ |
| 586 | apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); | 586 | apic_write(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); |
| 587 | 587 | ||
| 588 | Dprintk("Waiting for send to finish...\n"); | 588 | Dprintk("Waiting for send to finish...\n"); |
| 589 | send_status = safe_apic_wait_icr_idle(); | 589 | send_status = safe_apic_wait_icr_idle(); |
| @@ -592,14 +592,9 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | |||
| 592 | * Give the other CPU some time to accept the IPI. | 592 | * Give the other CPU some time to accept the IPI. |
| 593 | */ | 593 | */ |
| 594 | udelay(200); | 594 | udelay(200); |
| 595 | /* | ||
| 596 | * Due to the Pentium erratum 3AP. | ||
| 597 | */ | ||
| 598 | maxlvt = lapic_get_maxlvt(); | 595 | maxlvt = lapic_get_maxlvt(); |
| 599 | if (maxlvt > 3) { | 596 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
| 600 | apic_read_around(APIC_SPIV); | ||
| 601 | apic_write(APIC_ESR, 0); | 597 | apic_write(APIC_ESR, 0); |
| 602 | } | ||
| 603 | accept_status = (apic_read(APIC_ESR) & 0xEF); | 598 | accept_status = (apic_read(APIC_ESR) & 0xEF); |
| 604 | Dprintk("NMI sent.\n"); | 599 | Dprintk("NMI sent.\n"); |
| 605 | 600 | ||
| @@ -625,12 +620,14 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
| 625 | return send_status; | 620 | return send_status; |
| 626 | } | 621 | } |
| 627 | 622 | ||
| 623 | maxlvt = lapic_get_maxlvt(); | ||
| 624 | |||
| 628 | /* | 625 | /* |
| 629 | * Be paranoid about clearing APIC errors. | 626 | * Be paranoid about clearing APIC errors. |
| 630 | */ | 627 | */ |
| 631 | if (APIC_INTEGRATED(apic_version[phys_apicid])) { | 628 | if (APIC_INTEGRATED(apic_version[phys_apicid])) { |
| 632 | apic_read_around(APIC_SPIV); | 629 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
| 633 | apic_write(APIC_ESR, 0); | 630 | apic_write(APIC_ESR, 0); |
| 634 | apic_read(APIC_ESR); | 631 | apic_read(APIC_ESR); |
| 635 | } | 632 | } |
| 636 | 633 | ||
| @@ -639,13 +636,13 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
| 639 | /* | 636 | /* |
| 640 | * Turn INIT on target chip | 637 | * Turn INIT on target chip |
| 641 | */ | 638 | */ |
| 642 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); | 639 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); |
| 643 | 640 | ||
| 644 | /* | 641 | /* |
| 645 | * Send IPI | 642 | * Send IPI |
| 646 | */ | 643 | */ |
| 647 | apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT | 644 | apic_write(APIC_ICR, |
| 648 | | APIC_DM_INIT); | 645 | APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT); |
| 649 | 646 | ||
| 650 | Dprintk("Waiting for send to finish...\n"); | 647 | Dprintk("Waiting for send to finish...\n"); |
| 651 | send_status = safe_apic_wait_icr_idle(); | 648 | send_status = safe_apic_wait_icr_idle(); |
| @@ -655,10 +652,10 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
| 655 | Dprintk("Deasserting INIT.\n"); | 652 | Dprintk("Deasserting INIT.\n"); |
| 656 | 653 | ||
| 657 | /* Target chip */ | 654 | /* Target chip */ |
| 658 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); | 655 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); |
| 659 | 656 | ||
| 660 | /* Send IPI */ | 657 | /* Send IPI */ |
| 661 | apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); | 658 | apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); |
| 662 | 659 | ||
| 663 | Dprintk("Waiting for send to finish...\n"); | 660 | Dprintk("Waiting for send to finish...\n"); |
| 664 | send_status = safe_apic_wait_icr_idle(); | 661 | send_status = safe_apic_wait_icr_idle(); |
| @@ -689,12 +686,10 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
| 689 | */ | 686 | */ |
| 690 | Dprintk("#startup loops: %d.\n", num_starts); | 687 | Dprintk("#startup loops: %d.\n", num_starts); |
| 691 | 688 | ||
| 692 | maxlvt = lapic_get_maxlvt(); | ||
| 693 | |||
| 694 | for (j = 1; j <= num_starts; j++) { | 689 | for (j = 1; j <= num_starts; j++) { |
| 695 | Dprintk("Sending STARTUP #%d.\n", j); | 690 | Dprintk("Sending STARTUP #%d.\n", j); |
| 696 | apic_read_around(APIC_SPIV); | 691 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
| 697 | apic_write(APIC_ESR, 0); | 692 | apic_write(APIC_ESR, 0); |
| 698 | apic_read(APIC_ESR); | 693 | apic_read(APIC_ESR); |
| 699 | Dprintk("After apic_write.\n"); | 694 | Dprintk("After apic_write.\n"); |
| 700 | 695 | ||
| @@ -703,12 +698,11 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
| 703 | */ | 698 | */ |
| 704 | 699 | ||
| 705 | /* Target chip */ | 700 | /* Target chip */ |
| 706 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); | 701 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); |
| 707 | 702 | ||
| 708 | /* Boot on the stack */ | 703 | /* Boot on the stack */ |
| 709 | /* Kick the second */ | 704 | /* Kick the second */ |
| 710 | apic_write_around(APIC_ICR, APIC_DM_STARTUP | 705 | apic_write(APIC_ICR, APIC_DM_STARTUP | (start_eip >> 12)); |
| 711 | | (start_eip >> 12)); | ||
| 712 | 706 | ||
| 713 | /* | 707 | /* |
| 714 | * Give the other CPU some time to accept the IPI. | 708 | * Give the other CPU some time to accept the IPI. |
| @@ -724,13 +718,8 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
| 724 | * Give the other CPU some time to accept the IPI. | 718 | * Give the other CPU some time to accept the IPI. |
| 725 | */ | 719 | */ |
| 726 | udelay(200); | 720 | udelay(200); |
| 727 | /* | 721 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
| 728 | * Due to the Pentium erratum 3AP. | ||
| 729 | */ | ||
| 730 | if (maxlvt > 3) { | ||
| 731 | apic_read_around(APIC_SPIV); | ||
| 732 | apic_write(APIC_ESR, 0); | 722 | apic_write(APIC_ESR, 0); |
| 733 | } | ||
| 734 | accept_status = (apic_read(APIC_ESR) & 0xEF); | 723 | accept_status = (apic_read(APIC_ESR) & 0xEF); |
| 735 | if (send_status || accept_status) | 724 | if (send_status || accept_status) |
| 736 | break; | 725 | break; |
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index b15346092b7b..0a1b1a9d922d 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c | |||
| @@ -906,7 +906,6 @@ static inline int __init activate_vmi(void) | |||
| 906 | #ifdef CONFIG_X86_LOCAL_APIC | 906 | #ifdef CONFIG_X86_LOCAL_APIC |
| 907 | para_fill(pv_apic_ops.apic_read, APICRead); | 907 | para_fill(pv_apic_ops.apic_read, APICRead); |
| 908 | para_fill(pv_apic_ops.apic_write, APICWrite); | 908 | para_fill(pv_apic_ops.apic_write, APICWrite); |
| 909 | para_fill(pv_apic_ops.apic_write_atomic, APICWrite); | ||
| 910 | #endif | 909 | #endif |
| 911 | 910 | ||
| 912 | /* | 911 | /* |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 50dad44fb542..0313a5eec412 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
| @@ -991,7 +991,6 @@ __init void lguest_init(void) | |||
| 991 | #ifdef CONFIG_X86_LOCAL_APIC | 991 | #ifdef CONFIG_X86_LOCAL_APIC |
| 992 | /* apic read/write intercepts */ | 992 | /* apic read/write intercepts */ |
| 993 | pv_apic_ops.apic_write = lguest_apic_write; | 993 | pv_apic_ops.apic_write = lguest_apic_write; |
| 994 | pv_apic_ops.apic_write_atomic = lguest_apic_write; | ||
| 995 | pv_apic_ops.apic_read = lguest_apic_read; | 994 | pv_apic_ops.apic_read = lguest_apic_read; |
| 996 | #endif | 995 | #endif |
| 997 | 996 | ||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bb508456ef52..7f26c3718777 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -1131,7 +1131,6 @@ static const struct pv_irq_ops xen_irq_ops __initdata = { | |||
| 1131 | static const struct pv_apic_ops xen_apic_ops __initdata = { | 1131 | static const struct pv_apic_ops xen_apic_ops __initdata = { |
| 1132 | #ifdef CONFIG_X86_LOCAL_APIC | 1132 | #ifdef CONFIG_X86_LOCAL_APIC |
| 1133 | .apic_write = xen_apic_write, | 1133 | .apic_write = xen_apic_write, |
| 1134 | .apic_write_atomic = xen_apic_write, | ||
| 1135 | .apic_read = xen_apic_read, | 1134 | .apic_read = xen_apic_read, |
| 1136 | .setup_boot_clock = paravirt_nop, | 1135 | .setup_boot_clock = paravirt_nop, |
| 1137 | .setup_secondary_clock = paravirt_nop, | 1136 | .setup_secondary_clock = paravirt_nop, |
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h index 4e2c1e517f06..ea866baccefc 100644 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/pm.h> | 4 | #include <linux/pm.h> |
| 5 | #include <linux/delay.h> | 5 | #include <linux/delay.h> |
| 6 | |||
| 7 | #include <asm/alternative.h> | ||
| 6 | #include <asm/fixmap.h> | 8 | #include <asm/fixmap.h> |
| 7 | #include <asm/apicdef.h> | 9 | #include <asm/apicdef.h> |
| 8 | #include <asm/processor.h> | 10 | #include <asm/processor.h> |
| @@ -48,7 +50,6 @@ extern int disable_apic; | |||
| 48 | #include <asm/paravirt.h> | 50 | #include <asm/paravirt.h> |
| 49 | #else | 51 | #else |
| 50 | #define apic_write native_apic_write | 52 | #define apic_write native_apic_write |
| 51 | #define apic_write_atomic native_apic_write_atomic | ||
| 52 | #define apic_read native_apic_read | 53 | #define apic_read native_apic_read |
| 53 | #define setup_boot_clock setup_boot_APIC_clock | 54 | #define setup_boot_clock setup_boot_APIC_clock |
| 54 | #define setup_secondary_clock setup_secondary_APIC_clock | 55 | #define setup_secondary_clock setup_secondary_APIC_clock |
| @@ -58,12 +59,11 @@ extern int is_vsmp_box(void); | |||
| 58 | 59 | ||
| 59 | static inline void native_apic_write(unsigned long reg, u32 v) | 60 | static inline void native_apic_write(unsigned long reg, u32 v) |
| 60 | { | 61 | { |
| 61 | *((volatile u32 *)(APIC_BASE + reg)) = v; | 62 | volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg); |
| 62 | } | ||
| 63 | 63 | ||
| 64 | static inline void native_apic_write_atomic(unsigned long reg, u32 v) | 64 | alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP, |
| 65 | { | 65 | ASM_OUTPUT2("=r" (v), "=m" (*addr)), |
| 66 | (void)xchg((u32 *)(APIC_BASE + reg), v); | 66 | ASM_OUTPUT2("0" (v), "m" (*addr))); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static inline u32 native_apic_read(unsigned long reg) | 69 | static inline u32 native_apic_read(unsigned long reg) |
| @@ -75,16 +75,6 @@ extern void apic_wait_icr_idle(void); | |||
| 75 | extern u32 safe_apic_wait_icr_idle(void); | 75 | extern u32 safe_apic_wait_icr_idle(void); |
| 76 | extern int get_physical_broadcast(void); | 76 | extern int get_physical_broadcast(void); |
| 77 | 77 | ||
| 78 | #ifdef CONFIG_X86_GOOD_APIC | ||
| 79 | # define FORCE_READ_AROUND_WRITE 0 | ||
| 80 | # define apic_read_around(x) | ||
| 81 | # define apic_write_around(x, y) apic_write((x), (y)) | ||
| 82 | #else | ||
| 83 | # define FORCE_READ_AROUND_WRITE 1 | ||
| 84 | # define apic_read_around(x) apic_read(x) | ||
| 85 | # define apic_write_around(x, y) apic_write_atomic((x), (y)) | ||
| 86 | #endif | ||
| 87 | |||
| 88 | static inline void ack_APIC_irq(void) | 78 | static inline void ack_APIC_irq(void) |
| 89 | { | 79 | { |
| 90 | /* | 80 | /* |
| @@ -95,7 +85,7 @@ static inline void ack_APIC_irq(void) | |||
| 95 | */ | 85 | */ |
| 96 | 86 | ||
| 97 | /* Docs say use 0 for future compatibility */ | 87 | /* Docs say use 0 for future compatibility */ |
| 98 | apic_write_around(APIC_EOI, 0); | 88 | apic_write(APIC_EOI, 0); |
| 99 | } | 89 | } |
| 100 | 90 | ||
| 101 | extern int lapic_get_maxlvt(void); | 91 | extern int lapic_get_maxlvt(void); |
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h index 75ef959db329..2f5a792b0acc 100644 --- a/include/asm-x86/cpufeature.h +++ b/include/asm-x86/cpufeature.h | |||
| @@ -79,6 +79,7 @@ | |||
| 79 | #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ | 79 | #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ |
| 80 | #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ | 80 | #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ |
| 81 | #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ | 81 | #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ |
| 82 | #define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */ | ||
| 82 | 83 | ||
| 83 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | 84 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ |
| 84 | #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ | 85 | #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ |
diff --git a/include/asm-x86/mach-bigsmp/mach_apic.h b/include/asm-x86/mach-bigsmp/mach_apic.h index 017c8c19ad8f..c3b9dc6970c9 100644 --- a/include/asm-x86/mach-bigsmp/mach_apic.h +++ b/include/asm-x86/mach-bigsmp/mach_apic.h | |||
| @@ -63,9 +63,9 @@ static inline void init_apic_ldr(void) | |||
| 63 | unsigned long val; | 63 | unsigned long val; |
| 64 | int cpu = smp_processor_id(); | 64 | int cpu = smp_processor_id(); |
| 65 | 65 | ||
| 66 | apic_write_around(APIC_DFR, APIC_DFR_VALUE); | 66 | apic_write(APIC_DFR, APIC_DFR_VALUE); |
| 67 | val = calculate_ldr(cpu); | 67 | val = calculate_ldr(cpu); |
| 68 | apic_write_around(APIC_LDR, val); | 68 | apic_write(APIC_LDR, val); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static inline void setup_apic_routing(void) | 71 | static inline void setup_apic_routing(void) |
diff --git a/include/asm-x86/mach-default/mach_apic.h b/include/asm-x86/mach-default/mach_apic.h index 0b2cde5e1b74..f3226b9a6b82 100644 --- a/include/asm-x86/mach-default/mach_apic.h +++ b/include/asm-x86/mach-default/mach_apic.h | |||
| @@ -46,10 +46,10 @@ static inline void init_apic_ldr(void) | |||
| 46 | { | 46 | { |
| 47 | unsigned long val; | 47 | unsigned long val; |
| 48 | 48 | ||
| 49 | apic_write_around(APIC_DFR, APIC_DFR_VALUE); | 49 | apic_write(APIC_DFR, APIC_DFR_VALUE); |
| 50 | val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; | 50 | val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; |
| 51 | val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); | 51 | val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); |
| 52 | apic_write_around(APIC_LDR, val); | 52 | apic_write(APIC_LDR, val); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static inline int apic_id_registered(void) | 55 | static inline int apic_id_registered(void) |
diff --git a/include/asm-x86/mach-es7000/mach_apic.h b/include/asm-x86/mach-es7000/mach_apic.h index fbc8ad256f5a..0a3fdf930672 100644 --- a/include/asm-x86/mach-es7000/mach_apic.h +++ b/include/asm-x86/mach-es7000/mach_apic.h | |||
| @@ -66,9 +66,9 @@ static inline void init_apic_ldr(void) | |||
| 66 | unsigned long val; | 66 | unsigned long val; |
| 67 | int cpu = smp_processor_id(); | 67 | int cpu = smp_processor_id(); |
| 68 | 68 | ||
| 69 | apic_write_around(APIC_DFR, APIC_DFR_VALUE); | 69 | apic_write(APIC_DFR, APIC_DFR_VALUE); |
| 70 | val = calculate_ldr(cpu); | 70 | val = calculate_ldr(cpu); |
| 71 | apic_write_around(APIC_LDR, val); | 71 | apic_write(APIC_LDR, val); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | #ifndef CONFIG_X86_GENERICARCH | 74 | #ifndef CONFIG_X86_GENERICARCH |
diff --git a/include/asm-x86/mach-summit/mach_apic.h b/include/asm-x86/mach-summit/mach_apic.h index 1f76c2e70232..75d2c95005d7 100644 --- a/include/asm-x86/mach-summit/mach_apic.h +++ b/include/asm-x86/mach-summit/mach_apic.h | |||
| @@ -63,10 +63,10 @@ static inline void init_apic_ldr(void) | |||
| 63 | * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ | 63 | * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ |
| 64 | BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); | 64 | BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); |
| 65 | id = my_cluster | (1UL << count); | 65 | id = my_cluster | (1UL << count); |
| 66 | apic_write_around(APIC_DFR, APIC_DFR_VALUE); | 66 | apic_write(APIC_DFR, APIC_DFR_VALUE); |
| 67 | val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; | 67 | val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; |
| 68 | val |= SET_APIC_LOGICAL_ID(id); | 68 | val |= SET_APIC_LOGICAL_ID(id); |
| 69 | apic_write_around(APIC_LDR, val); | 69 | apic_write(APIC_LDR, val); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static inline int multi_timer_check(int apic, int irq) | 72 | static inline int multi_timer_check(int apic, int irq) |
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index ef5e8ec6a6ab..719d959d0bc4 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h | |||
| @@ -205,7 +205,6 @@ struct pv_apic_ops { | |||
| 205 | * these shouldn't be in this interface. | 205 | * these shouldn't be in this interface. |
| 206 | */ | 206 | */ |
| 207 | void (*apic_write)(unsigned long reg, u32 v); | 207 | void (*apic_write)(unsigned long reg, u32 v); |
| 208 | void (*apic_write_atomic)(unsigned long reg, u32 v); | ||
| 209 | u32 (*apic_read)(unsigned long reg); | 208 | u32 (*apic_read)(unsigned long reg); |
| 210 | void (*setup_boot_clock)(void); | 209 | void (*setup_boot_clock)(void); |
| 211 | void (*setup_secondary_clock)(void); | 210 | void (*setup_secondary_clock)(void); |
| @@ -896,11 +895,6 @@ static inline void apic_write(unsigned long reg, u32 v) | |||
| 896 | PVOP_VCALL2(pv_apic_ops.apic_write, reg, v); | 895 | PVOP_VCALL2(pv_apic_ops.apic_write, reg, v); |
| 897 | } | 896 | } |
| 898 | 897 | ||
| 899 | static inline void apic_write_atomic(unsigned long reg, u32 v) | ||
| 900 | { | ||
| 901 | PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v); | ||
| 902 | } | ||
| 903 | |||
| 904 | static inline u32 apic_read(unsigned long reg) | 898 | static inline u32 apic_read(unsigned long reg) |
| 905 | { | 899 | { |
| 906 | return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg); | 900 | return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg); |
