aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/xen/enlighten.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@xensource.com>2007-07-17 21:37:06 -0400
committerJeremy Fitzhardinge <jeremy@goop.org>2007-07-18 11:47:44 -0400
commitd66bf8fcf3fce058a1cd164a7c8ee6093fdf039c (patch)
treed09a2a4a8d0e81b8f19a4844c18690fe521bf513 /arch/i386/xen/enlighten.c
parentf120f13ea0dbb0b0d6675683d5f6faea71277e65 (diff)
xen: lazy-mmu operations
This patch uses the lazy-mmu hooks to batch mmu operations where possible. This is primarily useful for batching operations applied to active pagetables, which happens during mprotect, munmap, mremap and the like (mmap does not do bulk pagetable operations, so it isn't helped). Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Acked-by: Chris Wright <chrisw@sous-sol.org>
Diffstat (limited to 'arch/i386/xen/enlighten.c')
-rw-r--r--arch/i386/xen/enlighten.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c
index a1124b7f1d14..031dc1dcf819 100644
--- a/arch/i386/xen/enlighten.c
+++ b/arch/i386/xen/enlighten.c
@@ -472,28 +472,38 @@ static void xen_apic_write(unsigned long reg, unsigned long val)
472 472
473static void xen_flush_tlb(void) 473static void xen_flush_tlb(void)
474{ 474{
475 struct mmuext_op op; 475 struct mmuext_op *op;
476 struct multicall_space mcs = xen_mc_entry(sizeof(*op));
476 477
477 op.cmd = MMUEXT_TLB_FLUSH_LOCAL; 478 op = mcs.args;
478 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 479 op->cmd = MMUEXT_TLB_FLUSH_LOCAL;
479 BUG(); 480 MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
481
482 xen_mc_issue(PARAVIRT_LAZY_MMU);
480} 483}
481 484
482static void xen_flush_tlb_single(unsigned long addr) 485static void xen_flush_tlb_single(unsigned long addr)
483{ 486{
484 struct mmuext_op op; 487 struct mmuext_op *op;
488 struct multicall_space mcs = xen_mc_entry(sizeof(*op));
485 489
486 op.cmd = MMUEXT_INVLPG_LOCAL; 490 op = mcs.args;
487 op.arg1.linear_addr = addr & PAGE_MASK; 491 op->cmd = MMUEXT_INVLPG_LOCAL;
488 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 492 op->arg1.linear_addr = addr & PAGE_MASK;
489 BUG(); 493 MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
494
495 xen_mc_issue(PARAVIRT_LAZY_MMU);
490} 496}
491 497
492static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm, 498static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
493 unsigned long va) 499 unsigned long va)
494{ 500{
495 struct mmuext_op op; 501 struct {
502 struct mmuext_op op;
503 cpumask_t mask;
504 } *args;
496 cpumask_t cpumask = *cpus; 505 cpumask_t cpumask = *cpus;
506 struct multicall_space mcs;
497 507
498 /* 508 /*
499 * A couple of (to be removed) sanity checks: 509 * A couple of (to be removed) sanity checks:
@@ -510,17 +520,21 @@ static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
510 if (cpus_empty(cpumask)) 520 if (cpus_empty(cpumask))
511 return; 521 return;
512 522
523 mcs = xen_mc_entry(sizeof(*args));
524 args = mcs.args;
525 args->mask = cpumask;
526 args->op.arg2.vcpumask = &args->mask;
527
513 if (va == TLB_FLUSH_ALL) { 528 if (va == TLB_FLUSH_ALL) {
514 op.cmd = MMUEXT_TLB_FLUSH_MULTI; 529 args->op.cmd = MMUEXT_TLB_FLUSH_MULTI;
515 op.arg2.vcpumask = (void *)cpus;
516 } else { 530 } else {
517 op.cmd = MMUEXT_INVLPG_MULTI; 531 args->op.cmd = MMUEXT_INVLPG_MULTI;
518 op.arg1.linear_addr = va; 532 args->op.arg1.linear_addr = va;
519 op.arg2.vcpumask = (void *)cpus;
520 } 533 }
521 534
522 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 535 MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
523 BUG(); 536
537 xen_mc_issue(PARAVIRT_LAZY_MMU);
524} 538}
525 539
526static unsigned long xen_read_cr2(void) 540static unsigned long xen_read_cr2(void)