On 21.12.2011, at 02:34, Scott Wood wrote: > tlbilx is the new, preferred invalidation instruction. It is not > found on e500 prior to e500mc, but there should be no harm in > supporting it on all e500. > > Based on code from Ashish Kalra <Ashish.Kalra@xxxxxxxxxxxxx>. > > Signed-off-by: Scott Wood <scottwood@xxxxxxxxxxxxx> > --- > arch/powerpc/kvm/e500.h | 1 + > arch/powerpc/kvm/e500_emulate.c | 9 ++++++ > arch/powerpc/kvm/e500_tlb.c | 52 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 62 insertions(+), 0 deletions(-) > > diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h > index f4dee55..ce3f163 100644 > --- a/arch/powerpc/kvm/e500.h > +++ b/arch/powerpc/kvm/e500.h > @@ -124,6 +124,7 @@ int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500, > int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu); > int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu); > int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb); > +int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, int rb); > int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb); > int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500); > void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500); > diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c > index c80794d..af02c18 100644 > --- a/arch/powerpc/kvm/e500_emulate.c > +++ b/arch/powerpc/kvm/e500_emulate.c > @@ -22,6 +22,7 @@ > #define XOP_TLBSX 914 > #define XOP_TLBRE 946 > #define XOP_TLBWE 978 > +#define XOP_TLBILX 18 > > int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, > unsigned int inst, int *advance) > @@ -29,6 +30,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, > int emulated = EMULATE_DONE; > int ra; > int rb; > + int rt; > > switch (get_op(inst)) { > case 31: > @@ -47,6 +49,13 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, > emulated = kvmppc_e500_emul_tlbsx(vcpu,rb); > break; > > + case XOP_TLBILX: > + ra = get_ra(inst); > + rb = get_rb(inst); > + rt = get_rt(inst); > + emulated = kvmppc_e500_emul_tlbilx(vcpu, rt, ra, rb); > + break; > + > case XOP_TLBIVAX: > ra = get_ra(inst); > rb = get_rb(inst); > diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c > index 031fd5b..121cd68 100644 > --- a/arch/powerpc/kvm/e500_tlb.c > +++ b/arch/powerpc/kvm/e500_tlb.c > @@ -631,6 +631,58 @@ int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb) > return EMULATE_DONE; > } > > +static void tlbilx_all(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, > + int pid, int rt) > +{ > + struct kvm_book3e_206_tlb_entry *tlbe; > + int tid, esel; > + > + /* invalidate all entries */ > + for (esel = 0; esel < vcpu_e500->gtlb_params[tlbsel].entries; esel++) { By dereferencing the struct inside the loop you're creating a new load on every iteration. Please use a variable for entries. > + tlbe = get_entry(vcpu_e500, tlbsel, esel); > + tid = get_tlb_tid(tlbe); > + if (rt == 0 || tid == pid) { > + inval_gtlbe_on_host(vcpu_e500, tlbsel, esel); > + kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel); > + } > + } > +} > + > +static void tlbilx_one(struct kvmppc_vcpu_e500 *vcpu_e500, int pid, > + int ra, int rb) > +{ > + int tlbsel, esel; > + gva_t ea; > + > + ea = kvmppc_get_gpr(&vcpu_e500->vcpu, rb); > + if (ra) > + ea += kvmppc_get_gpr(&vcpu_e500->vcpu, ra); > + > + for (tlbsel = 0; tlbsel < 2; tlbsel++) { > + esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, -1); > + if (esel >= 0) { > + inval_gtlbe_on_host(vcpu_e500, tlbsel, esel); > + kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel); > + break; > + } > + } > +} > + > +int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, int rb) > +{ > + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); > + int pid = get_cur_spid(vcpu); > + > + if (rt == 0 || rt == 1) { > + tlbilx_all(vcpu_e500, 0, pid, rt); > + tlbilx_all(vcpu_e500, 1, pid, rt); > + } else if (rt == 3) { too many magic constants :) Alex -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html