* [patch 0/6] pv mmu fixes
@ 2008-03-17 12:19 Marcelo Tosatti
2008-03-17 12:19 ` [patch 1/6] KVM: pvmmu: handle ptes in highmem Marcelo Tosatti
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel
The following patchset fixes pvmmu/cr3-cache for 32-bit guests.
--
-------------------------------------------------------------------------
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/
^ permalink raw reply [flat|nested] 8+ messages in thread* [patch 1/6] KVM: pvmmu: handle ptes in highmem 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti @ 2008-03-17 12:19 ` Marcelo Tosatti 2008-03-17 12:19 ` [patch 2/6] KVM: pvmmu: hook set_pud for 3-level pagetables Marcelo Tosatti ` (5 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm-devel, Marcelo Tosatti [-- Attachment #1: kvm-mmu-highpte --] [-- Type: text/plain, Size: 1434 bytes --] Find the physical address through kmap_atomic_to_page(). Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Index: kvm.first/arch/x86/kernel/kvm.c =================================================================== --- kvm.first.orig/arch/x86/kernel/kvm.c +++ kvm.first/arch/x86/kernel/kvm.c @@ -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_cache static 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); } -- ------------------------------------------------------------------------- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch 2/6] KVM: pvmmu: hook set_pud for 3-level pagetables 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti 2008-03-17 12:19 ` [patch 1/6] KVM: pvmmu: handle ptes in highmem Marcelo Tosatti @ 2008-03-17 12:19 ` Marcelo Tosatti 2008-03-17 12:19 ` [patch 3/6] KVM: pvmmu: kvm_write_cr3() inline asm fix Marcelo Tosatti ` (4 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm-devel, Marcelo Tosatti [-- Attachment #1: kvm-fix-32 --] [-- Type: text/plain, Size: 1445 bytes --] The paravirt interface will export set_pud for 3-level pagetables. Hook it. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Index: kvm.first/arch/x86/kernel/kvm.c =================================================================== --- kvm.first.orig/arch/x86/kernel/kvm.c +++ kvm.first/arch/x86/kernel/kvm.c @@ -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; -- ------------------------------------------------------------------------- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch 3/6] KVM: pvmmu: kvm_write_cr3() inline asm fix 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti 2008-03-17 12:19 ` [patch 1/6] KVM: pvmmu: handle ptes in highmem Marcelo Tosatti 2008-03-17 12:19 ` [patch 2/6] KVM: pvmmu: hook set_pud for 3-level pagetables Marcelo Tosatti @ 2008-03-17 12:19 ` Marcelo Tosatti 2008-03-17 12:19 ` [patch 4/6] KVM: pvmmu: fix mmu_alloc_roots() typo Marcelo Tosatti ` (3 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm-devel, Marcelo Tosatti [-- Attachment #1: cr3-register --] [-- Type: text/plain, Size: 843 bytes --] Let the compiler choose register placing. All we care is that "trap" value gets retained. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Index: kvm.first/arch/x86/kernel/kvm.c =================================================================== --- kvm.first.orig/arch/x86/kernel/kvm.c +++ kvm.first/arch/x86/kernel/kvm.c @@ -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; -- ------------------------------------------------------------------------- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch 4/6] KVM: pvmmu: fix mmu_alloc_roots() typo 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti ` (2 preceding siblings ...) 2008-03-17 12:19 ` [patch 3/6] KVM: pvmmu: kvm_write_cr3() inline asm fix Marcelo Tosatti @ 2008-03-17 12:19 ` Marcelo Tosatti 2008-03-17 12:19 ` [patch 5/6] KVM: pvmmu: kvm_patch might be called after initialization Marcelo Tosatti ` (2 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm-devel, Marcelo Tosatti [-- Attachment #1: fix-mmu-alloc-roots --] [-- Type: text/plain, Size: 849 bytes --] Slipped through on the first patch. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Index: kvm.first/arch/x86/kvm/mmu.c =================================================================== --- kvm.first.orig/arch/x86/kvm/mmu.c +++ kvm.first/arch/x86/kvm/mmu.c @@ -1321,7 +1321,7 @@ static void mmu_alloc_roots(struct kvm_v ASSERT(!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; -- ------------------------------------------------------------------------- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch 5/6] KVM: pvmmu: kvm_patch might be called after initialization 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti ` (3 preceding siblings ...) 2008-03-17 12:19 ` [patch 4/6] KVM: pvmmu: fix mmu_alloc_roots() typo Marcelo Tosatti @ 2008-03-17 12:19 ` Marcelo Tosatti 2008-03-17 12:19 ` [patch 6/6] KVM: pvmmu: cache pdptrs Marcelo Tosatti 2008-03-17 14:46 ` [patch 0/6] pv mmu fixes Avi Kivity 6 siblings, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm-devel, Marcelo Tosatti [-- Attachment #1: fix-cr3-cache --] [-- Type: text/plain, Size: 837 bytes --] kvm_patch might be called during module load. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Index: kvm.first/arch/x86/kernel/kvm.c =================================================================== --- kvm.first.orig/arch/x86/kernel/kvm.c +++ kvm.first/arch/x86/kernel/kvm.c @@ -184,7 +184,7 @@ static void register_cr3_cache(void *cac wrmsrl(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) { -- ------------------------------------------------------------------------- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch 6/6] KVM: pvmmu: cache pdptrs 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti ` (4 preceding siblings ...) 2008-03-17 12:19 ` [patch 5/6] KVM: pvmmu: kvm_patch might be called after initialization Marcelo Tosatti @ 2008-03-17 12:19 ` Marcelo Tosatti 2008-03-17 14:46 ` [patch 0/6] pv mmu fixes Avi Kivity 6 siblings, 0 replies; 8+ messages in thread From: Marcelo Tosatti @ 2008-03-17 12:19 UTC (permalink / raw) To: Avi Kivity; +Cc: kvm-devel, Marcelo Tosatti [-- Attachment #1: cache-pdptrs --] [-- Type: text/plain, Size: 6425 bytes --] The pdptrs need to be cached in addition to the shadowed root tables, so the guest walk can be done properly. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Index: kvm.first/arch/x86/kvm/mmu.c =================================================================== --- kvm.first.orig/arch/x86/kvm/mmu.c +++ kvm.first/arch/x86/kvm/mmu.c @@ -1320,11 +1320,11 @@ static void mmu_alloc_roots(struct kvm_v ASSERT(!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, Index: kvm.first/arch/x86/kvm/paging_tmpl.h =================================================================== --- kvm.first.orig/arch/x86/kvm/paging_tmpl.h +++ kvm.first/arch/x86/kvm/paging_tmpl.h @@ -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; Index: kvm.first/arch/x86/kvm/x86.c =================================================================== --- kvm.first.orig/arch/x86/kvm/x86.c +++ kvm.first/arch/x86/kvm/x86.c @@ -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); Index: kvm.first/include/asm-x86/kvm_host.h =================================================================== --- kvm.first.orig/include/asm-x86/kvm_host.h +++ kvm.first/include/asm-x86/kvm_host.h @@ -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) Index: kvm.first/arch/x86/kvm/svm.c =================================================================== --- kvm.first.orig/arch/x86/kvm/svm.c +++ kvm.first/arch/x86/kvm/svm.c @@ -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; } -- ------------------------------------------------------------------------- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch 0/6] pv mmu fixes 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti ` (5 preceding siblings ...) 2008-03-17 12:19 ` [patch 6/6] KVM: pvmmu: cache pdptrs Marcelo Tosatti @ 2008-03-17 14:46 ` Avi Kivity 6 siblings, 0 replies; 8+ messages in thread From: Avi Kivity @ 2008-03-17 14:46 UTC (permalink / raw) To: Marcelo Tosatti; +Cc: kvm-devel Marcelo Tosatti wrote: > 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. -- 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/ ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-03-17 14:46 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-03-17 12:19 [patch 0/6] pv mmu fixes Marcelo Tosatti 2008-03-17 12:19 ` [patch 1/6] KVM: pvmmu: handle ptes in highmem Marcelo Tosatti 2008-03-17 12:19 ` [patch 2/6] KVM: pvmmu: hook set_pud for 3-level pagetables Marcelo Tosatti 2008-03-17 12:19 ` [patch 3/6] KVM: pvmmu: kvm_write_cr3() inline asm fix Marcelo Tosatti 2008-03-17 12:19 ` [patch 4/6] KVM: pvmmu: fix mmu_alloc_roots() typo Marcelo Tosatti 2008-03-17 12:19 ` [patch 5/6] KVM: pvmmu: kvm_patch might be called after initialization Marcelo Tosatti 2008-03-17 12:19 ` [patch 6/6] KVM: pvmmu: cache pdptrs Marcelo Tosatti 2008-03-17 14:46 ` [patch 0/6] pv mmu fixes Avi Kivity
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox