aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r--arch/x86/xen/mmu.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 4fca9d88bef0..d0976b87cd2c 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -438,14 +438,19 @@ void xen_set_pud(pud_t *ptr, pud_t val)
438 438
439void xen_set_pte(pte_t *ptep, pte_t pte) 439void xen_set_pte(pte_t *ptep, pte_t pte)
440{ 440{
441#ifdef CONFIG_X86_PAE
441 ptep->pte_high = pte.pte_high; 442 ptep->pte_high = pte.pte_high;
442 smp_wmb(); 443 smp_wmb();
443 ptep->pte_low = pte.pte_low; 444 ptep->pte_low = pte.pte_low;
445#else
446 *ptep = pte;
447#endif
444} 448}
445 449
450#ifdef CONFIG_X86_PAE
446void xen_set_pte_atomic(pte_t *ptep, pte_t pte) 451void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
447{ 452{
448 set_64bit((u64 *)ptep, pte_val_ma(pte)); 453 set_64bit((u64 *)ptep, native_pte_val(pte));
449} 454}
450 455
451void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 456void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
@@ -459,6 +464,7 @@ void xen_pmd_clear(pmd_t *pmdp)
459{ 464{
460 set_pmd(pmdp, __pmd(0)); 465 set_pmd(pmdp, __pmd(0));
461} 466}
467#endif /* CONFIG_X86_PAE */
462 468
463pmd_t xen_make_pmd(pmdval_t pmd) 469pmd_t xen_make_pmd(pmdval_t pmd)
464{ 470{
@@ -466,6 +472,49 @@ pmd_t xen_make_pmd(pmdval_t pmd)
466 return native_make_pmd(pmd); 472 return native_make_pmd(pmd);
467} 473}
468 474
475#if PAGETABLE_LEVELS == 4
476pudval_t xen_pud_val(pud_t pud)
477{
478 return pte_mfn_to_pfn(pud.pud);
479}
480
481pud_t xen_make_pud(pudval_t pud)
482{
483 pud = pte_pfn_to_mfn(pud);
484
485 return native_make_pud(pud);
486}
487
488void xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
489{
490 struct mmu_update u;
491
492 preempt_disable();
493
494 xen_mc_batch();
495
496 u.ptr = virt_to_machine(ptr).maddr;
497 u.val = pgd_val_ma(val);
498 extend_mmu_update(&u);
499
500 xen_mc_issue(PARAVIRT_LAZY_MMU);
501
502 preempt_enable();
503}
504
505void xen_set_pgd(pgd_t *ptr, pgd_t val)
506{
507 /* If page is not pinned, we can just update the entry
508 directly */
509 if (!page_pinned(ptr)) {
510 *ptr = val;
511 return;
512 }
513
514 xen_set_pgd_hyper(ptr, val);
515}
516#endif /* PAGETABLE_LEVELS == 4 */
517
469/* 518/*
470 (Yet another) pagetable walker. This one is intended for pinning a 519 (Yet another) pagetable walker. This one is intended for pinning a
471 pagetable. This means that it walks a pagetable and calls the 520 pagetable. This means that it walks a pagetable and calls the