pv mmu fixes
Subsystems (4)
cover pv mmu fixes
The following patchset fixes pvmmu/cr3-cache for 32-bit guests.
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 1/6 KVM: pvmmu: handle ptes in highmem
Find the physical address through kmap_atomic_to_page().
arch/x86/kernel/kvm.c +18 -5
@@ -26,6 +26,7 @@#include <linux/cpu.h> #include <linux/mm.h> #include <linux/hardirq.h> +#include <linux/highmem.h> #include <asm/tlbflush.h> #include <asm/asm.h>
@@ -205,11 +206,23 @@ static void __init setup_guest_cr3_cachestatic void kvm_mmu_write (void *dest,u64 val) { -struct kvm_mmu_op_write_pte wpte = { - .header.op =KVM_MMU_OP_WRITE_PTE , - .pte_phys = (unsigned long )__pa (dest), - .pte_val = val, - }; +__u64 pte_phys; +struct kvm_mmu_op_write_pte wpte; + +#ifdef CONFIG_HIGHPTE +struct page *page; +unsigned long dst = (unsigned long ) dest; + + page =kmap_atomic_to_page (dest); + pte_phys =page_to_pfn (page); + pte_phys <<=PAGE_SHIFT ; + pte_phys += (dst & ~(PAGE_MASK )); +#else + pte_phys = (unsigned long )__pa (dest); +#endif + wpte.header.op =KVM_MMU_OP_WRITE_PTE ; + wpte.pte_val = val; + wpte.pte_phys = pte_phys;kvm_deferred_mmu_op (&wpte,sizeof wpte); }
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 2/6 KVM: pvmmu: hook set_pud for 3-level pagetables
In reply to Marcelo TosattiThe paravirt interface will export set_pud for 3-level pagetables. Hook it.
arch/x86/kernel/kvm.c +8 -4
@@ -296,15 +296,17 @@ static void kvm_pmd_clear(pmd_t *pmdp) }#endif -static void kvm_set_pgd (pgd_t *pgdp,pgd_t pgd) +static void kvm_set_pud (pud_t *pudp,pud_t pud) { -kvm_mmu_write (pgdp,pgd_val (pgd)); +kvm_mmu_write (pudp,pud_val (pud)); } -static void kvm_set_pud (pud_t *pudp,pud_t pud) +#if PAGETABLE_LEVELS ==4 +static void kvm_set_pgd (pgd_t *pgdp,pgd_t pgd) { -kvm_mmu_write (pudp,pud_val (pud)); +kvm_mmu_write (pgdp,pgd_val (pgd)); } +#endif #endif /* PAGETABLE_LEVELS >= 3 */ static void kvm_flush_tlb (void )
@@ -363,8 +365,10 @@ static void paravirt_ops_setup(void) pv_mmu_ops.pmd_clear = kvm_pmd_clear;#endif pv_mmu_ops.set_pud = kvm_set_pud; +#if PAGETABLE_LEVELS ==4 pv_mmu_ops.set_pgd = kvm_set_pgd;#endif +#endif pv_mmu_ops.flush_tlb_user = kvm_flush_tlb; pv_mmu_ops.release_pt = kvm_release_pt; pv_mmu_ops.release_pd = kvm_release_pt;
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 3/6 KVM: pvmmu: kvm_write_cr3() inline asm fix
In reply to Marcelo TosattiLet the compiler choose register placing. All we care is that "trap" value gets retained.
arch/x86/kernel/kvm.c +1 -1
@@ -138,7 +138,7 @@ static void kvm_write_cr3(unsigned long _ASM_EXTABLE(0b, 2b) : "=&r" (trap) : "n" (1UL), "n" (0UL), -"b" (cache->entry[idx].host_cr3), +"r" (cache->entry[idx].host_cr3), "m" (__force_order));if (!trap) goto out;
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 4/6 KVM: pvmmu: fix mmu_alloc_roots() typo
In reply to Marcelo TosattiSlipped through on the first patch.
arch/x86/kvm/mmu.c +1 -1
@@ -1321,7 +1321,7 @@ static void mmu_alloc_roots(struct kvm_vASSERT (!VALID_PAGE (root));if (vcpu->arch.mmu.root_level ==PT32E_ROOT_LEVEL ) {if (!is_present_pte (vcpu->arch.pdptrs[i])) { - vcpu->arch.mmu.pae_root[i] =0 ; + vcpu->arch.mmu.pae_root[j][i] =0 ;continue ; } root_gfn = vcpu->arch.pdptrs[i] >>PAGE_SHIFT ;
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 5/6 KVM: pvmmu: kvm_patch might be called after initialization
In reply to Marcelo Tosattikvm_patch might be called during module load.
arch/x86/kernel/kvm.c +1 -1
@@ -184,7 +184,7 @@ static void register_cr3_cache(void *cacwrmsrl (KVM_MSR_SET_CR3_CACHE ,__pa (&state->cr3_cache)); } -static unsigned __init kvm_patch (u8 type,u16 clobbers,void *ibuf, +static unsigned kvm_patch (u8 type,u16 clobbers,void *ibuf,unsigned long addr,unsigned len) {switch (type) {
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 6/6 KVM: pvmmu: cache pdptrs
In reply to Marcelo TosattiThe pdptrs need to be cached in addition to the shadowed root tables, so the guest walk can be done properly.
arch/x86/kvm/mmu.c +2 -2
@@ -1320,11 +1320,11 @@ static void mmu_alloc_roots(struct kvm_vASSERT (!VALID_PAGE (root));if (vcpu->arch.mmu.root_level ==PT32E_ROOT_LEVEL ) { -if (!is_present_pte (vcpu->arch.pdptrs[i])) { +if (!is_present_pte (vcpu->arch.pdptrs[j][i])) { vcpu->arch.mmu.pae_root[j][i] =0 ;continue ; } - root_gfn = vcpu->arch.pdptrs[i] >>PAGE_SHIFT ; + root_gfn = vcpu->arch.pdptrs[j][i] >>PAGE_SHIFT ; }else if (vcpu->arch.mmu.root_level ==0 ) root_gfn =0 ; sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
arch/x86/kvm/paging_tmpl.h +2 -1
@@ -136,7 +136,8 @@ walk: pte = vcpu->arch.cr3;#if PTTYPE ==64 if (!is_long_mode (vcpu)) { - pte = vcpu->arch.pdptrs[(addr >>30 ) &3 ]; + pte = vcpu->arch.pdptrs[vcpu->arch.cr3_cache_idx] + [(addr >>30 ) &3 ];if (!is_present_pte (pte)) goto not_present; --walker->level;
arch/x86/kvm/x86.c +18 -9
@@ -192,13 +192,21 @@ static void __queue_exception(struct kvm/* * Load the pae pdptrs. Return true is they are all valid. */ -int load_pdptrs (struct kvm_vcpu *vcpu,unsigned long cr3) +int load_pdptrs (struct kvm_vcpu *vcpu,unsigned long cr3,int cr3_cache_inc) {gfn_t pdpt_gfn = cr3 >>PAGE_SHIFT ;unsigned offset = ((cr3 & (PAGE_SIZE -1 )) >>5 ) <<2 ;int i;int ret; -u64 pdpte[ARRAY_SIZE (vcpu->arch.pdptrs)]; +u64 pdpte[ARRAY_SIZE (vcpu->arch.pdptrs[0 ])]; +int idx = vcpu->arch.cr3_cache_idx; + + idx++; +if (unlikely (idx >= vcpu->arch.cr3_cache_limit)) + idx =0 ; + +if (cr3_cache_inc) + vcpu->arch.cr3_cache_idx = idx;down_read (&vcpu->kvm->slots_lock); ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
@@ -215,7 +223,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, u } ret =1 ; -memcpy (vcpu->arch.pdptrs, pdpte,sizeof (vcpu->arch.pdptrs)); +memcpy (vcpu->arch.pdptrs[idx], pdpte,sizeof (vcpu->arch.pdptrs[0 ])); out:up_read (&vcpu->kvm->slots_lock);
@@ -225,7 +233,7 @@ EXPORT_SYMBOL_GPL(load_pdptrs);static bool pdptrs_changed (struct kvm_vcpu *vcpu) { -u64 pdpte[ARRAY_SIZE (vcpu->arch.pdptrs)]; +u64 pdpte[ARRAY_SIZE (vcpu->arch.pdptrs[0 ])];bool changed = true;int r;
@@ -236,7 +244,8 @@ static bool pdptrs_changed(struct kvm_vc r =kvm_read_guest (vcpu->kvm, vcpu->arch.cr3 & ~31u , pdpte,sizeof (pdpte));if (r <0 ) goto out; - changed =memcmp (pdpte, vcpu->arch.pdptrs,sizeof (pdpte)) !=0 ; + changed =memcmp (pdpte, vcpu->arch.pdptrs[vcpu->arch.cr3_cache_idx], +sizeof (pdpte)) !=0 ; out:up_read (&vcpu->kvm->slots_lock);
@@ -286,7 +295,7 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, } } else#endif -if (is_pae (vcpu) && !load_pdptrs (vcpu, vcpu->arch.cr3)) { +if (is_pae (vcpu) && !load_pdptrs (vcpu, vcpu->arch.cr3,1 )) {printk (KERN_DEBUG "set_cr0: #GP, pdptrs " "reserved bits\n" );kvm_inject_gp (vcpu,0 );
@@ -325,7 +334,7 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu,return ; } }else if (is_paging (vcpu) && !is_pae (vcpu) && (cr4 &X86_CR4_PAE ) - && !load_pdptrs (vcpu, vcpu->arch.cr3)) { + && !load_pdptrs (vcpu, vcpu->arch.cr3,1 )) {printk (KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n" );kvm_inject_gp (vcpu,0 );return ;
@@ -363,7 +372,7 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu,kvm_inject_gp (vcpu,0 );return ; } -if (is_paging (vcpu) && !load_pdptrs (vcpu, cr3)) { +if (is_paging (vcpu) && !load_pdptrs (vcpu, cr3,0 )) {printk (KERN_DEBUG "set_cr3: #GP, pdptrs " "reserved bits\n" );kvm_inject_gp (vcpu,0 );
@@ -3047,7 +3056,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4; kvm_x86_ops->set_cr4 (vcpu, sregs->cr4);if (!is_long_mode (vcpu) &&is_pae (vcpu)) -load_pdptrs (vcpu, vcpu->arch.cr3); +load_pdptrs (vcpu, vcpu->arch.cr3,1 );if (mmu_reset_needed)kvm_mmu_reset_context (vcpu);
include/asm-x86/kvm_host.h +2 -3
@@ -211,7 +211,7 @@ struct kvm_vcpu_arch {unsigned int cr3_cache_limit;unsigned long cr4;unsigned long cr8; -u64 pdptrs[4 ];/* pae */ +u64 pdptrs[KVM_CR3_CACHE_SIZE ][4 ];/* pae */ u64 shadow_efer;u64 apic_base;struct kvm_lapic *apic;/* kernel irqchip context */
@@ -433,7 +433,7 @@ void kvm_mmu_zap_all(struct kvm *kvm);unsigned int kvm_mmu_calculate_mmu_pages (struct kvm *kvm);void kvm_mmu_change_mmu_pages (struct kvm *kvm,unsigned int kvm_nr_mmu_pages); -int load_pdptrs (struct kvm_vcpu *vcpu,unsigned long cr3); +int load_pdptrs (struct kvm_vcpu *vcpu,unsigned long cr3,int cr3_cache_inc);int __emulator_write_phys (struct kvm_vcpu *vcpu,gpa_t gpa,const void *val,int bytes);
@@ -526,7 +526,6 @@ int kvm_mmu_page_fault(struct kvm_vcpu *void kvm_enable_tdp (void ); -int load_pdptrs (struct kvm_vcpu *vcpu,unsigned long cr3);int complete_pio (struct kvm_vcpu *vcpu);static inline struct kvm_mmu_page *page_header (hpa_t shadow_page)
arch/x86/kvm/svm.c +1 -1
@@ -1394,7 +1394,7 @@ static int handle_exit(struct kvm_run *k vcpu->arch.cr0 = svm->vmcb->save.cr0; vcpu->arch.cr3 = svm->vmcb->save.cr3;if (is_paging (vcpu) &&is_pae (vcpu) && !is_long_mode (vcpu)) { -if (!load_pdptrs (vcpu, vcpu->arch.cr3)) { +if (!load_pdptrs (vcpu, vcpu->arch.cr3,1 )) {kvm_inject_gp (vcpu,0 );return 1 ; }
Signature · 4 lines
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Quoted 4 lines · Marcelo Tosatti
The following patchset fixes pvmmu/cr3-cache for 32-bit guests.
Thanks. I folded the fixes into the patches they fixed, and merged everything except cr3 cache (I want to look at it again and see if I can reduce the impact a little). pvmmu branch now contains the unmerged patches.
Signature · 7 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/