Some work such as TLB put/load on E500 is not necessary at every process switch, which may take place frequently when host workload is heavy.
This patch add a refresh interface for powerpc. These kind of work can use it to refresh at vcpu switch. Signed-off-by: Liu Yu <yu....@freescale.com> --- arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/kvm/e500.c | 7 +++++-- arch/powerpc/kvm/e500_tlb.c | 10 ++++------ arch/powerpc/kvm/e500_tlb.h | 3 +-- arch/powerpc/kvm/powerpc.c | 9 +++++++++ 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 82547c8..ac155a0 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -76,6 +76,7 @@ extern int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu); extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu); +extern void kvmppc_core_vcpu_refresh(struct kvm_vcpu *vcpu, int cpu); extern void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu); extern void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index d0cdb06..13dfd46 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -34,12 +34,15 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { - kvmppc_e500_tlb_load(vcpu, cpu); } void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) { - kvmppc_e500_tlb_put(vcpu); +} + +void kvmppc_core_vcpu_refresh(struct kvm_vcpu *vcpu, int cpu) +{ + kvmppc_e500_tlb_refresh(vcpu, cpu); } int kvmppc_core_check_processor_compat(void) diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index a5858e6..29c8c09 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c @@ -129,11 +129,14 @@ static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500, local_irq_enable(); } -void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu) +void kvmppc_e500_tlb_refresh(struct kvm_vcpu *vcpu, int cpu) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); int i; unsigned register mas0; + + _tlbia(); + /* Mark every guest entry in the shadow TLB entry modified, so that they * will all be reloaded on the next vcpu run (instead of being * demand-faulted). */ @@ -152,11 +155,6 @@ void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu) local_irq_enable(); } -void kvmppc_e500_tlb_put(struct kvm_vcpu *vcpu) -{ - _tlbia(); -} - /* Search the guest TLB for a matching entry. */ static int e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500, gva_t eaddr, int tlbsel, unsigned int pid, int as) diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h index fed42e5..61e2ac4 100644 --- a/arch/powerpc/kvm/e500_tlb.h +++ b/arch/powerpc/kvm/e500_tlb.h @@ -48,8 +48,7 @@ extern int kvmppc_e500_emul_tlbre(struct kvm_vcpu *); extern int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *, int, int); extern int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *, int); extern int kvmppc_e500_tlb_search(struct kvm_vcpu *, gva_t, int); -extern void kvmppc_e500_tlb_put(struct kvm_vcpu *); -extern void kvmppc_e500_tlb_load(struct kvm_vcpu *, int); +extern void kvmppc_e500_tlb_refresh(struct kvm_vcpu *, int); extern int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *); extern void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *); extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *); diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index fd84d9c..a7a92e7 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -30,6 +30,8 @@ #include <asm/tlbflush.h> #include "timing.h" +static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu) = NULL; + gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) { return gfn; @@ -215,6 +217,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) { kvmppc_mmu_destroy(vcpu); + __get_cpu_var(last_vcpu) = NULL; } void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) @@ -223,6 +226,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvmppc_core_load_guest_debugstate(vcpu); kvmppc_core_vcpu_load(vcpu, cpu); + + /* Refresh work can be done only when switch vcpu */ + if (__get_cpu_var(last_vcpu) != vcpu) { + kvmppc_core_vcpu_refresh(vcpu, cpu); + __get_cpu_var(last_vcpu) = vcpu; + } } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) -- 1.5.4 -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html