From mboxrd@z Thu Jan 1 00:00:00 1970 From: ehrhardt@linux.vnet.ibm.com Date: Mon, 14 Apr 2008 12:23:57 +0000 Subject: [kvm-ppc-devel] [PATCH] [2/3] kvmppc: full instruction emulation Message-Id: <12081758432822-git-send-email-ehrhardt@linux.vnet.ibm.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: kvm-ppc@vger.kernel.org From: Christian Ehrhardt This adds a relayfs based kernel interface that allows tracing of all emulated guest instructions. It is based on Hollis tracing of tlb activities. A suitable userspace program to read from that interface and a post processing script that give users a readable output follow. This feature is configurable in .config under the kvmppc virtualization itself. Signed-off-by: Christian Ehrhardt --- [diffstat] Kconfig | 9 ++++++ emulate.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ powerpc.c | 11 ++++++++ 3 files changed, 104 insertions(+) diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -49,6 +49,15 @@ config KVM_POWERPC_440_INSTRUCTION_STAT used to debug performance issues and adds a slight runtime overhead. If unsure, say N. +config KVM_POWERPC_440_TRACE_INSTRUCTIONS + bool "ppc440 instruction emulation tracing" + depends on KVM && 44x && KVM_POWERPC_440 + select RELAY + ---help--- + Adds the complete tracing of the emulated instructions via a relayfs + channel. + If unsure, say N. + config KVM_PPC_VIRTIO bool "Virtio Support" select VIRTIO diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -87,6 +88,85 @@ static inline unsigned int get_d(u32 ins static inline unsigned int get_d(u32 inst) { return inst & 0xffff; +} + +struct rchan *kvmppc_44x_instr_chan; + +struct instr_record { + u32 time; + u32 pc; + u32 instr; + u32 rsval; + u32 raval; + u32 rbval; +}; + +static void kvmppc_44x_instr_trace(const struct kvm_vcpu *vcpu) +{ + u32 inst = vcpu->arch.last_inst; + struct instr_record record = { + .time = current_kernel_time().tv_nsec, + .pc = vcpu->arch.pc, + .instr = vcpu->arch.last_inst, + .rsval = 0, + .raval = 0, + .rbval = 0, + }; + + switch (get_op(inst)) { + case 31: + switch (get_xop(inst)) { + case 131: /* wrtee */ + case 146: /* mtmsr */ + case 451: /* mtdcr */ + case 467: /* mtspr */ + record.rsval = vcpu->arch.gpr[get_rs(inst)]; + break; + case 279: /* lhzx */ + case 534: /* lwbrx */ + case 790: /* lhbrx */ + record.raval = vcpu->arch.gpr[get_ra(inst)]; + break; + case 311: /* lhzux */ + case 978: /* tlbwe */ + case 914: /* tlbsx */ + record.raval = vcpu->arch.gpr[get_ra(inst)]; + record.rbval = vcpu->arch.gpr[get_rb(inst)]; + break; + case 215: /* stbx */ + case 247: /* stbux */ + case 407: /* sthx */ + case 439: /* sthux */ + case 662: /* stwbrx */ + case 918: /* sthbrx */ + record.rsval = vcpu->arch.gpr[get_rs(inst)]; + record.raval = vcpu->arch.gpr[get_ra(inst)]; + record.rbval = vcpu->arch.gpr[get_rb(inst)]; + break; + } + break; + case 32: /* lwz */ + case 33: /* lwzu */ + case 34: /* lbz */ + case 35: /* lbzu */ + case 40: /* lhz */ + case 41: /* lhzu */ + record.raval = vcpu->arch.gpr[get_ra(inst)]; + break; + case 36: /* stw */ + case 38: /* stb */ + case 44: /* sth */ + record.rsval = vcpu->arch.gpr[get_rs(inst)]; + break; + case 37: /* stwu */ + case 39: /* stbu */ + case 45: /* sthu */ + record.raval = vcpu->arch.gpr[get_ra(inst)]; + record.rsval = vcpu->arch.gpr[get_rs(inst)]; + break; + } + + relay_write(kvmppc_44x_instr_chan, &record, sizeof(record)); } static inline void emulinstr_stat(struct kvm_vcpu *vcpu, @@ -234,6 +314,10 @@ int kvmppc_emulate_instruction(struct kv int dcrn; enum emulation_result emulated = EMULATE_DONE; int advance = 1; + +#ifdef CONFIG_KVM_POWERPC_440_TRACE_INSTRUCTIONS + kvmppc_44x_instr_trace(vcpu); +#endif switch (get_op(inst)) { case 3: /* trap */ diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -1082,6 +1082,7 @@ long kvm_arch_vm_ioctl(struct file *filp } extern struct rchan *kvmppc_44x_tlb_chan; +extern struct rchan *kvmppc_44x_instr_chan; /* * create_buf_file() callback. Creates relay file in debugfs. */ @@ -1133,6 +1134,13 @@ int kvm_arch_init(void *opaque) if (!kvmppc_44x_tlb_chan) printk("relay_open failed\n"); +#ifdef CONFIG_KVM_POWERPC_440_TRACE_INSTRUCTIONS + kvmppc_44x_instr_chan = relay_open("44x_instr", kvm_debugfs_dir, 64, + 64, &relay_callbacks, NULL); + if (!kvmppc_44x_instr_chan) + printk(KERN_ERR"relay_open failed\n"); +#endif + #ifdef CONFIG_MAGIC_SYSRQ printk("Registering kvmppc sysrq handler\n"); register_sysrq_key('V', &sysrq_kvm_op); @@ -1144,6 +1152,9 @@ void kvm_arch_exit(void) void kvm_arch_exit(void) { relay_close(kvmppc_44x_tlb_chan); +#ifdef CONFIG_KVM_POWERPC_440_TRACE_INSTRUCTIONS + relay_close(kvmppc_44x_instr_chan); +#endif } static int kvmppc_44x_init(void) ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ kvm-ppc-devel mailing list kvm-ppc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel