xen64: add extra pv_mmu_ops
We need extra pv_mmu_ops for 64-bit, to deal with the extra level of pagetable. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Cc: Stephen Tweedie <sct@redhat.com> Cc: Eduardo Habkost <ehabkost@redhat.com> Cc: Mark McLoughlin <markmc@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
e74359028d
commit
f6e587325b
|
@ -803,6 +803,18 @@ static void xen_release_pmd(u32 pfn)
|
||||||
xen_release_ptpage(pfn, PT_PMD);
|
xen_release_ptpage(pfn, PT_PMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PAGETABLE_LEVELS == 4
|
||||||
|
static void xen_alloc_pud(struct mm_struct *mm, u32 pfn)
|
||||||
|
{
|
||||||
|
xen_alloc_ptpage(mm, pfn, PT_PUD);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xen_release_pud(u32 pfn)
|
||||||
|
{
|
||||||
|
xen_release_ptpage(pfn, PT_PUD);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHPTE
|
#ifdef CONFIG_HIGHPTE
|
||||||
static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
|
static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
|
||||||
{
|
{
|
||||||
|
@ -922,6 +934,11 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
|
||||||
pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
|
pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
|
||||||
pv_mmu_ops.release_pte = xen_release_pte;
|
pv_mmu_ops.release_pte = xen_release_pte;
|
||||||
pv_mmu_ops.release_pmd = xen_release_pmd;
|
pv_mmu_ops.release_pmd = xen_release_pmd;
|
||||||
|
#if PAGETABLE_LEVELS == 4
|
||||||
|
pv_mmu_ops.alloc_pud = xen_alloc_pud;
|
||||||
|
pv_mmu_ops.release_pud = xen_release_pud;
|
||||||
|
#endif
|
||||||
|
|
||||||
pv_mmu_ops.set_pte = xen_set_pte;
|
pv_mmu_ops.set_pte = xen_set_pte;
|
||||||
|
|
||||||
xen_setup_shared_info();
|
xen_setup_shared_info();
|
||||||
|
@ -937,6 +954,9 @@ static __init void xen_post_allocator_init(void)
|
||||||
{
|
{
|
||||||
pv_mmu_ops.set_pmd = xen_set_pmd;
|
pv_mmu_ops.set_pmd = xen_set_pmd;
|
||||||
pv_mmu_ops.set_pud = xen_set_pud;
|
pv_mmu_ops.set_pud = xen_set_pud;
|
||||||
|
#if PAGETABLE_LEVELS == 4
|
||||||
|
pv_mmu_ops.set_pgd = xen_set_pgd;
|
||||||
|
#endif
|
||||||
|
|
||||||
xen_mark_init_mm_pinned();
|
xen_mark_init_mm_pinned();
|
||||||
}
|
}
|
||||||
|
@ -1185,15 +1205,26 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
||||||
.make_pte = xen_make_pte,
|
.make_pte = xen_make_pte,
|
||||||
.make_pgd = xen_make_pgd,
|
.make_pgd = xen_make_pgd,
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
.set_pte_atomic = xen_set_pte_atomic,
|
.set_pte_atomic = xen_set_pte_atomic,
|
||||||
.set_pte_present = xen_set_pte_at,
|
.set_pte_present = xen_set_pte_at,
|
||||||
.set_pud = xen_set_pud_hyper,
|
|
||||||
.pte_clear = xen_pte_clear,
|
.pte_clear = xen_pte_clear,
|
||||||
.pmd_clear = xen_pmd_clear,
|
.pmd_clear = xen_pmd_clear,
|
||||||
|
#endif /* CONFIG_X86_PAE */
|
||||||
|
.set_pud = xen_set_pud_hyper,
|
||||||
|
|
||||||
.make_pmd = xen_make_pmd,
|
.make_pmd = xen_make_pmd,
|
||||||
.pmd_val = xen_pmd_val,
|
.pmd_val = xen_pmd_val,
|
||||||
|
|
||||||
|
#if PAGETABLE_LEVELS == 4
|
||||||
|
.pud_val = xen_pud_val,
|
||||||
|
.make_pud = xen_make_pud,
|
||||||
|
.set_pgd = xen_set_pgd_hyper,
|
||||||
|
|
||||||
|
.alloc_pud = xen_alloc_pte_init,
|
||||||
|
.release_pud = xen_release_pte_init,
|
||||||
|
#endif /* PAGETABLE_LEVELS == 4 */
|
||||||
|
|
||||||
.activate_mm = xen_activate_mm,
|
.activate_mm = xen_activate_mm,
|
||||||
.dup_mmap = xen_dup_mmap,
|
.dup_mmap = xen_dup_mmap,
|
||||||
.exit_mmap = xen_exit_mmap,
|
.exit_mmap = xen_exit_mmap,
|
||||||
|
|
|
@ -438,14 +438,19 @@ void xen_set_pud(pud_t *ptr, pud_t val)
|
||||||
|
|
||||||
void xen_set_pte(pte_t *ptep, pte_t pte)
|
void xen_set_pte(pte_t *ptep, pte_t pte)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
ptep->pte_high = pte.pte_high;
|
ptep->pte_high = pte.pte_high;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
ptep->pte_low = pte.pte_low;
|
ptep->pte_low = pte.pte_low;
|
||||||
|
#else
|
||||||
|
*ptep = pte;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
|
void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
|
||||||
{
|
{
|
||||||
set_64bit((u64 *)ptep, pte_val_ma(pte));
|
set_64bit((u64 *)ptep, native_pte_val(pte));
|
||||||
}
|
}
|
||||||
|
|
||||||
void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
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)
|
||||||
{
|
{
|
||||||
set_pmd(pmdp, __pmd(0));
|
set_pmd(pmdp, __pmd(0));
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_X86_PAE */
|
||||||
|
|
||||||
pmd_t xen_make_pmd(pmdval_t pmd)
|
pmd_t xen_make_pmd(pmdval_t pmd)
|
||||||
{
|
{
|
||||||
|
@ -466,6 +472,49 @@ pmd_t xen_make_pmd(pmdval_t pmd)
|
||||||
return native_make_pmd(pmd);
|
return native_make_pmd(pmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PAGETABLE_LEVELS == 4
|
||||||
|
pudval_t xen_pud_val(pud_t pud)
|
||||||
|
{
|
||||||
|
return pte_mfn_to_pfn(pud.pud);
|
||||||
|
}
|
||||||
|
|
||||||
|
pud_t xen_make_pud(pudval_t pud)
|
||||||
|
{
|
||||||
|
pud = pte_pfn_to_mfn(pud);
|
||||||
|
|
||||||
|
return native_make_pud(pud);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
|
||||||
|
{
|
||||||
|
struct mmu_update u;
|
||||||
|
|
||||||
|
preempt_disable();
|
||||||
|
|
||||||
|
xen_mc_batch();
|
||||||
|
|
||||||
|
u.ptr = virt_to_machine(ptr).maddr;
|
||||||
|
u.val = pgd_val_ma(val);
|
||||||
|
extend_mmu_update(&u);
|
||||||
|
|
||||||
|
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||||
|
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void xen_set_pgd(pgd_t *ptr, pgd_t val)
|
||||||
|
{
|
||||||
|
/* If page is not pinned, we can just update the entry
|
||||||
|
directly */
|
||||||
|
if (!page_pinned(ptr)) {
|
||||||
|
*ptr = val;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xen_set_pgd_hyper(ptr, val);
|
||||||
|
}
|
||||||
|
#endif /* PAGETABLE_LEVELS == 4 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
(Yet another) pagetable walker. This one is intended for pinning a
|
(Yet another) pagetable walker. This one is intended for pinning a
|
||||||
pagetable. This means that it walks a pagetable and calls the
|
pagetable. This means that it walks a pagetable and calls the
|
||||||
|
|
|
@ -32,13 +32,24 @@ pgd_t xen_make_pgd(pgdval_t);
|
||||||
void xen_set_pte(pte_t *ptep, pte_t pteval);
|
void xen_set_pte(pte_t *ptep, pte_t pteval);
|
||||||
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
|
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||||
pte_t *ptep, pte_t pteval);
|
pte_t *ptep, pte_t pteval);
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
void xen_set_pte_atomic(pte_t *ptep, pte_t pte);
|
void xen_set_pte_atomic(pte_t *ptep, pte_t pte);
|
||||||
|
void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
|
||||||
|
void xen_pmd_clear(pmd_t *pmdp);
|
||||||
|
#endif /* CONFIG_X86_PAE */
|
||||||
|
|
||||||
void xen_set_pmd(pmd_t *pmdp, pmd_t pmdval);
|
void xen_set_pmd(pmd_t *pmdp, pmd_t pmdval);
|
||||||
void xen_set_pud(pud_t *ptr, pud_t val);
|
void xen_set_pud(pud_t *ptr, pud_t val);
|
||||||
void xen_set_pmd_hyper(pmd_t *pmdp, pmd_t pmdval);
|
void xen_set_pmd_hyper(pmd_t *pmdp, pmd_t pmdval);
|
||||||
void xen_set_pud_hyper(pud_t *ptr, pud_t val);
|
void xen_set_pud_hyper(pud_t *ptr, pud_t val);
|
||||||
void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
|
|
||||||
void xen_pmd_clear(pmd_t *pmdp);
|
#if PAGETABLE_LEVELS == 4
|
||||||
|
pudval_t xen_pud_val(pud_t pud);
|
||||||
|
pud_t xen_make_pud(pudval_t pudval);
|
||||||
|
void xen_set_pgd(pgd_t *pgdp, pgd_t pgd);
|
||||||
|
void xen_set_pgd_hyper(pgd_t *pgdp, pgd_t pgd);
|
||||||
|
#endif
|
||||||
|
|
||||||
pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
|
pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
|
||||||
void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
|
void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
|
||||||
|
|
|
@ -148,7 +148,11 @@ static inline pte_t __pte_ma(pteval_t x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define pmd_val_ma(v) ((v).pmd)
|
#define pmd_val_ma(v) ((v).pmd)
|
||||||
|
#ifdef __PAGETABLE_PUD_FOLDED
|
||||||
#define pud_val_ma(v) ((v).pgd.pgd)
|
#define pud_val_ma(v) ((v).pgd.pgd)
|
||||||
|
#else
|
||||||
|
#define pud_val_ma(v) ((v).pud)
|
||||||
|
#endif
|
||||||
#define __pmd_ma(x) ((pmd_t) { (x) } )
|
#define __pmd_ma(x) ((pmd_t) { (x) } )
|
||||||
|
|
||||||
#define pgd_val_ma(x) ((x).pgd)
|
#define pgd_val_ma(x) ((x).pgd)
|
||||||
|
|
Loading…
Reference in a new issue