>From 2e16085ad8b4ecfe7e053a627a86dc24bbe04315 Mon Sep 17 00:00:00 2001
From: Feng(Eric) Liu <[EMAIL PROTECTED]>
Date: Fri, 14 Mar 2008 18:19:46 -0400
Subject: [PATCH] kvm: "kvmtrace_format" prarses the trace data outputted
by kvmtrace in binary format, and reformats it according
to the rules in the file "format" of definitions.

Signed-off-by: Feng(Eric) Liu <[EMAIL PROTECTED]>
---
 user/formats         |   28 +++++++
 user/kvmtrace_format |  212
++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 240 insertions(+), 0 deletions(-)
 create mode 100644 user/formats
 create mode 100755 user/kvmtrace_format

diff --git a/user/formats b/user/formats
new file mode 100644
index 0000000..e3b8812
--- /dev/null
+++ b/user/formats
@@ -0,0 +1,28 @@
+0x00000000  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  unknown
(0x%(event)016x)  [ 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x ]
+
+0x0001f001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  lost_records
0x%(1)08x
+0x0001f002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  wrap_buffer
0x%(1)08x
+0x0001f003  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_change
0x%(1)08x
+
+0x00021001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMENTRY     [ vcpu:pid
= 0x%(1)08x ]
+0x00021002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMEXIT      [ vcpu:pid
= 0x%(1)08x, exitcode = 0x%(2)08x, rip  = 0x%(3)08x ]
+0x00022001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  PAGE_FAULT  [ vcpu:pid
= 0x%(1)08x, errorcode = 0x%(2)08x, virt = 0x%(3)08x ]
+0x00022002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INJ_VIRQ    [ vcpu:pid
= 0x%(1)08x, vector = 0x%(2)02x ]
+0x00022003  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  REINJ_VIRQ  [ vcpu:pid
= 0x%(1)08x, vector = 0x%(2)02x ]
+0x00022004  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  IO_READ     [ vcpu:pid
= 0x%(1)08x, port = 0x%(2)04x, size = %(3)d ]
+0x00022005  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  IO_WRITE    [ vcpu:pid
= 0x%(1)08x, port = 0x%(2)04x, size = %(3)d ]
+0x00022006  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  CR_READ     [ vcpu:pid
= 0x%(1)08x, CR# = %(2)d, value = 0x%(3)08x ]
+0x00022007  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  CR_WRITE    [ vcpu:pid
= 0x%(1)08x, CR# = %(2)d, value = 0x%(3)08x ]
+0x00022008  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  DR_READ     [ vcpu:pid
= 0x%(1)08x ]
+0x00022009  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  DR_WRITE    [ vcpu:pid
= 0x%(1)08x ]
+0x0002200A  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  MSR_READ    [ vcpu:pid
= 0x%(1)08x, MSR# = 0x%(2)08x, value = 0x%(3)08x ]
+0x0002200B  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  MSR_WRITE   [ vcpu:pid
= 0x%(1)08x, MSR# = 0x%(2)08x, value = 0x%(3)08x ]
+0x0002200C  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  CPUID       [ vcpu:pid
= 0x%(1)08x, func = 0x%(2)08x, eax:ebx = 0x%(3)016x, ecx:edx =
0x%(4)016x ]
+0x0002200D  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INTR        [ vcpu:pid
= 0x%(1)08x, vector = 0x%(2)02x ]
+0x0002200E  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  NMI         [ vcpu:pid
= 0x%(1)08x ]
+0x0002200F  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  SMI         [ vcpu:pid
= 0x%(1)08x ]
+0x00022010  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  VMMCALL     [ vcpu:pid
= 0x%(1)08x, func = 0x%(2)08x ]
+0x00022011  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  HLT         [ vcpu:pid
= 0x%(1)08x ]
+0x00022012  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INVLPG      [ vcpu:pid
= 0x%(1)08x, virt = 0x%(2)08x, invlpga = %(3)d, asid = 0x%(4)02x ]
+0x00022013  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  CLTS        [ vcpu:pid
= 0x%(1)08x ]
+0x00022014  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  LMSW        [ vcpu:pid
= 0x%(1)08x, value = 0x%(2)08x ]
diff --git a/user/kvmtrace_format b/user/kvmtrace_format
new file mode 100755
index 0000000..caa5b4e
--- /dev/null
+++ b/user/kvmtrace_format
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+
+# by Mark Williamson, (C) 2004 Intel Research Cambridge
+
+# Program for reformatting trace buffer output according to
user-supplied rules
+
+import re, sys, string, signal, struct, os, getopt
+
+def usage():
+    print >> sys.stderr, \
+          "Usage: " + sys.argv[0] + """ defs-file
+          Parses trace data in binary format, as output by kvmtrace and
+          reformats it according to the rules in a file of definitions.
The
+          rules in this file should have the format ({ and } show
grouping
+          and are not part of the syntax):
+
+          {event_id}{whitespace}{text format string}
+
+          The textual format string may include format specifiers, such
as:
+            %(cpu)d, %(tsc)d, %(event)d, %(1)d, %(2)d, %(3)d, %(4)d,
%(5)d
+          [ the 'd' format specifier outputs in decimal, alternatively
'x'
+            will output in hexadecimal and 'o' will output in octal ]
+
+          Which correspond to the CPU number, event ID, timestamp
counter and
+          the 5 data fields from the trace record.  There should be one
such
+          rule for each type of event.
+          
+          Depending on your system and the volume of trace buffer data,
+          this script may not be able to keep up with the output of
kvmtrace
+          if it is piped directly.  In these circumstances you should
have
+          kvmtrace output to a file for processing off-line.
+          """
+    sys.exit(1)
+
+def read_defs(defs_file):
+    defs = {}
+    
+    fd = open(defs_file)
+
+    reg = re.compile('(\S+)\s+(\S.*)')
+
+    while True:
+        line = fd.readline()
+        if not line:
+            break
+
+        if line[0] == '#' or line[0] == '\n':
+            continue
+
+        m = reg.match(line)
+
+        if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1)
+
+        defs[str(eval(m.group(1)))] = m.group(2)
+
+    return defs
+
+def sighand(x,y):
+    global interrupted
+    interrupted = 1
+
+##### Main code
+
+mhz = 0
+
+if len(sys.argv) < 2:
+    usage()
+
+try:
+    opts, arg = getopt.getopt(sys.argv[1:], "c:" )
+
+    for opt in opts:
+        if opt[0] == '-c' : mhz = int(opt[1])
+
+except getopt.GetoptError:
+    usage()
+
+signal.signal(signal.SIGTERM, sighand)
+signal.signal(signal.SIGHUP,  sighand)
+signal.signal(signal.SIGINT,  sighand)
+
+interrupted = 0
+
+defs = read_defs(arg[0])
+
+# structure of trace record (as output by kvmtrace):
+# HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I)
+#
+# HDR consists of EVENT:28:, n_data:3:, tsc_in:1:
+# EVENT means Event ID
+# n_data means number of data (like D1, D2, ...)
+# tsc_in means TSC data exists(1) or not(0).
+# if tsc_in == 0, TSC(Q) does not exists.
+#
+# CPU ID exists on trace data of EVENT=0x0001f003
+#
+HDRREC = "I"
+TSCREC = "Q"
+D1REC  = "I"
+D2REC  = "II"
+D3REC  = "III"
+D4REC  = "IIII"
+D5REC  = "IIIII"
+
+last_tsc = [0]
+
+i=0
+
+while not interrupted:
+    try:
+        i=i+1
+        line = sys.stdin.read(struct.calcsize(HDRREC))
+        if not line:
+            break
+        event = struct.unpack(HDRREC, line)[0]
+        n_data = event >> 28 & 0x7
+        tsc_in = event >> 31
+
+        d1 = 0
+        d2 = 0
+        d3 = 0
+        d4 = 0
+        d5 = 0
+
+        tsc = 0
+
+        if tsc_in == 1:
+            line = sys.stdin.read(struct.calcsize(TSCREC))
+            if not line:
+                break
+            tsc = struct.unpack(TSCREC, line)[0]
+
+        if n_data == 1:
+            line = sys.stdin.read(struct.calcsize(D1REC))
+            if not line:
+                break
+            d1 = struct.unpack(D1REC, line)[0]
+        if n_data == 2:
+            line = sys.stdin.read(struct.calcsize(D2REC))
+            if not line:
+                break
+            (d1, d2) = struct.unpack(D2REC, line)
+        if n_data == 3:
+            line = sys.stdin.read(struct.calcsize(D3REC))
+            if not line:
+                break
+            (d1, d2, d3) = struct.unpack(D3REC, line)
+        if n_data == 4:
+            line = sys.stdin.read(struct.calcsize(D4REC))
+            if not line:
+                break
+            (d1, d2, d3, d4) = struct.unpack(D4REC, line)
+        if n_data == 5:
+            line = sys.stdin.read(struct.calcsize(D5REC))
+            if not line:
+                break
+            (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line)
+
+        # Event field is 28bit of 'uint32_t' in header, not 'long'.
+        event &= 0x0fffffff
+        if event == 0x1f003:
+            cpu = d1
+
+
+        #tsc = (tscH<<32) | tscL
+
+        #print i, tsc
+
+        if cpu >= len(last_tsc):
+            last_tsc += [0] * (cpu - len(last_tsc) + 1)
+        elif tsc < last_tsc[cpu] and tsc_in == 1:
+            print "TSC stepped backward cpu %d !  %d %d" %
(cpu,tsc,last_tsc[cpu])
+
+        # provide relative TSC
+        if last_tsc[cpu] > 0 and tsc_in == 1:
+            reltsc = tsc - last_tsc[cpu]
+        else:
+            reltsc = 0
+
+        if tsc_in == 1:
+            last_tsc[cpu] = tsc
+
+        if mhz:
+            tsc = tsc / (mhz*1000000.0)
+
+        args = {'cpu'   : cpu,
+                'tsc'   : tsc,
+                'event' : event,
+                'reltsc': reltsc,
+                '1'     : d1,
+                '2'     : d2,
+                '3'     : d3,
+                '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)]
+                    print args
+
+
+    except IOError, struct.error: sys.exit()
-- 
1.5.1


--Eric (Liu, Feng)

Attachment: 0001-kvm-kvmtrace_format-prarses-the-trace-data-output.patch
Description: 0001-kvm-kvmtrace_format-prarses-the-trace-data-output.patch

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to