aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/mmu.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-06-16 07:30:02 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-25 09:17:23 -0400
commite57778a1e30470c9f5b79e370511b9af29b59c48 (patch)
tree01239f16b016d57206ba8bdfcbd443d8a26cd5e4 /arch/x86/xen/mmu.c
parent08b882c627aeeeb3cfd3c4354f0d360d7949549d (diff)
xen: implement ptep_modify_prot_start/commit
Xen has a pte update function which will update a pte while preserving its accessed and dirty bits. This means that ptep_modify_prot_start() can be implemented as a simple read of the pte value. The hardware may update the pte in the meantime, but ptep_modify_prot_commit() updates it while preserving any changes that may have happened in the meantime. The updates in ptep_modify_prot_commit() are batched if we're currently in lazy mmu mode. The mmu_update hypercall can take a batch of updates to perform, but this code doesn't make particular use of that feature, in favour of using generic multicall batching to get them all into the hypervisor. The net effect of this is that each mprotect pte update turns from two expensive trap-and-emulate faults into they hypervisor into a single hypercall whose cost is amortized in a batched multicall. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Acked-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r--arch/x86/xen/mmu.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 8132aa8c5d49..846dad7d54a5 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -323,6 +323,27 @@ out:
323 preempt_enable(); 323 preempt_enable();
324} 324}
325 325
326pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
327{
328 /* Just return the pte as-is. We preserve the bits on commit */
329 return *ptep;
330}
331
332void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
333 pte_t *ptep, pte_t pte)
334{
335 struct multicall_space mcs;
336 struct mmu_update *u;
337
338 mcs = xen_mc_entry(sizeof(*u));
339 u = mcs.args;
340 u->ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;
341 u->val = pte_val_ma(pte);
342 MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF);
343
344 xen_mc_issue(PARAVIRT_LAZY_MMU);
345}
346
326/* Assume pteval_t is equivalent to all the other *val_t types. */ 347/* Assume pteval_t is equivalent to all the other *val_t types. */
327static pteval_t pte_mfn_to_pfn(pteval_t val) 348static pteval_t pte_mfn_to_pfn(pteval_t val)
328{ 349{