x86: Serialize SMP bootup CMOS accesses on rtc_lock
authorJan Beulich <JBeulich@novell.com>
Tue, 19 Jul 2011 10:39:03 +0000 (11:39 +0100)
committerIngo Molnar <mingo@elte.hu>
Thu, 21 Jul 2011 07:20:59 +0000 (09:20 +0200)
With CPU hotplug, there is a theoretical race between other CMOS
(namely RTC) accesses and those done in the SMP secondary
processor bringup path.

I am unware of the problem having been noticed by anyone in practice,
but it would very likely be rather spurious and very hard to reproduce.
So to be on the safe side, acquire rtc_lock around those accesses.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: John Stultz <john.stultz@linaro.org>
Link: http://lkml.kernel.org/r/4E257AE7020000780004E2FF@nat28.tlf.novell.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/include/asm/smpboot_hooks.h

index 725b7783199328c936bb10350d55b797b661315e..49adfd7bb4a49e33c05da6e82a1378d23c29580c 100644 (file)
@@ -10,7 +10,11 @@ static inline void smpboot_clear_io_apic_irqs(void)
 
 static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&rtc_lock, flags);
        CMOS_WRITE(0xa, 0xf);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        local_flush_tlb();
        pr_debug("1.\n");
        *((volatile unsigned short *)phys_to_virt(apic->trampoline_phys_high)) =
@@ -23,6 +27,8 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
 
 static inline void smpboot_restore_warm_reset_vector(void)
 {
+       unsigned long flags;
+
        /*
         * Install writable page 0 entry to set BIOS data area.
         */
@@ -32,7 +38,9 @@ static inline void smpboot_restore_warm_reset_vector(void)
         * Paranoid:  Set warm reset code and vector here back
         * to default values.
         */
+       spin_lock_irqsave(&rtc_lock, flags);
        CMOS_WRITE(0, 0xf);
+       spin_unlock_irqrestore(&rtc_lock, flags);
 
        *((volatile u32 *)phys_to_virt(apic->trampoline_phys_low)) = 0;
 }
This page took 0.0276 seconds and 5 git commands to generate.