aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/mach-default
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2011-07-19 14:10:53 +0100
committerJan Beulich <jbeulich@novell.com>2011-07-19 14:10:53 +0100
commit876895c30294a8caead2386dcb7d17af88ed7cfd (patch)
tree4b6d42f576de3c67bdecb94276f718387badb0de /xen/include/asm-x86/mach-default
parente4c3755d4dd746511a87b9f7da7199fcd3ee0333 (diff)
downloadxen-876895c30294a8caead2386dcb7d17af88ed7cfd.tar.gz
xen-876895c30294a8caead2386dcb7d17af88ed7cfd.tar.bz2
xen-876895c30294a8caead2386dcb7d17af88ed7cfd.zip
x86: consistently serialize CMOS/RTC accesses on rtc_lock
Since RTC/CMOS accesses aren't atomic, there are possible races between code paths setting the index register and subsequently reading/writing the data register. This is supposed to be dealt with by acquiring rtc_lock, but two places up to now lacked respective synchronization: Accesses to the EFI time functions and smpboot_{setup,restore}_warm_reset_vector(). This in turn requires no longer directly passing through guest writes to the index register, but instead using a machanism similar to that for PCI config space method 1 accesses. Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/include/asm-x86/mach-default')
-rw-r--r--xen/include/asm-x86/mach-default/smpboot_hooks.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/xen/include/asm-x86/mach-default/smpboot_hooks.h b/xen/include/asm-x86/mach-default/smpboot_hooks.h
index a70d279912..14e1ee52a3 100644
--- a/xen/include/asm-x86/mach-default/smpboot_hooks.h
+++ b/xen/include/asm-x86/mach-default/smpboot_hooks.h
@@ -3,7 +3,11 @@
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);
flush_tlb_local();
Dprintk("1.\n");
*((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
@@ -14,6 +18,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.
*/
@@ -23,7 +29,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 int *) maddr_to_virt(0x467)) = 0;
}