From: Christian Ehrhardt <ehrhardt@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxx> --- [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() -- 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