diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/kvm.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/paravirt.c | 56 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/vmi_32.c | 20 |
5 files changed, 42 insertions, 40 deletions
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 33019ddb56b4..6551dedee20c 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -195,7 +195,7 @@ static void kvm_leave_lazy_mmu(void) | |||
195 | struct kvm_para_state *state = kvm_para_state(); | 195 | struct kvm_para_state *state = kvm_para_state(); |
196 | 196 | ||
197 | mmu_queue_flush(state); | 197 | mmu_queue_flush(state); |
198 | paravirt_leave_lazy(paravirt_get_lazy_mode()); | 198 | paravirt_leave_lazy_mmu(); |
199 | state->mode = paravirt_get_lazy_mode(); | 199 | state->mode = paravirt_get_lazy_mode(); |
200 | } | 200 | } |
201 | 201 | ||
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 8e45f4464880..aa3442340705 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -246,18 +246,16 @@ static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LA | |||
246 | 246 | ||
247 | static inline void enter_lazy(enum paravirt_lazy_mode mode) | 247 | static inline void enter_lazy(enum paravirt_lazy_mode mode) |
248 | { | 248 | { |
249 | BUG_ON(__get_cpu_var(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); | 249 | BUG_ON(percpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE); |
250 | BUG_ON(preemptible()); | ||
251 | 250 | ||
252 | __get_cpu_var(paravirt_lazy_mode) = mode; | 251 | percpu_write(paravirt_lazy_mode, mode); |
253 | } | 252 | } |
254 | 253 | ||
255 | void paravirt_leave_lazy(enum paravirt_lazy_mode mode) | 254 | static void leave_lazy(enum paravirt_lazy_mode mode) |
256 | { | 255 | { |
257 | BUG_ON(__get_cpu_var(paravirt_lazy_mode) != mode); | 256 | BUG_ON(percpu_read(paravirt_lazy_mode) != mode); |
258 | BUG_ON(preemptible()); | ||
259 | 257 | ||
260 | __get_cpu_var(paravirt_lazy_mode) = PARAVIRT_LAZY_NONE; | 258 | percpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE); |
261 | } | 259 | } |
262 | 260 | ||
263 | void paravirt_enter_lazy_mmu(void) | 261 | void paravirt_enter_lazy_mmu(void) |
@@ -267,22 +265,36 @@ void paravirt_enter_lazy_mmu(void) | |||
267 | 265 | ||
268 | void paravirt_leave_lazy_mmu(void) | 266 | void paravirt_leave_lazy_mmu(void) |
269 | { | 267 | { |
270 | paravirt_leave_lazy(PARAVIRT_LAZY_MMU); | 268 | leave_lazy(PARAVIRT_LAZY_MMU); |
271 | } | 269 | } |
272 | 270 | ||
273 | void paravirt_enter_lazy_cpu(void) | 271 | void paravirt_start_context_switch(struct task_struct *prev) |
274 | { | 272 | { |
273 | BUG_ON(preemptible()); | ||
274 | |||
275 | if (percpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) { | ||
276 | arch_leave_lazy_mmu_mode(); | ||
277 | set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES); | ||
278 | } | ||
275 | enter_lazy(PARAVIRT_LAZY_CPU); | 279 | enter_lazy(PARAVIRT_LAZY_CPU); |
276 | } | 280 | } |
277 | 281 | ||
278 | void paravirt_leave_lazy_cpu(void) | 282 | void paravirt_end_context_switch(struct task_struct *next) |
279 | { | 283 | { |
280 | paravirt_leave_lazy(PARAVIRT_LAZY_CPU); | 284 | BUG_ON(preemptible()); |
285 | |||
286 | leave_lazy(PARAVIRT_LAZY_CPU); | ||
287 | |||
288 | if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES)) | ||
289 | arch_enter_lazy_mmu_mode(); | ||
281 | } | 290 | } |
282 | 291 | ||
283 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | 292 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void) |
284 | { | 293 | { |
285 | return __get_cpu_var(paravirt_lazy_mode); | 294 | if (in_interrupt()) |
295 | return PARAVIRT_LAZY_NONE; | ||
296 | |||
297 | return percpu_read(paravirt_lazy_mode); | ||
286 | } | 298 | } |
287 | 299 | ||
288 | void arch_flush_lazy_mmu_mode(void) | 300 | void arch_flush_lazy_mmu_mode(void) |
@@ -290,7 +302,6 @@ void arch_flush_lazy_mmu_mode(void) | |||
290 | preempt_disable(); | 302 | preempt_disable(); |
291 | 303 | ||
292 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | 304 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { |
293 | WARN_ON(preempt_count() == 1); | ||
294 | arch_leave_lazy_mmu_mode(); | 305 | arch_leave_lazy_mmu_mode(); |
295 | arch_enter_lazy_mmu_mode(); | 306 | arch_enter_lazy_mmu_mode(); |
296 | } | 307 | } |
@@ -298,19 +309,6 @@ void arch_flush_lazy_mmu_mode(void) | |||
298 | preempt_enable(); | 309 | preempt_enable(); |
299 | } | 310 | } |
300 | 311 | ||
301 | void arch_flush_lazy_cpu_mode(void) | ||
302 | { | ||
303 | preempt_disable(); | ||
304 | |||
305 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { | ||
306 | WARN_ON(preempt_count() == 1); | ||
307 | arch_leave_lazy_cpu_mode(); | ||
308 | arch_enter_lazy_cpu_mode(); | ||
309 | } | ||
310 | |||
311 | preempt_enable(); | ||
312 | } | ||
313 | |||
314 | struct pv_info pv_info = { | 312 | struct pv_info pv_info = { |
315 | .name = "bare hardware", | 313 | .name = "bare hardware", |
316 | .paravirt_enabled = 0, | 314 | .paravirt_enabled = 0, |
@@ -402,10 +400,8 @@ struct pv_cpu_ops pv_cpu_ops = { | |||
402 | .set_iopl_mask = native_set_iopl_mask, | 400 | .set_iopl_mask = native_set_iopl_mask, |
403 | .io_delay = native_io_delay, | 401 | .io_delay = native_io_delay, |
404 | 402 | ||
405 | .lazy_mode = { | 403 | .start_context_switch = paravirt_nop, |
406 | .enter = paravirt_nop, | 404 | .end_context_switch = paravirt_nop, |
407 | .leave = paravirt_nop, | ||
408 | }, | ||
409 | }; | 405 | }; |
410 | 406 | ||
411 | struct pv_apic_ops pv_apic_ops = { | 407 | struct pv_apic_ops pv_apic_ops = { |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 76f8f84043a2..5de30f0960fb 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -407,7 +407,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
407 | * done before math_state_restore, so the TS bit is up | 407 | * done before math_state_restore, so the TS bit is up |
408 | * to date. | 408 | * to date. |
409 | */ | 409 | */ |
410 | arch_leave_lazy_cpu_mode(); | 410 | arch_end_context_switch(next_p); |
411 | 411 | ||
412 | /* If the task has used fpu the last 5 timeslices, just do a full | 412 | /* If the task has used fpu the last 5 timeslices, just do a full |
413 | * restore of the math state immediately to avoid the trap; the | 413 | * restore of the math state immediately to avoid the trap; the |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index b751a41392b1..66ad06791d6f 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -428,7 +428,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
428 | * done before math_state_restore, so the TS bit is up | 428 | * done before math_state_restore, so the TS bit is up |
429 | * to date. | 429 | * to date. |
430 | */ | 430 | */ |
431 | arch_leave_lazy_cpu_mode(); | 431 | arch_end_context_switch(next_p); |
432 | 432 | ||
433 | /* | 433 | /* |
434 | * Switch FS and GS. | 434 | * Switch FS and GS. |
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index 95deb9f2211e..b263423fbe2a 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c | |||
@@ -462,22 +462,28 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, | |||
462 | } | 462 | } |
463 | #endif | 463 | #endif |
464 | 464 | ||
465 | static void vmi_enter_lazy_cpu(void) | 465 | static void vmi_start_context_switch(struct task_struct *prev) |
466 | { | 466 | { |
467 | paravirt_enter_lazy_cpu(); | 467 | paravirt_start_context_switch(prev); |
468 | vmi_ops.set_lazy_mode(2); | 468 | vmi_ops.set_lazy_mode(2); |
469 | } | 469 | } |
470 | 470 | ||
471 | static void vmi_end_context_switch(struct task_struct *next) | ||
472 | { | ||
473 | vmi_ops.set_lazy_mode(0); | ||
474 | paravirt_end_context_switch(next); | ||
475 | } | ||
476 | |||
471 | static void vmi_enter_lazy_mmu(void) | 477 | static void vmi_enter_lazy_mmu(void) |
472 | { | 478 | { |
473 | paravirt_enter_lazy_mmu(); | 479 | paravirt_enter_lazy_mmu(); |
474 | vmi_ops.set_lazy_mode(1); | 480 | vmi_ops.set_lazy_mode(1); |
475 | } | 481 | } |
476 | 482 | ||
477 | static void vmi_leave_lazy(void) | 483 | static void vmi_leave_lazy_mmu(void) |
478 | { | 484 | { |
479 | paravirt_leave_lazy(paravirt_get_lazy_mode()); | ||
480 | vmi_ops.set_lazy_mode(0); | 485 | vmi_ops.set_lazy_mode(0); |
486 | paravirt_leave_lazy_mmu(); | ||
481 | } | 487 | } |
482 | 488 | ||
483 | static inline int __init check_vmi_rom(struct vrom_header *rom) | 489 | static inline int __init check_vmi_rom(struct vrom_header *rom) |
@@ -711,14 +717,14 @@ static inline int __init activate_vmi(void) | |||
711 | para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask); | 717 | para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask); |
712 | para_fill(pv_cpu_ops.io_delay, IODelay); | 718 | para_fill(pv_cpu_ops.io_delay, IODelay); |
713 | 719 | ||
714 | para_wrap(pv_cpu_ops.lazy_mode.enter, vmi_enter_lazy_cpu, | 720 | para_wrap(pv_cpu_ops.start_context_switch, vmi_start_context_switch, |
715 | set_lazy_mode, SetLazyMode); | 721 | set_lazy_mode, SetLazyMode); |
716 | para_wrap(pv_cpu_ops.lazy_mode.leave, vmi_leave_lazy, | 722 | para_wrap(pv_cpu_ops.end_context_switch, vmi_end_context_switch, |
717 | set_lazy_mode, SetLazyMode); | 723 | set_lazy_mode, SetLazyMode); |
718 | 724 | ||
719 | para_wrap(pv_mmu_ops.lazy_mode.enter, vmi_enter_lazy_mmu, | 725 | para_wrap(pv_mmu_ops.lazy_mode.enter, vmi_enter_lazy_mmu, |
720 | set_lazy_mode, SetLazyMode); | 726 | set_lazy_mode, SetLazyMode); |
721 | para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy, | 727 | para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy_mmu, |
722 | set_lazy_mode, SetLazyMode); | 728 | set_lazy_mode, SetLazyMode); |
723 | 729 | ||
724 | /* user and kernel flush are just handled with different flags to FlushTLB */ | 730 | /* user and kernel flush are just handled with different flags to FlushTLB */ |