diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/alternative.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic_64.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot_64.c | 7 |
3 files changed, 29 insertions, 5 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index bd72d94e713e..11b03d3c6fda 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
11 | #include <asm/mce.h> | 11 | #include <asm/mce.h> |
12 | #include <asm/nmi.h> | 12 | #include <asm/nmi.h> |
13 | #include <asm/vsyscall.h> | ||
13 | 14 | ||
14 | #define MAX_PATCH_LEN (255-1) | 15 | #define MAX_PATCH_LEN (255-1) |
15 | 16 | ||
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 395928de28ea..09b82093bc75 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -964,8 +964,34 @@ void __init setup_boot_APIC_clock (void) | |||
964 | setup_APIC_timer(); | 964 | setup_APIC_timer(); |
965 | } | 965 | } |
966 | 966 | ||
967 | /* | ||
968 | * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the | ||
969 | * C1E flag only in the secondary CPU, so when we detect the wreckage | ||
970 | * we already have enabled the boot CPU local apic timer. Check, if | ||
971 | * disable_apic_timer is set and the DUMMY flag is cleared. If yes, | ||
972 | * set the DUMMY flag again and force the broadcast mode in the | ||
973 | * clockevents layer. | ||
974 | */ | ||
975 | void __cpuinit check_boot_apic_timer_broadcast(void) | ||
976 | { | ||
977 | struct clock_event_device *levt = &per_cpu(lapic_events, boot_cpu_id); | ||
978 | |||
979 | if (!disable_apic_timer || | ||
980 | (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY)) | ||
981 | return; | ||
982 | |||
983 | printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n"); | ||
984 | lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY; | ||
985 | levt->features |= CLOCK_EVT_FEAT_DUMMY; | ||
986 | |||
987 | local_irq_enable(); | ||
988 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &boot_cpu_id); | ||
989 | local_irq_disable(); | ||
990 | } | ||
991 | |||
967 | void __cpuinit setup_secondary_APIC_clock(void) | 992 | void __cpuinit setup_secondary_APIC_clock(void) |
968 | { | 993 | { |
994 | check_boot_apic_timer_broadcast(); | ||
969 | setup_APIC_timer(); | 995 | setup_APIC_timer(); |
970 | } | 996 | } |
971 | 997 | ||
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 57ccf7cb6b91..720a7d1f8862 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c | |||
@@ -335,11 +335,6 @@ void __cpuinit start_secondary(void) | |||
335 | */ | 335 | */ |
336 | check_tsc_sync_target(); | 336 | check_tsc_sync_target(); |
337 | 337 | ||
338 | Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); | ||
339 | setup_secondary_APIC_clock(); | ||
340 | |||
341 | Dprintk("cpu %d: enabling apic timer\n", smp_processor_id()); | ||
342 | |||
343 | if (nmi_watchdog == NMI_IO_APIC) { | 338 | if (nmi_watchdog == NMI_IO_APIC) { |
344 | disable_8259A_irq(0); | 339 | disable_8259A_irq(0); |
345 | enable_NMI_through_LVT0(NULL); | 340 | enable_NMI_through_LVT0(NULL); |
@@ -374,6 +369,8 @@ void __cpuinit start_secondary(void) | |||
374 | 369 | ||
375 | unlock_ipi_call_lock(); | 370 | unlock_ipi_call_lock(); |
376 | 371 | ||
372 | setup_secondary_APIC_clock(); | ||
373 | |||
377 | cpu_idle(); | 374 | cpu_idle(); |
378 | } | 375 | } |
379 | 376 | ||