diff options
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r-- | arch/x86/xen/mmu.c | 143 |
1 files changed, 56 insertions, 87 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 2a054ef2a3da..6cbcf65609ad 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -156,6 +156,10 @@ void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags) | |||
156 | void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, | 156 | void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, |
157 | pte_t *ptep, pte_t pteval) | 157 | pte_t *ptep, pte_t pteval) |
158 | { | 158 | { |
159 | /* updates to init_mm may be done without lock */ | ||
160 | if (mm == &init_mm) | ||
161 | preempt_disable(); | ||
162 | |||
159 | if (mm == current->mm || mm == &init_mm) { | 163 | if (mm == current->mm || mm == &init_mm) { |
160 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | 164 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { |
161 | struct multicall_space mcs; | 165 | struct multicall_space mcs; |
@@ -163,14 +167,61 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
163 | 167 | ||
164 | MULTI_update_va_mapping(mcs.mc, addr, pteval, 0); | 168 | MULTI_update_va_mapping(mcs.mc, addr, pteval, 0); |
165 | xen_mc_issue(PARAVIRT_LAZY_MMU); | 169 | xen_mc_issue(PARAVIRT_LAZY_MMU); |
166 | return; | 170 | goto out; |
167 | } else | 171 | } else |
168 | if (HYPERVISOR_update_va_mapping(addr, pteval, 0) == 0) | 172 | if (HYPERVISOR_update_va_mapping(addr, pteval, 0) == 0) |
169 | return; | 173 | goto out; |
170 | } | 174 | } |
171 | xen_set_pte(ptep, pteval); | 175 | xen_set_pte(ptep, pteval); |
176 | |||
177 | out: | ||
178 | if (mm == &init_mm) | ||
179 | preempt_enable(); | ||
180 | } | ||
181 | |||
182 | pteval_t xen_pte_val(pte_t pte) | ||
183 | { | ||
184 | pteval_t ret = pte.pte; | ||
185 | |||
186 | if (ret & _PAGE_PRESENT) | ||
187 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | pgdval_t xen_pgd_val(pgd_t pgd) | ||
193 | { | ||
194 | pgdval_t ret = pgd.pgd; | ||
195 | if (ret & _PAGE_PRESENT) | ||
196 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | pte_t xen_make_pte(pteval_t pte) | ||
201 | { | ||
202 | if (pte & _PAGE_PRESENT) { | ||
203 | pte = phys_to_machine(XPADDR(pte)).maddr; | ||
204 | pte &= ~(_PAGE_PCD | _PAGE_PWT); | ||
205 | } | ||
206 | |||
207 | return (pte_t){ .pte = pte }; | ||
172 | } | 208 | } |
173 | 209 | ||
210 | pgd_t xen_make_pgd(pgdval_t pgd) | ||
211 | { | ||
212 | if (pgd & _PAGE_PRESENT) | ||
213 | pgd = phys_to_machine(XPADDR(pgd)).maddr; | ||
214 | |||
215 | return (pgd_t){ pgd }; | ||
216 | } | ||
217 | |||
218 | pmdval_t xen_pmd_val(pmd_t pmd) | ||
219 | { | ||
220 | pmdval_t ret = native_pmd_val(pmd); | ||
221 | if (ret & _PAGE_PRESENT) | ||
222 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
223 | return ret; | ||
224 | } | ||
174 | #ifdef CONFIG_X86_PAE | 225 | #ifdef CONFIG_X86_PAE |
175 | void xen_set_pud(pud_t *ptr, pud_t val) | 226 | void xen_set_pud(pud_t *ptr, pud_t val) |
176 | { | 227 | { |
@@ -214,100 +265,18 @@ void xen_pmd_clear(pmd_t *pmdp) | |||
214 | xen_set_pmd(pmdp, __pmd(0)); | 265 | xen_set_pmd(pmdp, __pmd(0)); |
215 | } | 266 | } |
216 | 267 | ||
217 | unsigned long long xen_pte_val(pte_t pte) | 268 | pmd_t xen_make_pmd(pmdval_t pmd) |
218 | { | 269 | { |
219 | unsigned long long ret = 0; | 270 | if (pmd & _PAGE_PRESENT) |
220 | |||
221 | if (pte.pte_low) { | ||
222 | ret = ((unsigned long long)pte.pte_high << 32) | pte.pte_low; | ||
223 | ret = machine_to_phys(XMADDR(ret)).paddr | 1; | ||
224 | } | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | unsigned long long xen_pmd_val(pmd_t pmd) | ||
230 | { | ||
231 | unsigned long long ret = pmd.pmd; | ||
232 | if (ret) | ||
233 | ret = machine_to_phys(XMADDR(ret)).paddr | 1; | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | unsigned long long xen_pgd_val(pgd_t pgd) | ||
238 | { | ||
239 | unsigned long long ret = pgd.pgd; | ||
240 | if (ret) | ||
241 | ret = machine_to_phys(XMADDR(ret)).paddr | 1; | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | pte_t xen_make_pte(unsigned long long pte) | ||
246 | { | ||
247 | if (pte & _PAGE_PRESENT) { | ||
248 | pte = phys_to_machine(XPADDR(pte)).maddr; | ||
249 | pte &= ~(_PAGE_PCD | _PAGE_PWT); | ||
250 | } | ||
251 | |||
252 | return (pte_t){ .pte = pte }; | ||
253 | } | ||
254 | |||
255 | pmd_t xen_make_pmd(unsigned long long pmd) | ||
256 | { | ||
257 | if (pmd & 1) | ||
258 | pmd = phys_to_machine(XPADDR(pmd)).maddr; | 271 | pmd = phys_to_machine(XPADDR(pmd)).maddr; |
259 | 272 | ||
260 | return (pmd_t){ pmd }; | 273 | return native_make_pmd(pmd); |
261 | } | ||
262 | |||
263 | pgd_t xen_make_pgd(unsigned long long pgd) | ||
264 | { | ||
265 | if (pgd & _PAGE_PRESENT) | ||
266 | pgd = phys_to_machine(XPADDR(pgd)).maddr; | ||
267 | |||
268 | return (pgd_t){ pgd }; | ||
269 | } | 274 | } |
270 | #else /* !PAE */ | 275 | #else /* !PAE */ |
271 | void xen_set_pte(pte_t *ptep, pte_t pte) | 276 | void xen_set_pte(pte_t *ptep, pte_t pte) |
272 | { | 277 | { |
273 | *ptep = pte; | 278 | *ptep = pte; |
274 | } | 279 | } |
275 | |||
276 | unsigned long xen_pte_val(pte_t pte) | ||
277 | { | ||
278 | unsigned long ret = pte.pte_low; | ||
279 | |||
280 | if (ret & _PAGE_PRESENT) | ||
281 | ret = machine_to_phys(XMADDR(ret)).paddr; | ||
282 | |||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | unsigned long xen_pgd_val(pgd_t pgd) | ||
287 | { | ||
288 | unsigned long ret = pgd.pgd; | ||
289 | if (ret) | ||
290 | ret = machine_to_phys(XMADDR(ret)).paddr | 1; | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | pte_t xen_make_pte(unsigned long pte) | ||
295 | { | ||
296 | if (pte & _PAGE_PRESENT) { | ||
297 | pte = phys_to_machine(XPADDR(pte)).maddr; | ||
298 | pte &= ~(_PAGE_PCD | _PAGE_PWT); | ||
299 | } | ||
300 | |||
301 | return (pte_t){ pte }; | ||
302 | } | ||
303 | |||
304 | pgd_t xen_make_pgd(unsigned long pgd) | ||
305 | { | ||
306 | if (pgd & _PAGE_PRESENT) | ||
307 | pgd = phys_to_machine(XPADDR(pgd)).maddr; | ||
308 | |||
309 | return (pgd_t){ pgd }; | ||
310 | } | ||
311 | #endif /* CONFIG_X86_PAE */ | 280 | #endif /* CONFIG_X86_PAE */ |
312 | 281 | ||
313 | /* | 282 | /* |