aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/mmu.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-06-16 07:30:03 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-25 09:17:34 -0400
commit400d34944c4ad82a817c06e570bc93b1114aa596 (patch)
treed963075e7a293c8481adcc66aff0fa5d87f35c09 /arch/x86/xen/mmu.c
parente57778a1e30470c9f5b79e370511b9af29b59c48 (diff)
xen: add mechanism to extend existing multicalls
Some Xen hypercalls accept an array of operations to work on. In general this is because its more efficient for the hypercall to the work all at once rather than as separate hypercalls (even batched as a multicall). This patch adds a mechanism (xen_mc_extend_args()) to allocate more argument space to the last-issued multicall, in order to extend its argument list. The user of this mechanism is xen/mmu.c, which uses it to extend the args array of mmu_update. This is particularly valuable when doing the update for a large mprotect, which goes via ptep_modify_prot_commit(), but it also manages to batch updates to pgd/pmds as well. 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.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 846dad7d54a5..f6b8225c2a0b 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -230,18 +230,35 @@ static bool page_pinned(void *ptr)
230 return PagePinned(page); 230 return PagePinned(page);
231} 231}
232 232
233void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val) 233static void extend_mmu_update(const struct mmu_update *update)
234{ 234{
235 struct multicall_space mcs; 235 struct multicall_space mcs;
236 struct mmu_update *u; 236 struct mmu_update *u;
237 237
238 preempt_disable(); 238 mcs = xen_mc_extend_args(__HYPERVISOR_mmu_update, sizeof(*u));
239
240 if (mcs.mc != NULL)
241 mcs.mc->args[1]++;
242 else {
243 mcs = __xen_mc_entry(sizeof(*u));
244 MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, DOMID_SELF);
245 }
239 246
240 mcs = xen_mc_entry(sizeof(*u));
241 u = mcs.args; 247 u = mcs.args;
242 u->ptr = virt_to_machine(ptr).maddr; 248 *u = *update;
243 u->val = pmd_val_ma(val); 249}
244 MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF); 250
251void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val)
252{
253 struct mmu_update u;
254
255 preempt_disable();
256
257 xen_mc_batch();
258
259 u.ptr = virt_to_machine(ptr).maddr;
260 u.val = pmd_val_ma(val);
261 extend_mmu_update(&u);
245 262
246 xen_mc_issue(PARAVIRT_LAZY_MMU); 263 xen_mc_issue(PARAVIRT_LAZY_MMU);
247 264
@@ -332,14 +349,13 @@ pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t
332void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, 349void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
333 pte_t *ptep, pte_t pte) 350 pte_t *ptep, pte_t pte)
334{ 351{
335 struct multicall_space mcs; 352 struct mmu_update u;
336 struct mmu_update *u;
337 353
338 mcs = xen_mc_entry(sizeof(*u)); 354 xen_mc_batch();
339 u = mcs.args; 355
340 u->ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD; 356 u.ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;
341 u->val = pte_val_ma(pte); 357 u.val = pte_val_ma(pte);
342 MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF); 358 extend_mmu_update(&u);
343 359
344 xen_mc_issue(PARAVIRT_LAZY_MMU); 360 xen_mc_issue(PARAVIRT_LAZY_MMU);
345} 361}
@@ -396,16 +412,15 @@ pmdval_t xen_pmd_val(pmd_t pmd)
396 412
397void xen_set_pud_hyper(pud_t *ptr, pud_t val) 413void xen_set_pud_hyper(pud_t *ptr, pud_t val)
398{ 414{
399 struct multicall_space mcs; 415 struct mmu_update u;
400 struct mmu_update *u;
401 416
402 preempt_disable(); 417 preempt_disable();
403 418
404 mcs = xen_mc_entry(sizeof(*u)); 419 xen_mc_batch();
405 u = mcs.args; 420
406 u->ptr = virt_to_machine(ptr).maddr; 421 u.ptr = virt_to_machine(ptr).maddr;
407 u->val = pud_val_ma(val); 422 u.val = pud_val_ma(val);
408 MULTI_mmu_update(mcs.mc, u, 1, NULL, DOMID_SELF); 423 extend_mmu_update(&u);
409 424
410 xen_mc_issue(PARAVIRT_LAZY_MMU); 425 xen_mc_issue(PARAVIRT_LAZY_MMU);
411 426