aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/xen/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/xen/mmu.c')
-rw-r--r--arch/i386/xen/mmu.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/arch/i386/xen/mmu.c b/arch/i386/xen/mmu.c
index f431cf14e644..4ae038aa6c24 100644
--- a/arch/i386/xen/mmu.c
+++ b/arch/i386/xen/mmu.c
@@ -98,12 +98,20 @@ void make_lowmem_page_readwrite(void *vaddr)
98 98
99void xen_set_pmd(pmd_t *ptr, pmd_t val) 99void xen_set_pmd(pmd_t *ptr, pmd_t val)
100{ 100{
101 struct mmu_update u; 101 struct multicall_space mcs;
102 struct mmu_update *u;
102 103
103 u.ptr = virt_to_machine(ptr).maddr; 104 preempt_disable();
104 u.val = pmd_val_ma(val); 105
105 if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) 106 mcs = xen_mc_entry(sizeof(*u));
106 BUG(); 107 u = mcs.args;
108 u->ptr = virt_to_machine(ptr).maddr;
109 u->val = pmd_val_ma(val);
110 MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF);
111
112 xen_mc_issue(PARAVIRT_LAZY_MMU);
113
114 preempt_enable();
107} 115}
108 116
109/* 117/*
@@ -146,20 +154,38 @@ void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
146void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, 154void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
147 pte_t *ptep, pte_t pteval) 155 pte_t *ptep, pte_t pteval)
148{ 156{
149 if ((mm != current->mm && mm != &init_mm) || 157 if (mm == current->mm || mm == &init_mm) {
150 HYPERVISOR_update_va_mapping(addr, pteval, 0) != 0) 158 if (xen_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
151 xen_set_pte(ptep, pteval); 159 struct multicall_space mcs;
160 mcs = xen_mc_entry(0);
161
162 MULTI_update_va_mapping(mcs.mc, addr, pteval, 0);
163 xen_mc_issue(PARAVIRT_LAZY_MMU);
164 return;
165 } else
166 if (HYPERVISOR_update_va_mapping(addr, pteval, 0) == 0)
167 return;
168 }
169 xen_set_pte(ptep, pteval);
152} 170}
153 171
154#ifdef CONFIG_X86_PAE 172#ifdef CONFIG_X86_PAE
155void xen_set_pud(pud_t *ptr, pud_t val) 173void xen_set_pud(pud_t *ptr, pud_t val)
156{ 174{
157 struct mmu_update u; 175 struct multicall_space mcs;
176 struct mmu_update *u;
158 177
159 u.ptr = virt_to_machine(ptr).maddr; 178 preempt_disable();
160 u.val = pud_val_ma(val); 179
161 if (HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0) 180 mcs = xen_mc_entry(sizeof(*u));
162 BUG(); 181 u = mcs.args;
182 u->ptr = virt_to_machine(ptr).maddr;
183 u->val = pud_val_ma(val);
184 MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF);
185
186 xen_mc_issue(PARAVIRT_LAZY_MMU);
187
188 preempt_enable();
163} 189}
164 190
165void xen_set_pte(pte_t *ptep, pte_t pte) 191void xen_set_pte(pte_t *ptep, pte_t pte)