diff options
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r-- | arch/x86/xen/mmu.c | 51 |
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 | ||
439 | void xen_set_pte(pte_t *ptep, pte_t pte) | 439 | void 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 | ||
446 | void xen_set_pte_atomic(pte_t *ptep, pte_t pte) | 451 | void 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 | ||
451 | void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 456 | void 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 | ||
463 | pmd_t xen_make_pmd(pmdval_t pmd) | 469 | pmd_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 | ||
476 | pudval_t xen_pud_val(pud_t pud) | ||
477 | { | ||
478 | return pte_mfn_to_pfn(pud.pud); | ||
479 | } | ||
480 | |||
481 | pud_t xen_make_pud(pudval_t pud) | ||
482 | { | ||
483 | pud = pte_pfn_to_mfn(pud); | ||
484 | |||
485 | return native_make_pud(pud); | ||
486 | } | ||
487 | |||
488 | void 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 | |||
505 | void 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 |