* [kvm-ppc-devel] [PATCH] [2/3] kvmppc: full instruction emulation
@ 2008-04-14 12:23 ehrhardt
0 siblings, 0 replies; only message in thread
From: ehrhardt @ 2008-04-14 12:23 UTC (permalink / raw)
To: kvm-ppc
From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
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 <ehrhardt@linux.vnet.ibm.com>
---
[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 <linux/timer.h>
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/relay.h>
#include <linux/kvm_host.h>
#include <asm/dcr.h>
@@ -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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-04-14 12:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-14 12:23 [kvm-ppc-devel] [PATCH] [2/3] kvmppc: full instruction emulation ehrhardt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.