diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2009-02-12 13:02:56 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-02-12 17:11:58 -0500 |
commit | d85cf93da66977dbc645352be1b2084a659d8a0b (patch) | |
tree | c8783022810c0ae48f5a5007ce9163c99e804d6f /arch/x86 | |
parent | be03d9e8022030c16abf534e33e185bfc3d40eef (diff) |
x86/paravirt: make arch_flush_lazy_mmu/cpu disable preemption
Impact: avoid access to percpu vars in preempible context
They are intended to be used whenever there's the possibility
that there's some stale state which is going to be overwritten
with a queued update, or to force a state change when we may be
in lazy mode. Either way, we could end up calling it with
preemption enabled, so wrap the functions in their own little
preempt-disable section so they can be safely called in any
context (though preemption should never be enabled if we're actually
in a lazy state).
(Move out of line to avoid #include dependencies.)
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/paravirt.h | 17 | ||||
-rw-r--r-- | arch/x86/kernel/paravirt.c | 24 |
2 files changed, 26 insertions, 15 deletions
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index ba3e2ff6aedc..a660eceaa273 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -1352,14 +1352,7 @@ static inline void arch_leave_lazy_cpu_mode(void) | |||
1352 | PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); | 1352 | PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); |
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | static inline void arch_flush_lazy_cpu_mode(void) | 1355 | void arch_flush_lazy_cpu_mode(void); |
1356 | { | ||
1357 | if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { | ||
1358 | arch_leave_lazy_cpu_mode(); | ||
1359 | arch_enter_lazy_cpu_mode(); | ||
1360 | } | ||
1361 | } | ||
1362 | |||
1363 | 1356 | ||
1364 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE | 1357 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE |
1365 | static inline void arch_enter_lazy_mmu_mode(void) | 1358 | static inline void arch_enter_lazy_mmu_mode(void) |
@@ -1372,13 +1365,7 @@ static inline void arch_leave_lazy_mmu_mode(void) | |||
1372 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); | 1365 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); |
1373 | } | 1366 | } |
1374 | 1367 | ||
1375 | static inline void arch_flush_lazy_mmu_mode(void) | 1368 | void arch_flush_lazy_mmu_mode(void); |
1376 | { | ||
1377 | if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { | ||
1378 | arch_leave_lazy_mmu_mode(); | ||
1379 | arch_enter_lazy_mmu_mode(); | ||
1380 | } | ||
1381 | } | ||
1382 | 1369 | ||
1383 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | 1370 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, |
1384 | unsigned long phys, pgprot_t flags) | 1371 | unsigned long phys, pgprot_t flags) |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index e4c8fb608873..dcba6c567a2a 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -268,6 +268,30 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | |||
268 | return __get_cpu_var(paravirt_lazy_mode); | 268 | return __get_cpu_var(paravirt_lazy_mode); |
269 | } | 269 | } |
270 | 270 | ||
271 | void arch_flush_lazy_mmu_mode(void) | ||
272 | { | ||
273 | preempt_disable(); | ||
274 | |||
275 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | ||
276 | arch_leave_lazy_mmu_mode(); | ||
277 | arch_enter_lazy_mmu_mode(); | ||
278 | } | ||
279 | |||
280 | preempt_enable(); | ||
281 | } | ||
282 | |||
283 | void arch_flush_lazy_cpu_mode(void) | ||
284 | { | ||
285 | preempt_disable(); | ||
286 | |||
287 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { | ||
288 | arch_leave_lazy_cpu_mode(); | ||
289 | arch_enter_lazy_cpu_mode(); | ||
290 | } | ||
291 | |||
292 | preempt_enable(); | ||
293 | } | ||
294 | |||
271 | struct pv_info pv_info = { | 295 | struct pv_info pv_info = { |
272 | .name = "bare hardware", | 296 | .name = "bare hardware", |
273 | .paravirt_enabled = 0, | 297 | .paravirt_enabled = 0, |