aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r--arch/x86/xen/mmu.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index c4a391f88980..72f08ab43a4d 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -514,20 +514,43 @@ static void drop_other_mm_ref(void *info)
514 514
515 if (__get_cpu_var(cpu_tlbstate).active_mm == mm) 515 if (__get_cpu_var(cpu_tlbstate).active_mm == mm)
516 leave_mm(smp_processor_id()); 516 leave_mm(smp_processor_id());
517
518 /* If this cpu still has a stale cr3 reference, then make sure
519 it has been flushed. */
520 if (x86_read_percpu(xen_current_cr3) == __pa(mm->pgd)) {
521 load_cr3(swapper_pg_dir);
522 arch_flush_lazy_cpu_mode();
523 }
517} 524}
518 525
519static void drop_mm_ref(struct mm_struct *mm) 526static void drop_mm_ref(struct mm_struct *mm)
520{ 527{
528 cpumask_t mask;
529 unsigned cpu;
530
521 if (current->active_mm == mm) { 531 if (current->active_mm == mm) {
522 if (current->mm == mm) 532 if (current->mm == mm)
523 load_cr3(swapper_pg_dir); 533 load_cr3(swapper_pg_dir);
524 else 534 else
525 leave_mm(smp_processor_id()); 535 leave_mm(smp_processor_id());
536 arch_flush_lazy_cpu_mode();
537 }
538
539 /* Get the "official" set of cpus referring to our pagetable. */
540 mask = mm->cpu_vm_mask;
541
542 /* It's possible that a vcpu may have a stale reference to our
543 cr3, because its in lazy mode, and it hasn't yet flushed
544 its set of pending hypercalls yet. In this case, we can
545 look at its actual current cr3 value, and force it to flush
546 if needed. */
547 for_each_online_cpu(cpu) {
548 if (per_cpu(xen_current_cr3, cpu) == __pa(mm->pgd))
549 cpu_set(cpu, mask);
526 } 550 }
527 551
528 if (!cpus_empty(mm->cpu_vm_mask)) 552 if (!cpus_empty(mask))
529 xen_smp_call_function_mask(mm->cpu_vm_mask, drop_other_mm_ref, 553 xen_smp_call_function_mask(mask, drop_other_mm_ref, mm, 1);
530 mm, 1);
531} 554}
532#else 555#else
533static void drop_mm_ref(struct mm_struct *mm) 556static void drop_mm_ref(struct mm_struct *mm)