aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/xen/mmu.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/mmu.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/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)