xen: allow set_pte_at on init_mm to be lockless
authorJeremy Fitzhardinge <jeremy@goop.org>
Wed, 2 Apr 2008 17:54:10 +0000 (10:54 -0700)
committerIngo Molnar <mingo@elte.hu>
Thu, 24 Apr 2008 21:57:33 +0000 (23:57 +0200)
The usual pagetable locking protocol doesn't seem to apply to updates
to init_mm, so don't rely on preemption being disabled in xen_set_pte_at
on init_mm.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/xen/mmu.c

index 272635aaef887e0aee36c1038973b4ab393f83e1..6cbcf65609addd6f04d6d6b8d05607624442337b 100644 (file)
@@ -156,6 +156,10 @@ void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
 void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
                    pte_t *ptep, pte_t pteval)
 {
+       /* updates to init_mm may be done without lock */
+       if (mm == &init_mm)
+               preempt_disable();
+
        if (mm == current->mm || mm == &init_mm) {
                if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
                        struct multicall_space mcs;
@@ -163,12 +167,16 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
 
                        MULTI_update_va_mapping(mcs.mc, addr, pteval, 0);
                        xen_mc_issue(PARAVIRT_LAZY_MMU);
-                       return;
+                       goto out;
                } else
                        if (HYPERVISOR_update_va_mapping(addr, pteval, 0) == 0)
-                               return;
+                               goto out;
        }
        xen_set_pte(ptep, pteval);
+
+out:
+       if (mm == &init_mm)
+               preempt_enable();
 }
 
 pteval_t xen_pte_val(pte_t pte)