>From c22da0fa5b09ea7b9e6045a660eb1782afc5200a Mon Sep 17 00:00:00 2001
From: Feng(Eric) Liu <[EMAIL PROTECTED]>
Date: Thu, 10 Apr 2008 09:34:20 -0400
Subject: [PATCH] kvm: "kvmtrace_format" parses the binary trace data
from kvmtrace, and
reformats it according to the rules in the file "formats" of
definitions.

Signed-off-by: Feng (Eric) Liu <[EMAIL PROTECTED]>
---
 user/formats         |   24 ++++++
 user/kvmtrace_format |  200
++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 224 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..5313a47
--- /dev/null
+++ b/user/formats
@@ -0,0 +1,24 @@
+0x00000000  %(tsc)d (+%(reltsc)8d)  unknown (0x%(event)016x) vcpu =
0x%(vcpu)08x  pid = 0x%(pid)08x [ 0x%(1)08x 0x%(2)08x 0x%(3)08x
0x%(4)08x 0x%(5)08x ]
+
+0x00010001  %(tsc)d (+%(reltsc)8d)  VMENTRY       vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x
+0x00010002  %(tsc)d (+%(reltsc)8d)  VMEXIT        vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ exitcode = 0x%(1)08x, rip = 0x%(3)08x %(2)08x ]
+0x00020001  %(tsc)d (+%(reltsc)8d)  PAGE_FAULT    vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
+0x00020002  %(tsc)d (+%(reltsc)8d)  INJ_VIRQ      vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x00020003  %(tsc)d (+%(reltsc)8d)  REDELIVER_EVT vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x00020004  %(tsc)d (+%(reltsc)8d)  PEND_INTR     vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x00020005  %(tsc)d (+%(reltsc)8d)  IO_READ       vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
+0x00020006  %(tsc)d (+%(reltsc)8d)  IO_WRITE      vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
+0x00020007  %(tsc)d (+%(reltsc)8d)  CR_READ       vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
+0x00020008  %(tsc)d (+%(reltsc)8d)  CR_WRITE      vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
+0x00020009  %(tsc)d (+%(reltsc)8d)  DR_READ       vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
+0x0002000A  %(tsc)d (+%(reltsc)8d)  DR_WRITE      vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
+0x0002000B  %(tsc)d (+%(reltsc)8d)  MSR_READ      vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
+0x0002000C  %(tsc)d (+%(reltsc)8d)  MSR_WRITE     vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
+0x0002000D  %(tsc)d (+%(reltsc)8d)  CPUID         vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ func = 0x%(1)08x, eax = 0x%(2)08x, ebx = 0x%(3)08x,
ecx = 0x%(4)08x edx = 0x%(5)08x]
+0x0002000E  %(tsc)d (+%(reltsc)8d)  INTR          vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x0002000F  %(tsc)d (+%(reltsc)8d)  NMI           vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x
+0x00020010  %(tsc)d (+%(reltsc)8d)  VMMCALL       vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x [ func = 0x%(1)08x ]
+0x00020011  %(tsc)d (+%(reltsc)8d)  HLT           vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x
+0x00020012  %(tsc)d (+%(reltsc)8d)  CLTS          vcpu = 0x%(vcpu)08x
pid = 0x%(pid)08x
+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 ]
diff --git a/user/kvmtrace_format b/user/kvmtrace_format
new file mode 100755
index 0000000..9e7cfd4
--- /dev/null
+++ b/user/kvmtrace_format
@@ -0,0 +1,200 @@
+#!/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:
+            %(tsc)d, %(event)d, %(pid)d %(vcpu)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 event ID, timestamp counter, pid
+         , vcpu 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:
+# pid:32, vcpu_id:32
+# 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.
+#
+HDRREC = "III"
+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, pid, vcpu_id) = struct.unpack(HDRREC, line)
+
+        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 &= 0x0fffffff
+
+        # provide relative TSC
+
+        if last_tsc > 0 and tsc_in == 1:
+            reltsc = tsc - last_tsc
+        else:
+            reltsc = 0
+
+        if tsc_in == 1:
+            last_tsc = tsc
+
+        if mhz:
+            tsc = tsc / (mhz*1000000.0)
+
+        args = {'tsc'   : tsc,
+                'event' : event,
+                'reltsc': reltsc,
+               'pid'   : pid,
+               'vcpu'  : vcpu_id,
+                '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: 0003-kvm-kvmtrace_format-parses-the-binary-trace-data.patch
Description: 0003-kvm-kvmtrace_format-parses-the-binary-trace-data.patch

-------------------------------------------------------------------------
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-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to