[PATCH 7/9] kvm-userspace: kvmtrace_format: add ppc instruction emulation

ehrhardt
2008-07-10T10:54:43Z

This patch adds the handling of the ppc instruction emulation trace records.
Due to the fact that those are more complex than the classic "formats" file
way this patch adds a check of the event id and maps to the internal handler
function if needed (other complex trace records that might appear in future
can hook up there too).
Additionally this fixes the ppc tlb trace record definitions in the formats
file now that the revised kernel patch series is submitted.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
formats | 16 +--
kvmtrace_format | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 268 insertions(+), 24 deletions(-)

[diff]

diff --git a/user/formats b/user/formats
--- a/user/formats
+++ b/user/formats
@@ -23,13 +23,9 @@
0x00020013 %(tsc)d (+%(reltsc)8d) LMSW vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ value = 0x%(1)08x ]
0x00020014 %(tsc)d (+%(reltsc)8d) APIC_ACCESS vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ offset = 0x%(1)08x ]
0x00020015 %(tsc)d (+%(reltsc)8d) TDP_FAULT vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
-# ppc: context switch
-0x00020016 %(tsc)d (+%(reltsc)8d) CONT_SWITCH vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x
-# ppc: tlb write
-0x00020017 %(tsc)d (+%(reltsc)8d) TLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: tlb invalidate
-0x00020018 %(tsc)d (+%(reltsc)8d) TLB_INVAL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: guest TLB write
-0x00020019 %(tsc)d (+%(reltsc)8d) GTLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: shadow TLB write
-0x00020020 %(tsc)d (+%(reltsc)8d) STLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+# ppc: tlb traces
+0x00020016 GTLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+0x00020017 STLB_WRITE vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+0x00020018 STLB_INVAL vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+# ppc: instruction emulation - this type is handled more complex in kvmtrace_format, but listed to show the eventid and transported data
+#0x00020019 %(tsc)d (+%(reltsc)8d) PPC_INSTR vcpu = 0x%(vcpu)08x pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ]
diff --git a/user/kvmtrace_format b/user/kvmtrace_format
--- a/user/kvmtrace_format
+++ b/user/kvmtrace_format
@@ -58,6 +58,250 @@
def sighand(x,y):
global interrupted
interrupted = 1
+
+# ppc instruction decoding for event type 0x00020019 (PPC_INSTR)
+def get_op(instr):
+ return (instr >> 26);
+
+def get_xop(instr):
+ return (instr >> 1) & 0x3ff;
+
+def get_sprn(instr):
+ return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0)
+
+def get_dcrn(instr):
+ return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
+
+def get_tlbwe_type(instr):
+ ws = (instr >> 11) & 0x1f;
+ if ws == 0:
+ return "PAGEID"
+ elif ws == 1:
+ return "XLAT"
+ elif ws == 2:
+ return "ATTRIB"
+ else:
+ return "UNKNOWN"
+
+def get_name(instr):
+ if get_op(instr)==3:
+ return "trap"
+ elif get_op(instr)==19:
+ if get_xop(instr) == 50:
+ return "rfi"
+ else:
+ return "unknown"
+ elif get_op(instr)==31:
+ if get_xop(instr) == 83:
+ return "mfmsr"
+
+ elif get_xop(instr) == 87:
+ return "lbzx"
+
+ elif get_xop(instr) == 131:
+ return "wrtee"
+
+ elif get_xop(instr) == 146:
+ return "mtmsr"
+
+ elif get_xop(instr) == 163:
+ return "wrteei"
+
+ elif get_xop(instr) == 215:
+ return "stbx"
+
+ elif get_xop(instr) == 247:
+ return "stbux"
+
+ elif get_xop(instr) == 279:
+ return "lhzx"
+
+ elif get_xop(instr) == 311:
+ return "lhzux"
+
+ elif get_xop(instr) == 323:
+ return "mfdcr"
+
+ elif get_xop(instr) == 339:
+ return "mfspr"
+
+ elif get_xop(instr) == 407:
+ return "sthx"
+
+ elif get_xop(instr) == 439:
+ return "sthux"
+
+ elif get_xop(instr) == 451:
+ return "mtdcr"
+
+ elif get_xop(instr) == 467:
+ return "mtspr"
+
+ elif get_xop(instr) == 470:
+ return "dcbi"
+
+ elif get_xop(instr) == 534:
+ return "lwbrx"
+
+ elif get_xop(instr) == 566:
+ return "tlbsync"
+
+ elif get_xop(instr) == 662:
+ return "stwbrx"
+
+ elif get_xop(instr) == 978:
+ return "tlbwe"
+
+ elif get_xop(instr) == 914:
+ return "tlbsx"
+
+ elif get_xop(instr) == 790:
+ return "lhbrx"
+
+ elif get_xop(instr) == 918:
+ return "sthbrx"
+
+ elif get_xop(instr) == 966:
+ return "iccci"
+
+ else:
+ return "unknown"
+
+ elif get_op(instr) == 32:
+ return "lwz"
+
+ elif get_op(instr) == 33:
+ return "lwzu"
+
+ elif get_op(instr) == 34:
+ return "lbz"
+
+ elif get_op(instr) == 35:
+ return "lbzu"
+
+ elif get_op(instr) == 36:
+ return "stw"
+
+ elif get_op(instr) == 37:
+ return "stwu"
+
+ elif get_op(instr) == 38:
+ return "stb"
+
+ elif get_op(instr) == 39:
+ return "stbu"
+
+ elif get_op(instr) == 40:
+ return "lhz"
+
+ elif get_op(instr) == 41:
+ return "lhzu"
+
+ elif get_op(instr) == 44:
+ return "sth"
+
+ elif get_op(instr) == 45:
+ return "sthu"
+
+ else:
+ return "unknown"
+
+def get_sprn_name(sprn):
+ if sprn == 0x01a:
+ return "SRR0"
+ elif sprn == 0x01b:
+ return "SRR1"
+ elif sprn == 0x3b2:
+ return "MMUCR"
+ elif sprn == 0x030:
+ return "PID"
+ elif sprn == 0x03f:
+ return "IVPR"
+ elif sprn == 0x3b3:
+ return "CCR0"
+ elif sprn == 0x378:
+ return "CCR1"
+ elif sprn == 0x11f:
+ return "PVR"
+ elif sprn == 0x03d:
+ return "DEAR"
+ elif sprn == 0x03e:
+ return "ESR"
+ elif sprn == 0x134:
+ return "DBCR0"
+ elif sprn == 0x135:
+ return "DBCR1"
+ elif sprn == 0x11c:
+ return "TBWL"
+ elif sprn == 0x11d:
+ return "TBWU"
+ elif sprn == 0x016:
+ return "DEC"
+ elif sprn == 0x150:
+ return "TSR"
+ elif sprn == 0x154:
+ return "TCR"
+ elif sprn == 0x110:
+ return "SPRG0"
+ elif sprn == 0x111:
+ return "SPRG1"
+ elif sprn == 0x112:
+ return "SPRG2"
+ elif sprn == 0x113:
+ return "SPRG3"
+ elif sprn == 0x114:
+ return "SPRG4"
+ elif sprn == 0x115:
+ return "SPRG5"
+ elif sprn == 0x116:
+ return "SPRG6"
+ elif sprn == 0x117:
+ return "SPRG7"
+ elif sprn == 0x190:
+ return "IVOR0"
+ elif sprn == 0x191:
+ return "IVOR1"
+ elif sprn == 0x192:
+ return "IVOR2"
+ elif sprn == 0x193:
+ return "IVOR3"
+ elif sprn == 0x194:
+ return "IVOR4"
+ elif sprn == 0x195:
+ return "IVOR5"
+ elif sprn == 0x196:
+ return "IVOR6"
+ elif sprn == 0x197:
+ return "IVOR7"
+ elif sprn == 0x198:
+ return "IVOR8"
+ elif sprn == 0x199:
+ return "IVOR9"
+ elif sprn == 0x19a:
+ return "IVOR10"
+ elif sprn == 0x19b:
+ return "IVOR11"
+ elif sprn == 0x19c:
+ return "IVOR12"
+ elif sprn == 0x19d:
+ return "IVOR13"
+ elif sprn == 0x19e:
+ return "IVOR14"
+ elif sprn == 0x19f:
+ return "IVOR15"
+ else:
+ return "UNKNOWN"
+
+def get_special(instr):
+ if get_op(instr) == 31:
+ if (get_xop(instr) == 339) or (get_xop(instr) == 467):
+ sprn = get_sprn(instr);
+ return ("- sprn 0x%03x %8s" % (sprn, get_sprn_name(sprn)))
+ elif (get_xop(instr) == 323 ) or (get_xop(instr) == 451):
+ return ("- dcrn 0x%03x" % get_dcrn(instr))
+ elif (get_xop(instr) == 978 ) or (get_xop(instr) == 451):
+ return ("- ws -> %8s" % get_tlbwe_type(instr))
+ return ""

##### Main code

@@ -206,20 +450,24 @@
'4' : d4,
'5' : d5 }

- try:
-
- if defs.has_key(str(event)):
- print defs[str(event)] % args
- else:
- if defs.has_key(str(0)): print defs[str(0)] % args
- except TypeError:
- if defs.has_key(str(event)):
- print defs[str(event)]
- print args
- else:
- if defs.has_key(str(0)):
- print defs[str(0)]
+ # some event types need more than just formats mapping they are if/elif
+ # chained here and the last default else is the mapping via formats
+ if event == 0x00020019:
+ pdata = (tsc, reltsc, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1))
+ print "%d (+%12d) PPC_INSTR vcpu = 0x%08x pid = 0x%08x [ instr = 0x%08x, pc = 0x%08x, emul = %01d, mnemonic = %8s %s" % pdata
+ else:
+ try:
+ if defs.has_key(str(event)):
+ print defs[str(event)] % args
+ else:
+ if defs.has_key(str(0)): print defs[str(0)] % args
+ except TypeError:
+ if defs.has_key(str(event)):
+ print defs[str(event)]
print args
-
+ else:
+ if defs.has_key(str(0)):
+ print defs[str(0)]
+ print args

except IOError, struct.error: sys.exit()