On Tue, 2009-09-29 at 10:18 +0200, Alexander Graf wrote: > Little opcodes behave differently on desktop and embedded PowerPC cores. > In order to reflect those differences, let's add some #ifdef code to emulate.c. > > We could probably also handle them in the core specific emulation files, but I > would prefer to reuse as much code as possible. > > Signed-off-by: Alexander Graf <agraf@xxxxxxx> > --- > arch/powerpc/kvm/emulate.c | 30 ++++++++++++++++++++++++++++++ > 1 files changed, 30 insertions(+), 0 deletions(-) > > diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c > index 50d411d..665fa83 100644 > --- a/arch/powerpc/kvm/emulate.c > +++ b/arch/powerpc/kvm/emulate.c > @@ -32,6 +32,7 @@ > #include "trace.h" > > #define OP_TRAP 3 > +#define OP_TRAP_64 2 > > #define OP_31_XOP_LWZX 23 > #define OP_31_XOP_LBZX 87 > @@ -68,7 +69,19 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu) > { > unsigned long nr_jiffies; > > +#ifdef CONFIG_PPC64 > +#ifdef DEBUG_EMUL > + printk(KERN_INFO "mtDEC: %x\n", vcpu->arch.dec); > +#endif > + /* POWER4+ triggers a dec interrupt if the value is < 0 */ > + if (vcpu->arch.dec & 0x80000000) { > + del_timer(&vcpu->arch.dec_timer); > + kvmppc_core_queue_dec(vcpu); > + } > + else if (true) { > +#else > if (vcpu->arch.tcr & TCR_DIE) { > +#endif > /* The decrementer ticks at the same rate as the timebase, so > * that's how we convert the guest DEC value to the number of > * host ticks. */ Ifdefs through the middle of control syntax makes my head hurt. :) Instead, let's do this: #ifdef CONFIG_PPC64 static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu) { return 1; } #else static int kvmppc_dec_enabled(struct kvm_vcpu *vcpu) { return vcpu->arch.tcr & TCR_DIE; } #endif Then kvmppc_emulate_dec() becomes: #ifdef CONFIG_PPC64 /* POWER4+ triggers a dec interrupt if the value is < 0 */ if (vcpu->arch.dec & 0x80000000) { del_timer(&vcpu->arch.dec_timer); kvmppc_core_queue_dec(vcpu); goto out; } #endif if (kvmppc_dec_enabled(vcpu)) { ... out: } > @@ -113,9 +126,16 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) > /* this default type might be overwritten by subcategories */ > kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); > > +#ifdef DEBUG_EMUL > + printk(KERN_INFO "Emulating opcode %d / %d\n", get_op(inst), get_xop(inst)); > +#endif We definitely need to use pr_debug() here. (All over, not just this patch.) > switch (get_op(inst)) { > case OP_TRAP: > +#ifdef CONFIG_PPC64 > + case OP_TRAP_64: > +#else > vcpu->arch.esr |= ESR_PTR; > +#endif > kvmppc_core_queue_program(vcpu); > advance = 0; > break; > @@ -189,6 +209,13 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) > vcpu->arch.gpr[rt] = vcpu->arch.srr0; break; > case SPRN_SRR1: > vcpu->arch.gpr[rt] = vcpu->arch.srr1; break; > +#ifdef CONFIG_PPC64 > + case SPRN_PVR: > + vcpu->arch.gpr[rt] = vcpu->arch.pvr; break; > + case SPRN_PIR: > + case SPRN_MSSSR0: > + vcpu->arch.gpr[rt] = 0; break; > +#else > case SPRN_PVR: > vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break; > case SPRN_PIR: Let's not split the PVR handling here. As discussed elsewhere, ppc32 should also use vcpu->arch.pvr. (Obviously you can't test that part, but just make the code right and we'll sort it out.) Better idea for PIR: return vcpu->vcpu_id. > @@ -201,6 +228,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) > vcpu->arch.gpr[rt] = mftbl(); break; > case SPRN_TBWU: > vcpu->arch.gpr[rt] = mftbu(); break; > +#endif > > case SPRN_SPRG0: > vcpu->arch.gpr[rt] = vcpu->arch.sprg0; break; > @@ -271,6 +299,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) > case SPRN_TBWL: break; > case SPRN_TBWU: break; > > + case SPRN_MSSSR0: break; > + > case SPRN_DEC: > vcpu->arch.dec = vcpu->arch.gpr[rs]; > kvmppc_emulate_dec(vcpu); -- Hollis Blanchard IBM Linux Technology Center -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html