ppc patch queue 2013-02-15
Subsystems (3)
Hi Marcelo / Gleb,
This is my current patch queue for ppc. Please pull.
Highlights of this queue drop are:
- BookE: Fast mapping support for 4k backed memory
- BookE: Handle alignment interrupts
Alex
The following changes since commit cbd29cb6e38af6119df2cdac0c58acf0e85c177e:
Jan Kiszka (1):
KVM: nVMX: Remove redundant get_vmcs12 from nested_vmx_exit_handled_msr
are available in the git repository at:
git://github.com/agraf/linux-2.6.git kvm-ppc-next
Alexander Graf (11):
KVM: PPC: E500: Move write_stlbe higher
KVM: PPC: E500: Explicitly mark shadow maps invalid
KVM: PPC: E500: Propagate errors when shadow mapping
KVM: PPC: e500: Call kvmppc_mmu_map for initial mapping
KVM: PPC: E500: Split host and guest MMU parts
KVM: PPC: e500: Implement TLB1-in-TLB0 mapping
KVM: PPC: E500: Make clear_tlb_refs and clear_tlb1_bitmap static
KVM: PPC: E500: Remove kvmppc_e500_tlbil_all usage from guest TLB code Merge commit 'origin/next' into kvm-ppc-next
KVM: PPC: BookE: Handle alignment interrupts
Merge commit 'origin/next' into kvm-ppc-next
Bharat Bhushan (3):
KVM: PPC: booke: use vcpu reference from thread_struct
KVM: PPC: booke: Allow multiple exception types
booke: Added DBCR4 SPR number
arch/powerpc/include/asm/kvm_ppc.h | 2 - arch/powerpc/include/asm/reg.h | 2 - arch/powerpc/include/asm/reg_booke.h | 1 + arch/powerpc/kernel/asm-offsets.c | 2 +- arch/powerpc/kvm/Makefile | 9 +- arch/powerpc/kvm/booke.c | 30 +- arch/powerpc/kvm/booke.h | 1 + arch/powerpc/kvm/booke_interrupts.S | 49 +- arch/powerpc/kvm/e500.c | 16 +- arch/powerpc/kvm/e500.h | 1 + arch/powerpc/kvm/e500_mmu.c | 809 +++++++++++++++++++ arch/powerpc/kvm/e500_mmu_host.c | 699 +++++++++++++++++ arch/powerpc/kvm/e500_mmu_host.h | 18 + arch/powerpc/kvm/e500_tlb.c | 1430 ---------------------------------- 14 files changed, 1610 insertions(+), 1459 deletions(-) create mode 100644 arch/powerpc/kvm/e500_mmu.c create mode 100644 arch/powerpc/kvm/e500_mmu_host.c create mode 100644 arch/powerpc/kvm/e500_mmu_host.h delete mode 100644 arch/powerpc/kvm/e500_tlb.c
PATCH 1/12 KVM: PPC: E500: Move write_stlbe higher
Later patches want to call the function and it doesn't have dependencies on anything below write_host_tlbe.
Move it higher up in the file.
--- arch/powerpc/kvm/e500_tlb.c | 32 ++++++++++++++++---------------- 1 files changed, 16 insertions(+), 16 deletions(-)
arch/powerpc/kvm/e500_tlb.c +16 -16
@@ -156,6 +156,22 @@ static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500, } } +/* sesel is for tlb1 only */ +static void write_stlbe (struct kvmppc_vcpu_e500 *vcpu_e500, +struct kvm_book3e_206_tlb_entry *gtlbe, +struct kvm_book3e_206_tlb_entry *stlbe, +int stlbsel,int sesel) +{ +int stid; + +preempt_disable (); + stid =kvmppc_e500_get_tlb_stid (&vcpu_e500->vcpu, gtlbe); + + stlbe->mas1 |=MAS1_TID (stid); +write_host_tlbe (vcpu_e500, stlbsel, sesel, stlbe); +preempt_enable (); +} +#ifdef CONFIG_KVM_E500V2 void kvmppc_map_magic (struct kvm_vcpu *vcpu) {
@@ -834,22 +850,6 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, gva_t ea)return EMULATE_DONE ; } -/* sesel is for tlb1 only */ -static void write_stlbe (struct kvmppc_vcpu_e500 *vcpu_e500, -struct kvm_book3e_206_tlb_entry *gtlbe, -struct kvm_book3e_206_tlb_entry *stlbe, -int stlbsel,int sesel) -{ -int stid; - -preempt_disable (); - stid =kvmppc_e500_get_tlb_stid (&vcpu_e500->vcpu, gtlbe); - - stlbe->mas1 |=MAS1_TID (stid); -write_host_tlbe (vcpu_e500, stlbsel, sesel, stlbe); -preempt_enable (); -} -int kvmppc_e500_emul_tlbwe (struct kvm_vcpu *vcpu) {struct kvmppc_vcpu_e500 *vcpu_e500 =to_e500 (vcpu);
Signature · 1 line
1.6.0.2
PATCH 2/12 KVM: PPC: E500: Explicitly mark shadow maps invalid
In reply to Alexander GrafWhen we invalidate shadow TLB maps on the host, we don't mark them as not valid. But we should.
Fix this by removing the E500_TLB_VALID from their flags when invalidating.
--- arch/powerpc/kvm/e500_tlb.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-)
arch/powerpc/kvm/e500_tlb.c +10 -3
@@ -204,9 +204,13 @@ static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, { struct kvm_book3e_206_tlb_entry *gtlbe get_entry(vcpu_e500, tlbsel, esel); +struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; -if (tlbsel =1 && - vcpu_e500->gtlb_priv[1 ][esel].ref.flags &E500_TLB_BITMAP ) { +/* Don't bother with unmapped entries */ +if (!(ref->flags &E500_TLB_VALID )) +return ; + +if (tlbsel =1 && ref->flags &E500_TLB_BITMAP ) {u64 tmp = vcpu_e500->g2h_tlb1_map[esel];int hw_tlb_indx;unsigned long flags;
@@ -224,7 +228,7 @@ static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, }mb (); vcpu_e500->g2h_tlb1_map[esel] =0 ; - vcpu_e500->gtlb_priv[1 ][esel].ref.flags &= ~E500_TLB_BITMAP ; + ref->flags &= ~(E500_TLB_BITMAP |E500_TLB_VALID );local_irq_restore (flags);return ;
@@ -232,6 +236,9 @@ static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500,/* Guest tlbe is backed by at most one host tlbe per shadow pid. */ kvmppc_e500_tlbil_one (vcpu_e500, gtlbe); + +/* Mark the TLB as not backed by the host anymore */ + ref->flags &= ~E500_TLB_VALID ; }static int tlb0_set_base (gva_t addr,int sets,int ways)
Signature · 1 line
1.6.0.2
Re: [PATCH 02/12] KVM: PPC: E500: Explicitly mark shadow maps invalid
Quoted 17 lines · Alexander Graf
When we invalidate shadow TLB maps on the host, we don't mark them as not valid. But we should.
Fix this by removing the
E500_TLB_VALIDfrom their flags when invalidating.Signed-off-by Alexander Graf <[email protected]>--- arch/powerpc/kvm/e500_tlb.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-)arch/powerpc/kvm/e500_tlb.c +0
-0@@ -204,9 +204,13 @@ static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500,
arch/powerpc/kvm/e500_tlb.c static void inval_gtlbe_on_host(struct · line 212
Quoted 10 lines
arch/powerpc/kvm/e500_tlb.c +4
-2{struct kvm_book3e_206_tlb_entry *gtlbe =get_entry (vcpu_e500, tlbsel, esel); +struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; -if (tlbsel ==1 && - vcpu_e500->gtlb_priv[1 ][esel].ref.flags &E500_TLB_BITMAP ) { +/* Don't bother with unmapped entries */ +if (!(ref->flags &E500_TLB_VALID )) +return ;
This is broken as pointed out here:
http://patchwork.ozlabs.org/patch/220356/
...and note that I'm still seeing problems even after that fix, which I'll try to debug today.
-Scott
PATCH 3/12 KVM: PPC: E500: Propagate errors when shadow mapping
In reply to Alexander GrafWhen shadow mapping a page, mapping this page can fail. In that case we don't have a shadow map.
Take this case into account, otherwise we might end up writing bogus TLB entries into the host TLB.
While at it, also move the write_stlbe() calls into the respective TLBn handlers.
--- arch/powerpc/kvm/e500_tlb.c | 69 +++++++++++++++++++++++++----------------- 1 files changed, 41 insertions(+), 28 deletions(-)
arch/powerpc/kvm/e500_tlb.c +41 -28
@@ -432,7 +432,7 @@ static inline void kvmppc_e500_setup_stlbe(#endif } -static inline void kvmppc_e500_shadow_map (struct kvmppc_vcpu_e500 *vcpu_e500, +static inline int kvmppc_e500_shadow_map (struct kvmppc_vcpu_e500 *vcpu_e500,u64 gvaddr,gfn_t gfn,struct kvm_book3e_206_tlb_entry *gtlbe,int tlbsel,struct kvm_book3e_206_tlb_entry *stlbe,struct tlbe_ref *ref)
@@ -551,7 +551,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,if (is_error_noslot_pfn (pfn)) {printk (KERN_ERR "Couldn't get real page for gfn %lx!\n" , (long )gfn); -return ; +return -EINVAL ; }/* Align guest and physical address to page map boundaries */
@@ -571,22 +571,33 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,/* Drop refcount on page, so that mmu notifiers can clear it */ kvm_release_pfn_clean (pfn); + +return 0 ; }/* XXX only map the one-one case, for now use TLB0 */ -static void kvmppc_e500_tlb0_map (struct kvmppc_vcpu_e500 *vcpu_e500, -int esel, -struct kvm_book3e_206_tlb_entry *stlbe) +static int kvmppc_e500_tlb0_map (struct kvmppc_vcpu_e500 *vcpu_e500, +int esel, +struct kvm_book3e_206_tlb_entry *stlbe) {struct kvm_book3e_206_tlb_entry *gtlbe;struct tlbe_ref *ref; +int stlbsel =0 ; +int sesel =0 ; +int r; gtlbe =get_entry (vcpu_e500,0 , esel); ref = &vcpu_e500->gtlb_priv[0 ][esel].ref; -kvmppc_e500_shadow_map (vcpu_e500,get_tlb_eaddr (gtlbe), + r =kvmppc_e500_shadow_map (vcpu_e500,get_tlb_eaddr (gtlbe),get_tlb_raddr (gtlbe) >>PAGE_SHIFT , gtlbe,0 , stlbe, ref); +if (r) +return r; + +write_stlbe (vcpu_e500, gtlbe, stlbe, stlbsel, sesel); + +return 0 ; }/* Caller must ensure that the specified guest TLB entry is safe to insert into
@@ -597,25 +608,32 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, struct kvm_book3e_206_tlb_entry *stlbe, int esel) {struct tlbe_ref *ref; -unsigned int victim; +unsigned int sesel; +int r; +int stlbsel =1 ; - victim = vcpu_e500->host_tlb1_nv++; + sesel = vcpu_e500->host_tlb1_nv++;if (unlikely (vcpu_e500->host_tlb1_nv >=tlb1_max_shadow_size ())) vcpu_e500->host_tlb1_nv =0 ; - ref = &vcpu_e500->tlb_refs[1 ][victim]; -kvmppc_e500_shadow_map (vcpu_e500, gvaddr, gfn, gtlbe,1 , stlbe, ref); + ref = &vcpu_e500->tlb_refs[1 ][sesel]; + r =kvmppc_e500_shadow_map (vcpu_e500, gvaddr, gfn, gtlbe,1 , stlbe, + ref); +if (r) +return r; - vcpu_e500->g2h_tlb1_map[esel] |= (u64 )1 << victim; + vcpu_e500->g2h_tlb1_map[esel] |= (u64 )1 << sesel; vcpu_e500->gtlb_priv[1 ][esel].ref.flags |=E500_TLB_BITMAP ; -if (vcpu_e500->h2g_tlb1_rmap[victim]) { -unsigned int idx = vcpu_e500->h2g_tlb1_rmap[victim]; - vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << victim); +if (vcpu_e500->h2g_tlb1_rmap[sesel]) { +unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel]; + vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel); } - vcpu_e500->h2g_tlb1_rmap[victim] = esel; + vcpu_e500->h2g_tlb1_rmap[sesel] = esel; -return victim; +write_stlbe (vcpu_e500, gtlbe, stlbe, stlbsel, sesel); + +return 0 ; }static void kvmppc_recalc_tlb1map_range (struct kvmppc_vcpu_e500 *vcpu_e500)
@@ -1034,30 +1052,27 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,struct kvm_book3e_206_tlb_entry *gtlbe, stlbe;int tlbsel =tlbsel_of (index);int esel =esel_of (index); -int stlbsel, sesel; gtlbe =get_entry (vcpu_e500, tlbsel, esel);switch (tlbsel) {case 0 : - stlbsel =0 ; - sesel =0 ;/* unused */ priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; -/* Only triggers after clear_tlb_refs */ -if (unlikely (!(priv->ref.flags &E500_TLB_VALID ))) +/* Triggers after clear_tlb_refs or on initial mapping */ +if (!(priv->ref.flags &E500_TLB_VALID )) {kvmppc_e500_tlb0_map (vcpu_e500, esel, &stlbe); -else + }else {kvmppc_e500_setup_stlbe (vcpu, gtlbe,BOOK3E_PAGESZ_4K , &priv->ref, eaddr, &stlbe); +write_stlbe (vcpu_e500, gtlbe, &stlbe,0 ,0 ); + }break ;case 1 : {gfn_t gfn = gpaddr >>PAGE_SHIFT ; - - stlbsel =1 ; - sesel =kvmppc_e500_tlb1_map (vcpu_e500, eaddr, gfn, - gtlbe, &stlbe, esel); +kvmppc_e500_tlb1_map (vcpu_e500, eaddr, gfn, gtlbe, &stlbe, + esel);break ; }
@@ -1065,8 +1080,6 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,BUG ();break ; } - -write_stlbe (vcpu_e500, gtlbe, &stlbe, stlbsel, sesel); }/************* MMU Notifiers *************/
Signature · 1 line
1.6.0.2
PATCH 4/12 KVM: PPC: e500: Call kvmppc_mmu_map for initial mapping
In reply to Alexander GrafWhen emulating tlbwe, we want to automatically map the entry that just got written in our shadow TLB map, because chances are quite high that it's going to be used very soon.
Today this happens explicitly, duplicating all the logic that is in kvmppc_mmu_map() already. Just call that one instead.
--- arch/powerpc/kvm/e500_tlb.c | 38 +++++++------------------------------- 1 files changed, 7 insertions(+), 31 deletions(-)
arch/powerpc/kvm/e500_tlb.c +7 -31
@@ -878,8 +878,8 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, gva_t ea)int kvmppc_e500_emul_tlbwe (struct kvm_vcpu *vcpu) {struct kvmppc_vcpu_e500 *vcpu_e500 =to_e500 (vcpu); -struct kvm_book3e_206_tlb_entry *gtlbe, stlbe; -int tlbsel, esel, stlbsel, sesel; +struct kvm_book3e_206_tlb_entry *gtlbe; +int tlbsel, esel;int recal =0 ; tlbsel =get_tlb_tlbsel (vcpu);
@@ -917,40 +917,16 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)/* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ if (tlbe_is_host_safe (vcpu, gtlbe)) { -u64 eaddr; -u64 raddr; +u64 eaddr =get_tlb_eaddr (gtlbe); +u64 raddr =get_tlb_raddr (gtlbe); -switch (tlbsel) { -case 0 : -/* TLB0 */ +if (tlbsel ==0 ) { gtlbe->mas1 &= ~MAS1_TSIZE (~0 ); gtlbe->mas1 |=MAS1_TSIZE (BOOK3E_PAGESZ_4K ); - - stlbsel =0 ; -kvmppc_e500_tlb0_map (vcpu_e500, esel, &stlbe); - sesel =0 ;/* unused */ - -break ; - -case 1 : -/* TLB1 */ - eaddr =get_tlb_eaddr (gtlbe); - raddr =get_tlb_raddr (gtlbe); - -/* Create a 4KB mapping on the host. -* If the guest wanted a large page, -* only the first 4KB is mapped here and the rest -* are mapped on the fly. */ - stlbsel =1 ; - sesel =kvmppc_e500_tlb1_map (vcpu_e500, eaddr, - raddr >>PAGE_SHIFT , gtlbe, &stlbe, esel); -break ; - -default : -BUG (); } -write_stlbe (vcpu_e500, gtlbe, &stlbe, stlbsel, sesel); +/* Premap the faulting page */ +kvmppc_mmu_map (vcpu, eaddr, raddr,index_of (tlbsel, esel)); }kvmppc_set_exit_type (vcpu,EMULATED_TLBWE_EXITS );
Signature · 1 line
1.6.0.2
PATCH 5/12 KVM: PPC: E500: Split host and guest MMU parts
In reply to Alexander GrafThis patch splits the file e500_tlb.c into e500_mmu.c (guest TLB handling) and e500_mmu_host.c (host TLB handling).
The main benefit of this split is readability and maintainability. It's just a lot harder to write dirty code :).
--- arch/powerpc/kvm/Makefile | 9 +- arch/powerpc/kvm/e500_mmu.c | 811 ++++++++++++++++++++++ arch/powerpc/kvm/e500_mmu_host.c | 672 ++++++++++++++++++ arch/powerpc/kvm/e500_mmu_host.h | 20 + arch/powerpc/kvm/e500_tlb.c | 1426 -------------------------------------- 5 files changed, 1509 insertions(+), 1429 deletions(-) create mode 100644 arch/powerpc/kvm/e500_mmu.c create mode 100644 arch/powerpc/kvm/e500_mmu_host.c create mode 100644 arch/powerpc/kvm/e500_mmu_host.h delete mode 100644 arch/powerpc/kvm/e500_tlb.c
arch/powerpc/kvm/Makefile +6 -3
@@ -10,7 +10,8 @@ common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o \ eventfd.o) CFLAGS_44x_tlb.o := -I. -CFLAGS_e500_tlb.o := -I. +CFLAGS_e500_mmu.o := -I. +CFLAGS_e500_mmu_host.o := -I. CFLAGS_emulate.o := -I. common-objs-y += powerpc.o emulate.o
@@ -35,7 +36,8 @@ kvm-e500-objs := \ booke_emulate.o \ booke_interrupts.o \ e500.o \ - e500_tlb.o \ + e500_mmu.o \ + e500_mmu_host.o \ e500_emulate.o kvm-objs-$(CONFIG_KVM_E500V2) := $(kvm-e500-objs)
@@ -45,7 +47,8 @@ kvm-e500mc-objs := \ booke_emulate.o \ bookehv_interrupts.o \ e500mc.o \ - e500_tlb.o \ + e500_mmu.o \ + e500_mmu_host.o \ e500_emulate.o kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs)
arch/powerpc/kvm/e500_mmu.c new file +811 -0
811 lines not on this page · raw message
arch/powerpc/kvm/e500_mmu_host.c new file +672 -0
672 lines not on this page · raw message
arch/powerpc/kvm/e500_mmu_host.h new file +20 -0
@@ -0,0 +1,20 @@ +/* +* Copyright (C) 2008-2013 Freescale Semiconductor, Inc. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License, version 2, as +* published by the Free Software Foundation. +*/ + +#ifndef KVM_E500_MMU_HOST_H +#define KVM_E500_MMU_HOST_H + +void inval_gtlbe_on_host (struct kvmppc_vcpu_e500 *vcpu_e500,int tlbsel, +int esel); + +void clear_tlb1_bitmap (struct kvmppc_vcpu_e500 *vcpu_e500); +void clear_tlb_refs (struct kvmppc_vcpu_e500 *vcpu_e500); +int e500_mmu_host_init (struct kvmppc_vcpu_e500 *vcpu_e500); +void e500_mmu_host_uninit (struct kvmppc_vcpu_e500 *vcpu_e500); + +#endif /* KVM_E500_MMU_HOST_H */
arch/powerpc/kvm/e500_tlb.c deleted +0 -1426
1,426 lines not on this page · raw message
Signature · 1 line
1.6.0.2
PATCH 6/12 KVM: PPC: e500: Implement TLB1-in-TLB0 mapping
In reply to Alexander GrafWhen a host mapping fault happens in a guest TLB1 entry today, we map the translated guest entry into the host's TLB1.
This isn't particularly clever when the guest is mapped by normal 4k pages, since these would be a lot better to put into TLB0 instead.
This patch adds the required logic to map 4k TLB1 shadow maps into the host's TLB0.
--- arch/powerpc/kvm/e500.h | 1 + arch/powerpc/kvm/e500_mmu_host.c | 65 +++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 19 deletions(-)
arch/powerpc/kvm/e500.h +1 -0
@@ -28,6 +28,7 @@#define E500_TLB_VALID 1#define E500_TLB_BITMAP 2 +#define E500_TLB_TLB0 (1 << 2)struct tlbe_ref {pfn_t pfn;
arch/powerpc/kvm/e500_mmu_host.c +46 -19
94 lines not on this page · raw message
Signature · 1 line
1.6.0.2
PATCH 7/12 KVM: PPC: E500: Make clear_tlb_refs and clear_tlb1_bitmap static
In reply to Alexander GrafHost shadow TLB flushing is logic that the guest TLB code should have no insight about. Declare the internal clear_tlb_refs and clear_tlb1_bitmap functions static to the host TLB handling file.
Instead of these, we can use the already exported kvmppc_core_flush_tlb(). This gives us a common API across the board to say "please flush any pending host shadow translation".
--- arch/powerpc/kvm/e500_mmu.c | 6 ++---- arch/powerpc/kvm/e500_mmu_host.c | 4 ++-- arch/powerpc/kvm/e500_mmu_host.h | 2 -- 3 files changed, 4 insertions(+), 8 deletions(-)
arch/powerpc/kvm/e500_mmu.c +2 -4
@@ -541,10 +541,8 @@ static void free_gtlb(struct kvmppc_vcpu_e500 *vcpu_e500) {int i; -clear_tlb1_bitmap (vcpu_e500); +kvmppc_core_flush_tlb (&vcpu_e500->vcpu);kfree (vcpu_e500->g2h_tlb1_map); - -clear_tlb_refs (vcpu_e500);kfree (vcpu_e500->gtlb_priv[0 ]);kfree (vcpu_e500->gtlb_priv[1 ]);
@@ -735,7 +733,7 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu, {struct kvmppc_vcpu_e500 *vcpu_e500 =to_e500 (vcpu);kvmppc_recalc_tlb1map_range (vcpu_e500); -clear_tlb_refs (vcpu_e500); +kvmppc_core_flush_tlb (vcpu);return 0 ; }
arch/powerpc/kvm/e500_mmu_host.c +2 -2
@@ -262,7 +262,7 @@ static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) } } -void clear_tlb1_bitmap (struct kvmppc_vcpu_e500 *vcpu_e500) +static void clear_tlb1_bitmap (struct kvmppc_vcpu_e500 *vcpu_e500) {if (vcpu_e500->g2h_tlb1_map) memset(vcpu_e500->g2h_tlb1_map, 0,
@@ -284,7 +284,7 @@ static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) } } -void clear_tlb_refs (struct kvmppc_vcpu_e500 *vcpu_e500) +static void clear_tlb_refs (struct kvmppc_vcpu_e500 *vcpu_e500) {int stlbsel =1 ;int i;
arch/powerpc/kvm/e500_mmu_host.h +0 -2
@@ -12,8 +12,6 @@void inval_gtlbe_on_host (struct kvmppc_vcpu_e500 *vcpu_e500,int tlbsel,int esel); -void clear_tlb1_bitmap (struct kvmppc_vcpu_e500 *vcpu_e500); -void clear_tlb_refs (struct kvmppc_vcpu_e500 *vcpu_e500);int e500_mmu_host_init (struct kvmppc_vcpu_e500 *vcpu_e500);void e500_mmu_host_uninit (struct kvmppc_vcpu_e500 *vcpu_e500);
Signature · 1 line
1.6.0.2
PATCH 8/12 KVM: PPC: E500: Remove kvmppc_e500_tlbil_all usage from guest TLB code
In reply to Alexander GrafThe guest TLB handling code should not have any insight into how the host TLB shadow code works.
kvmppc_e500_tlbil_all() is a function that is used for distinction between e500v2 and e500mc (E.HV) on how to flush shadow entries. This function really is private between the e500.c/e500mc.c file and e500_mmu_host.c.
Instead of this one, use the public kvmppc_core_flush_tlb() function to flush all shadow TLB entries. As a nice side effect, with this we also end up flushing TLB1 entries which we forgot to do before.
--- arch/powerpc/kvm/e500_mmu.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
arch/powerpc/kvm/e500_mmu.c +4 -4
@@ -239,8 +239,8 @@ int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500, ulong value)for (esel =0 ; esel < vcpu_e500->gtlb_params[1 ].entries; esel++)kvmppc_e500_gtlbe_invalidate (vcpu_e500,1 , esel); -/* Invalidate all vcpu id mappings */ -kvmppc_e500_tlbil_all (vcpu_e500); +/* Invalidate all host shadow mappings */ +kvmppc_core_flush_tlb (&vcpu_e500->vcpu);return EMULATE_DONE ; }
@@ -269,8 +269,8 @@ int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, gva_t ea)kvmppc_e500_gtlbe_invalidate (vcpu_e500, tlbsel, esel); } -/* Invalidate all vcpu id mappings */ -kvmppc_e500_tlbil_all (vcpu_e500); +/* Invalidate all host shadow mappings */ +kvmppc_core_flush_tlb (&vcpu_e500->vcpu);return EMULATE_DONE ; }
Signature · 1 line
1.6.0.2
PATCH 9/12 KVM: PPC: booke: use vcpu reference from thread_struct
In reply to Alexander GrafFrom: Bharat Bhushan <[email protected]>
Like other places, use thread_struct to get vcpu reference.
--- arch/powerpc/include/asm/reg.h | 2 -- arch/powerpc/kernel/asm-offsets.c | 2 +- arch/powerpc/kvm/booke_interrupts.S | 6 ++---- 3 files changed, 3 insertions(+), 7 deletions(-)
arch/powerpc/include/asm/reg.h +0 -2
@@ -919,8 +919,6 @@#define SPRN_SPRG_RSCRATCH_DBG SPRN_SPRG9#define SPRN_SPRG_WSCRATCH_DBG SPRN_SPRG9#endif -#define SPRN_SPRG_RVCPU SPRN_SPRG1 -#define SPRN_SPRG_WVCPU SPRN_SPRG1#endif #ifdef CONFIG_8xx
arch/powerpc/kernel/asm-offsets.c +1 -1
@@ -117,7 +117,7 @@ int main(void)#ifdef CONFIG_KVM_BOOK3S_32_HANDLER DEFINE (THREAD_KVM_SVCPU , offsetof(struct thread_struct , kvm_shadow_vcpu));#endif -#ifdef CONFIG_KVM_BOOKE_HV +#if defined(CONFIG_KVM ) && defined(CONFIG_BOOKE )DEFINE (THREAD_KVM_VCPU , offsetof(struct thread_struct , kvm_vcpu));#endif
arch/powerpc/kvm/booke_interrupts.S +2 -4
@@ -56,7 +56,8 @@ _GLOBAL(kvmppc_handler_\ivor_nr) /* Get pointer to vcpu and record exit number. */ mtspr \scratch , r4 - mfspr r4, SPRN_SPRG_RVCPU + mfspr r4, SPRN_SPRG_THREAD + lwz r4, THREAD_KVM_VCPU(r4) stw r3, VCPU_GPR(R3)(r4) stw r5, VCPU_GPR(R5)(r4) stw r6, VCPU_GPR(R6)(r4)
@@ -402,9 +403,6 @@ lightweight_exit: lwz r8, kvmppc_booke_handlers@l(r8) mtspr SPRN_IVPR, r8 - /* Save vcpu pointer for the exception handlers. */ - mtspr SPRN_SPRG_WVCPU, r4 - lwz r5, VCPU_SHARED(r4) /* Can't switch the stack pointer until after IVPR is switched,
Signature · 1 line
1.6.0.2
PATCH 10/12 KVM: PPC: booke: Allow multiple exception types
In reply to Alexander GrafFrom: Bharat Bhushan <[email protected]>
Current kvmppc_booke_handlers uses the same macro (KVM_HANDLER) and all handlers are considered to be the same size. This will not be the case if we want to use different macros for different handlers.
This patch improves the kvmppc_booke_handler so that it can support different macros for different handlers.
--- arch/powerpc/include/asm/kvm_ppc.h | 2 - arch/powerpc/kvm/booke.c | 14 ++++++++---- arch/powerpc/kvm/booke.h | 1 + arch/powerpc/kvm/booke_interrupts.S | 37 ++++++++++++++++++++++++++++++++-- arch/powerpc/kvm/e500.c | 16 +++++++++----- 5 files changed, 54 insertions(+), 16 deletions(-)
arch/powerpc/include/asm/kvm_ppc.h +0 -2
@@ -49,8 +49,6 @@ enum emulation_result {extern int kvmppc_vcpu_run (struct kvm_run *kvm_run,struct kvm_vcpu *vcpu);extern int __kvmppc_vcpu_run (struct kvm_run *kvm_run,struct kvm_vcpu *vcpu); -extern char kvmppc_handlers_start[]; -extern unsigned long kvmppc_handler_len;extern void kvmppc_handler_highmem (void );extern void kvmppc_dump_vcpu (struct kvm_vcpu *vcpu);
arch/powerpc/kvm/booke.c +9 -5
@@ -1594,7 +1594,9 @@ int __init kvmppc_booke_init(void) {#ifndef CONFIG_KVM_BOOKE_HV unsigned long ivor[16 ]; +unsigned long *handler = kvmppc_booke_handler_addr;unsigned long max_ivor =0 ; +unsigned long handler_len;int i;/* We install our own exception handlers by hijacking IVPR. IVPR must
@@ -1627,14 +1629,16 @@ int __init kvmppc_booke_init(void)for (i =0 ; i <16 ; i++) {if (ivor[i] > max_ivor) - max_ivor = ivor[i]; + max_ivor = i; + handler_len = handler[i +1 ] - handler[i];memcpy ((void *)kvmppc_booke_handlers + ivor[i], - kvmppc_handlers_start + i * kvmppc_handler_len, - kvmppc_handler_len); + (void *)handler[i], handler_len); } -flush_icache_range (kvmppc_booke_handlers, - kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); + + handler_len = handler[max_ivor +1 ] - handler[max_ivor]; +flush_icache_range (kvmppc_booke_handlers, kvmppc_booke_handlers + + ivor[max_ivor] + handler_len);#endif /* !BOOKE_HV */ return 0 ; }
arch/powerpc/kvm/booke.h +1 -0
@@ -65,6 +65,7 @@ (1 << BOOKE_IRQPRIO_CRITICAL))extern unsigned long kvmppc_booke_handlers; +extern unsigned long kvmppc_booke_handler_addr[];void kvmppc_set_msr (struct kvm_vcpu *vcpu,u32 new_msr);void kvmppc_mmu_msr_notify (struct kvm_vcpu *vcpu,u32 old_msr);
arch/powerpc/kvm/booke_interrupts.S +34 -3
@@ -74,6 +74,14 @@ _GLOBAL(kvmppc_handler_\ivor_nr) bctr .endm +.macro KVM_HANDLER_ADDR ivor_nr + .long kvmppc_handler_\ivor_nr +.endm + +.macro KVM_HANDLER_END + .long kvmppc_handlers_end +.endm + _GLOBAL(kvmppc_handlers_start) KVM_HANDLER BOOKE_INTERRUPT_CRITICAL SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_MACHINE_CHECK SPRN_SPRG_RSCRATCH_MC SPRN_MCSRR0
@@ -94,9 +102,7 @@ KVM_HANDLER BOOKE_INTERRUPT_DEBUG SPRN_SPRG_RSCRATCH_CRIT SPRN_CSRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA SPRN_SPRG_RSCRATCH0 SPRN_SRR0 KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND SPRN_SPRG_RSCRATCH0 SPRN_SRR0 - -_GLOBAL(kvmppc_handler_len) - .long kvmppc_handler_1 - kvmppc_handler_0 +_GLOBAL(kvmppc_handlers_end) /* Registers: * SPRG_SCRATCH0: guest r4
@@ -461,6 +467,31 @@ lightweight_exit: lwz r4, VCPU_GPR(R4)(r4) rfi + .data + .align 4 + .globl kvmppc_booke_handler_addr +kvmppc_booke_handler_addr: +KVM_HANDLER_ADDR BOOKE_INTERRUPT_CRITICAL +KVM_HANDLER_ADDR BOOKE_INTERRUPT_MACHINE_CHECK +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DATA_STORAGE +KVM_HANDLER_ADDR BOOKE_INTERRUPT_INST_STORAGE +KVM_HANDLER_ADDR BOOKE_INTERRUPT_EXTERNAL +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ALIGNMENT +KVM_HANDLER_ADDR BOOKE_INTERRUPT_PROGRAM +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FP_UNAVAIL +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SYSCALL +KVM_HANDLER_ADDR BOOKE_INTERRUPT_AP_UNAVAIL +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DECREMENTER +KVM_HANDLER_ADDR BOOKE_INTERRUPT_FIT +KVM_HANDLER_ADDR BOOKE_INTERRUPT_WATCHDOG +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DTLB_MISS +KVM_HANDLER_ADDR BOOKE_INTERRUPT_ITLB_MISS +KVM_HANDLER_ADDR BOOKE_INTERRUPT_DEBUG +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_UNAVAIL +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_DATA +KVM_HANDLER_ADDR BOOKE_INTERRUPT_SPE_FP_ROUND +KVM_HANDLER_END /*Always keep this in end*/ + #ifdef CONFIG_SPE _GLOBAL(kvmppc_save_guest_spe) cmpi 0,r3,0
arch/powerpc/kvm/e500.c +10 -6
@@ -491,6 +491,9 @@ static int __init kvmppc_e500_init(void) {int r, i;unsigned long ivor[3 ]; +/* Process remaining handlers above the generic first 16 */ +unsigned long *handler = &kvmppc_booke_handler_addr[16 ]; +unsigned long handler_len;unsigned long max_ivor =0 ; r =kvmppc_core_check_processor_compat ();
@@ -506,15 +509,16 @@ static int __init kvmppc_e500_init(void) ivor[1 ] =mfspr (SPRN_IVOR33 ); ivor[2 ] =mfspr (SPRN_IVOR34 );for (i =0 ; i <3 ; i++) { -if (ivor[i] > max_ivor) - max_ivor = ivor[i]; +if (ivor[i] > ivor[max_ivor]) + max_ivor = i; + handler_len = handler[i +1 ] - handler[i];memcpy ((void *)kvmppc_booke_handlers + ivor[i], - kvmppc_handlers_start + (i +16 ) * kvmppc_handler_len, - kvmppc_handler_len); + (void *)handler[i], handler_len); } -flush_icache_range (kvmppc_booke_handlers, - kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); + handler_len = handler[max_ivor +1 ] - handler[max_ivor]; +flush_icache_range (kvmppc_booke_handlers, kvmppc_booke_handlers + + ivor[max_ivor] + handler_len);return kvm_init (NULL ,sizeof (struct kvmppc_vcpu_e500 ),0 ,THIS_MODULE ); }
Signature · 1 line
1.6.0.2
PATCH 11/12 booke: Added DBCR4 SPR number
In reply to Alexander GrafFrom: Bharat Bhushan <[email protected]>
--- arch/powerpc/include/asm/reg_booke.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/powerpc/include/asm/reg_booke.h +1 -0
@@ -56,6 +56,7 @@#define SPRN_SPRG7W 0x117/* Special Purpose Register General 7 Write */ #define SPRN_EPCR 0x133/* Embedded Processor Control Register */ #define SPRN_DBCR2 0x136/* Debug Control Register 2 */ +#define SPRN_DBCR4 0x233/* Debug Control Register 4 */ #define SPRN_MSRP 0x137/* MSR Protect Register */ #define SPRN_IAC3 0x13A/* Instruction Address Compare 3 */ #define SPRN_IAC4 0x13B/* Instruction Address Compare 4 */
Signature · 1 line
1.6.0.2
PATCH 12/12 KVM: PPC: BookE: Handle alignment interrupts
In reply to Alexander GrafWhen the guest triggers an alignment interrupt, we don't handle it properly today and instead BUG_ON(). This really shouldn't happen.
Instead, we should just pass the interrupt back into the guest so it can deal with it.
--- arch/powerpc/kvm/booke.c | 16 +++++++++++++++- arch/powerpc/kvm/booke_interrupts.S | 6 ++++-- 2 files changed, 19 insertions(+), 3 deletions(-)
arch/powerpc/kvm/booke.c +15 -1
@@ -182,6 +182,14 @@ static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,kvmppc_booke_queue_irqprio (vcpu,BOOKE_IRQPRIO_INST_STORAGE ); } +static void kvmppc_core_queue_alignment (struct kvm_vcpu *vcpu,ulong dear_flags, +ulong esr_flags) +{ + vcpu->arch.queued_dear = dear_flags; + vcpu->arch.queued_esr = esr_flags; +kvmppc_booke_queue_irqprio (vcpu,BOOKE_IRQPRIO_ALIGNMENT ); +} +void kvmppc_core_queue_program (struct kvm_vcpu *vcpu,ulong esr_flags) { vcpu->arch.queued_esr = esr_flags;
@@ -345,6 +353,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,switch (priority) {case BOOKE_IRQPRIO_DTLB_MISS :case BOOKE_IRQPRIO_DATA_STORAGE : +case BOOKE_IRQPRIO_ALIGNMENT : update_dear = true;/* fall through */ case BOOKE_IRQPRIO_INST_STORAGE :
@@ -358,7 +367,6 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,case BOOKE_IRQPRIO_SPE_FP_DATA :case BOOKE_IRQPRIO_SPE_FP_ROUND :case BOOKE_IRQPRIO_AP_UNAVAIL : -case BOOKE_IRQPRIO_ALIGNMENT : allowed =1 ; msr_mask =MSR_CE |MSR_ME |MSR_DE ; int_class =INT_CLASS_NONCRIT ;
@@ -971,6 +979,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, r =RESUME_GUEST ;break ; +case BOOKE_INTERRUPT_ALIGNMENT : +kvmppc_core_queue_alignment (vcpu, vcpu->arch.fault_dear, + vcpu->arch.fault_esr); + r =RESUME_GUEST ; +break ; +#ifdef CONFIG_KVM_BOOKE_HV case BOOKE_INTERRUPT_HV_SYSCALL :if (!(vcpu->arch.shared->msr &MSR_PR )) {
arch/powerpc/kvm/booke_interrupts.S +4 -2
@@ -45,12 +45,14 @@ (1<<BOOKE_INTERRUPT_DEBUG)) #define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ - (1<<BOOKE_INTERRUPT_DTLB_MISS)) + (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ + (1<<BOOKE_INTERRUPT_ALIGNMENT)) #define NEED_ESR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \ (1<<BOOKE_INTERRUPT_INST_STORAGE) | \ (1<<BOOKE_INTERRUPT_PROGRAM) | \ - (1<<BOOKE_INTERRUPT_DTLB_MISS)) + (1<<BOOKE_INTERRUPT_DTLB_MISS) | \ + (1<<BOOKE_INTERRUPT_ALIGNMENT)) .macro KVM_HANDLER ivor_nr scratch srr0 _GLOBAL(kvmppc_handler_\ivor_nr)
Signature · 1 line
1.6.0.2
Pulled, thanks.
Quoted 61 lines · Alexander Graf
Hi Marcelo / Gleb,
This is my current patch queue for ppc. Please pull.
Highlights of this queue drop are:
- BookE: Fast mapping support for 4k backed memory
- BookE: Handle alignment interruptsAlex
The following changes since commit
cbd29cb6e38af6119df2cdac0c58acf0e85c177e:
Jan Kiszka (1):
KVM: nVMX: Remove redundantget_vmcs12fromnested_vmx_exit_handled_msrare available in the git repository at:
git://github.com/agraf/linux-2.6.gitkvm-ppc-nextAlexander Graf (11):
KVM: PPC: E500: Movewrite_stlbehigher
KVM: PPC: E500: Explicitly mark shadow maps invalid
KVM: PPC: E500: Propagate errors when shadow mapping
KVM: PPC: e500: Callkvmppc_mmu_mapfor initial mapping
KVM: PPC: E500: Split host and guest MMU parts
KVM: PPC: e500: Implement TLB1-in-TLB0 mapping
KVM: PPC: E500: Makeclear_tlb_refsandclear_tlb1_bitmapstatic
KVM: PPC: E500: Removekvmppc_e500_tlbil_allusage from guest TLB code Merge commit 'origin/next' into kvm-ppc-next
KVM: PPC: BookE: Handle alignment interrupts
Merge commit 'origin/next' into kvm-ppc-nextBharat Bhushan (3):
KVM: PPC: booke: use vcpu reference fromthread_struct
KVM: PPC: booke: Allow multiple exception types
booke: Added DBCR4 SPR numberarch/powerpc/include/asm/kvm_ppc.h | 2 - arch/powerpc/include/asm/reg.h | 2 - arch/powerpc/include/asm/reg_booke.h | 1 + arch/powerpc/kernel/asm-offsets.c | 2 +- arch/powerpc/kvm/Makefile | 9 +- arch/powerpc/kvm/booke.c | 30 +- arch/powerpc/kvm/booke.h | 1 + arch/powerpc/kvm/booke_interrupts.S | 49 +- arch/powerpc/kvm/e500.c | 16 +- arch/powerpc/kvm/e500.h | 1 + arch/powerpc/kvm/e500_mmu.c | 809 +++++++++++++++++++ arch/powerpc/kvm/e500_mmu_host.c | 699 +++++++++++++++++ arch/powerpc/kvm/e500_mmu_host.h | 18 + arch/powerpc/kvm/e500_tlb.c | 1430 ---------------------------------- 14 files changed, 1610 insertions(+), 1459 deletions(-) create mode 100644 arch/powerpc/kvm/e500_mmu.c create mode 100644 arch/powerpc/kvm/e500_mmu_host.c create mode 100644 arch/powerpc/kvm/e500_mmu_host.h delete mode 100644 arch/powerpc/kvm/e500_tlb.c--
To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html