>From 7e218b96dc908362afb501755f3f4b8ec530b700 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 28 Nov 2011 17:58:38 -0500 Subject: x86/paravirt/xen: Optimize pte_flags by marking it as paravirt_ident_[32|64] type. Which means that we have to use: __PV_IS_CALLEE_SAVE(_paravirt_ident_64) which requires that the pte_flags on the 'pv_mmu_ops' structure be defined as struct paravirt_callee_save. We end up using the _paravirt_ident_64 function for both baremetal and for Xen guests that have PAT disabled. For those that have pat_enabled, we end up calling xen_pte_flags. The big benefit of making the .pte_flags as struct paravirt_callee_save and making it PTE_IDENT is that while the code looks as so when compiled: ff 14 25 e8 52 c1 81 callq *0xffffffff81c152e8 That however, on baremetal and under Xen when !pat_enable ends up being patched over (by using the DEF_NATIVE macro) to be: 48 89 f8 mov %rdi,%rax 66 66 66 90 data32 data32 xchg %ax,%ax (the 32-bit version is of course different). For details refer to 'paravirt_patch_ident_64' function. The Xen version which requires pat_enable==1, ends up patched to be: call xen_pte_flags; Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/paravirt.h | 11 ++++++++++- arch/x86/include/asm/paravirt_types.h | 2 +- arch/x86/kernel/paravirt.c | 2 +- arch/x86/xen/mmu.c | 11 +++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 6533409..b113feb 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -464,7 +464,16 @@ static inline void pmd_update_defer(struct mm_struct *mm, unsigned long addr, static inline pteval_t pte_flags(pte_t pte) { - return pv_mmu_ops.pte_flags(pte) & PTE_FLAGS_MASK; + pteval_t ret; + + if (sizeof(pteval_t) > sizeof(long)) + ret = PVOP_CALLEE2(pteval_t, pv_mmu_ops.pte_flags, + pte.pte, (u64)pte.pte >> 32); + else + ret = PVOP_CALLEE1(pteval_t, pv_mmu_ops.pte_flags, + pte.pte); + + return ret & PTE_FLAGS_MASK; } static inline pte_t __pte(pteval_t val) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 86bce9d..5890cd7c 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -288,7 +288,7 @@ struct pv_mmu_ops { void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); - pteval_t (*pte_flags)(pte_t pte); + struct paravirt_callee_save pte_flags; struct paravirt_callee_save pte_val; struct paravirt_callee_save make_pte; diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 4780367..ba22188 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -462,7 +462,7 @@ struct pv_mmu_ops pv_mmu_ops = { #endif #endif /* PAGETABLE_LEVELS >= 3 */ - .pte_flags = native_pte_flags, + .pte_flags = PTE_IDENT, .pte_val = PTE_IDENT, .pgd_val = PTE_IDENT, diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 5b79048..24e275a 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1965,6 +1965,13 @@ void __init xen_ident_map_ISA(void) xen_flush_tlb(); } +#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) +/* 32-bit pagetable entries */ +#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_32) +#else +/* 64-bit pagetable entries */ +#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) +#endif static void __init xen_post_allocator_init(void) { pv_mmu_ops.set_pte = xen_set_pte; @@ -1986,7 +1993,7 @@ static void __init xen_post_allocator_init(void) #endif if (!pat_enabled) - pv_mmu_ops.pte_flags = native_pte_flags; + pv_mmu_ops.pte_flags = PTE_IDENT; #ifdef CONFIG_X86_64 SetPagePinned(virt_to_page(level3_user_vsyscall)); #endif @@ -2035,7 +2042,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .ptep_modify_prot_start = __ptep_modify_prot_start, .ptep_modify_prot_commit = __ptep_modify_prot_commit, - .pte_flags = xen_pte_flags, + .pte_flags = __PV_IS_CALLEE_SAVE(xen_pte_flags), .pte_val = PV_CALLEE_SAVE(xen_pte_val), .pgd_val = PV_CALLEE_SAVE(xen_pgd_val), -- 1.7.7.3