aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@novell.com>2011-07-19 06:53:07 -0400
committerIngo Molnar <mingo@elte.hu>2011-07-21 03:21:00 -0400
commitef68c8f87ed13f65df867dddf36c0e185b27b942 (patch)
tree5caf15b1d46697bda2201fd1625d498e64df9f01 /arch/x86/platform
parentac619f4eba45da10053fc991f8a5d47b3be79fa3 (diff)
x86: Serialize EFI time accesses on rtc_lock
The EFI specification requires that callers of the time related runtime functions serialize with other CMOS accesses in the kernel, as the EFI time functions may choose to also use the legacy CMOS RTC. Besides fixing a latent bug, this is a prerequisite to safely enable the rtc-efi driver for x86, which ought to be preferred over rtc-cmos on all EFI platforms. Signed-off-by: Jan Beulich <jbeulich@novell.com> Acked-by: Matthew Garrett <mjg59@srcf.ucam.org> Cc: <mjg@redhat.com> Link: http://lkml.kernel.org/r/4E257E33020000780004E319@nat28.tlf.novell.com Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'arch/x86/platform')
-rw-r--r--arch/x86/platform/efi/efi.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 474356b98ede..b8823d5a0117 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -79,26 +79,50 @@ early_param("add_efi_memmap", setup_add_efi_memmap);
79 79
80static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) 80static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
81{ 81{
82 return efi_call_virt2(get_time, tm, tc); 82 unsigned long flags;
83 efi_status_t status;
84
85 spin_lock_irqsave(&rtc_lock, flags);
86 status = efi_call_virt2(get_time, tm, tc);
87 spin_unlock_irqrestore(&rtc_lock, flags);
88 return status;
83} 89}
84 90
85static efi_status_t virt_efi_set_time(efi_time_t *tm) 91static efi_status_t virt_efi_set_time(efi_time_t *tm)
86{ 92{
87 return efi_call_virt1(set_time, tm); 93 unsigned long flags;
94 efi_status_t status;
95
96 spin_lock_irqsave(&rtc_lock, flags);
97 status = efi_call_virt1(set_time, tm);
98 spin_unlock_irqrestore(&rtc_lock, flags);
99 return status;
88} 100}
89 101
90static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, 102static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
91 efi_bool_t *pending, 103 efi_bool_t *pending,
92 efi_time_t *tm) 104 efi_time_t *tm)
93{ 105{
94 return efi_call_virt3(get_wakeup_time, 106 unsigned long flags;
95 enabled, pending, tm); 107 efi_status_t status;
108
109 spin_lock_irqsave(&rtc_lock, flags);
110 status = efi_call_virt3(get_wakeup_time,
111 enabled, pending, tm);
112 spin_unlock_irqrestore(&rtc_lock, flags);
113 return status;
96} 114}
97 115
98static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) 116static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
99{ 117{
100 return efi_call_virt2(set_wakeup_time, 118 unsigned long flags;
101 enabled, tm); 119 efi_status_t status;
120
121 spin_lock_irqsave(&rtc_lock, flags);
122 status = efi_call_virt2(set_wakeup_time,
123 enabled, tm);
124 spin_unlock_irqrestore(&rtc_lock, flags);
125 return status;
102} 126}
103 127
104static efi_status_t virt_efi_get_variable(efi_char16_t *name, 128static efi_status_t virt_efi_get_variable(efi_char16_t *name,
@@ -164,11 +188,14 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
164static efi_status_t __init phys_efi_get_time(efi_time_t *tm, 188static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
165 efi_time_cap_t *tc) 189 efi_time_cap_t *tc)
166{ 190{
191 unsigned long flags;
167 efi_status_t status; 192 efi_status_t status;
168 193
194 spin_lock_irqsave(&rtc_lock, flags);
169 efi_call_phys_prelog(); 195 efi_call_phys_prelog();
170 status = efi_call_phys2(efi_phys.get_time, tm, tc); 196 status = efi_call_phys2(efi_phys.get_time, tm, tc);
171 efi_call_phys_epilog(); 197 efi_call_phys_epilog();
198 spin_unlock_irqrestore(&rtc_lock, flags);
172 return status; 199 return status;
173} 200}
174 201