trace: Add 'vcpu' event property to trace guest vCPU

This property identifies events that trace vCPU-specific information.

It adds a "CPUState*" argument to events with the property, identifying
the vCPU raising the event. TCG translation events also have a
"TCGv_env" implicit argument that is later used as the "CPUState*"
argument at execution time.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Message-id: 145641861797.30295.6991314023181842105.stgit@localhost
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Lluís Vilanova 2016-02-25 17:43:38 +01:00 committed by Stefan Hajnoczi
parent b23197f9cf
commit 3d211d9f4d
11 changed files with 189 additions and 32 deletions

View file

@ -161,7 +161,7 @@ class Event(object):
"(?:(?:(?P<fmt_trans>\".+),)?\s*(?P<fmt>\".+))?"
"\s*")
_VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec"])
_VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"])
def __init__(self, name, props, fmt, args, orig=None):
"""
@ -230,7 +230,13 @@ class Event(object):
if "tcg" in props and isinstance(fmt, str):
raise ValueError("Events with 'tcg' property must have two formats")
return Event(name, props, fmt, args)
event = Event(name, props, fmt, args)
# add implicit arguments when using the 'vcpu' property
import tracetool.vcpu
event = tracetool.vcpu.transform_event(event)
return event
def __repr__(self):
"""Evaluable string representation for this object."""
@ -285,6 +291,7 @@ def _read_events(fobj):
event_trans.name += "_trans"
event_trans.properties += ["tcg-trans"]
event_trans.fmt = event.fmt[0]
# ignore TCG arguments
args_trans = []
for atrans, aorig in zip(
event_trans.transform(tracetool.transform.TCG_2_HOST).args,

View file

@ -6,7 +6,7 @@ trace/generated-tracers.h
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@ -23,6 +23,7 @@ def generate(events, backend):
'#define TRACE__GENERATED_TRACERS_H',
'',
'#include "qemu-common.h"',
'#include "qemu/typedefs.h"',
'')
backend.generate_begin(events)

View file

@ -13,7 +13,18 @@ __maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
from tracetool import out, Arguments
import tracetool.vcpu
def vcpu_transform_args(args):
assert len(args) == 1
return Arguments([
args,
# NOTE: this name must be kept in sync with the one in "tcg_h"
# NOTE: Current helper code uses TCGv_env (CPUArchState*)
("TCGv_env", "__tcg_" + args.names()[0]),
])
def generate(events, backend):
@ -35,21 +46,21 @@ def generate(events, backend):
if "tcg-trans" not in e.properties:
continue
# get the original event definition
e = e.original
out('static inline void %(name_tcg)s(%(args)s)',
'{',
name_tcg=e.api(e.QEMU_TRACE_TCG),
args=e.args)
name_tcg=e.original.api(e.QEMU_TRACE_TCG),
args=tracetool.vcpu.transform_args("tcg_h", e.original))
if "disable" not in e.properties:
args_trans = e.original.event_trans.args
args_exec = tracetool.vcpu.transform_args(
"tcg_helper_c", e.original.event_exec, "wrapper")
out(' %(name_trans)s(%(argnames_trans)s);',
' gen_helper_%(name_exec)s(%(argnames_exec)s);',
name_trans=e.event_trans.api(e.QEMU_TRACE),
name_exec=e.event_exec.api(e.QEMU_TRACE),
argnames_trans=", ".join(e.event_trans.args.names()),
argnames_exec=", ".join(e.event_exec.args.names()))
name_trans=e.original.event_trans.api(e.QEMU_TRACE),
name_exec=e.original.event_exec.api(e.QEMU_TRACE),
argnames_trans=", ".join(args_trans.names()),
argnames_exec=", ".join(args_exec.names()))
out('}')

View file

@ -6,15 +6,38 @@ Generate trace/generated-helpers.c.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
from tracetool import Arguments, out
from tracetool.transform import *
import tracetool.vcpu
def vcpu_transform_args(args, mode):
assert len(args) == 1
# NOTE: this name must be kept in sync with the one in "tcg_h"
args = Arguments([(args.types()[0], "__tcg_" + args.names()[0])])
if mode == "code":
return Arguments([
# Does cast from helper requirements to tracing types
("CPUState *", "ENV_GET_CPU(%s)" % args.names()[0]),
])
else:
args = Arguments([
# NOTE: Current helper code uses TCGv_env (CPUArchState*)
("CPUArchState *", args.names()[0]),
])
if mode == "header":
return args
elif mode == "wrapper":
return args.transform(HOST_2_TCG)
else:
assert False
def generate(events, backend):
@ -34,18 +57,18 @@ def generate(events, backend):
if "tcg-exec" not in e.properties:
continue
# tracetool.generate always transforms types to host
e_args = e.original.args
e_args_api = tracetool.vcpu.transform_args(
"tcg_helper_c", e.original, "header").transform(
HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF)
e_args_call = tracetool.vcpu.transform_args(
"tcg_helper_c", e, "code")
values = ["(%s)%s" % (t, n)
for t, n in e.args.transform(TCG_2_TCG_HELPER_DEF)]
out('void %(name_tcg)s(%(args)s)',
out('void %(name_tcg)s(%(args_api)s)',
'{',
' %(name)s(%(values)s);',
' %(name)s(%(args_call)s);',
'}',
name_tcg="helper_%s_proxy" % e.api(),
name=e.api(),
args=e_args.transform(HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF),
values=", ".join(values),
args_api=e_args_api,
args_call=", ".join(e_args_call.casted()),
)

View file

@ -6,7 +6,7 @@ Generate trace/generated-helpers.h.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@ -15,6 +15,7 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
from tracetool.transform import *
import tracetool.vcpu
def generate(events, backend):
@ -29,11 +30,9 @@ def generate(events, backend):
if "tcg-exec" not in e.properties:
continue
# tracetool.generate always transforms types to host
e_args = e.original.args
# TCG helper proxy declaration
fmt = "DEF_HELPER_FLAGS_%(argc)d(%(name)s, %(flags)svoid%(types)s)"
e_args = tracetool.vcpu.transform_args("tcg_helper_c", e.original, "header")
args = e_args.transform(HOST_2_TCG_COMPAT, HOST_2_TCG,
TCG_2_TCG_HELPER_DECL)
types = ", ".join(args.types())

View file

@ -6,7 +6,7 @@ Generate trace/generated-helpers-wrappers.h.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@ -15,6 +15,7 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
from tracetool.transform import *
import tracetool.vcpu
def generate(events, backend):
@ -33,7 +34,7 @@ def generate(events, backend):
continue
# tracetool.generate always transforms types to host
e_args = e.original.args
e_args = tracetool.vcpu.transform_args("tcg_helper_c", e.original, "wrapper")
# mixed-type to TCG helper bridge
args_tcg_compat = e_args.transform(HOST_2_TCG_COMPAT)

View file

@ -32,4 +32,5 @@ def generate(events, backend):
' */',
'#pragma GCC diagnostic ignored "-Wredundant-decls"',
'',
'#include "qemu/typedefs.h"',
'#include "generated-ust-provider.h"')

View file

@ -6,7 +6,7 @@ Type-transformation rules.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@ -98,6 +98,7 @@ HOST_2_TCG = {
"uint32_t": "TCGv_i32",
"uint64_t": "TCGv_i64",
"void *" : "TCGv_ptr",
"CPUArchState *": "TCGv_env",
None: _host_2_tcg,
}
@ -130,6 +131,7 @@ TCG_2_TCG_HELPER_DECL = {
"TCGv_ptr": "ptr",
"TCGv_i32": "i32",
"TCGv_i64": "i64",
"TCGv_env": "env",
None: _tcg_2_tcg_helper_decl_error,
}

70
scripts/tracetool/vcpu.py Normal file
View file

@ -0,0 +1,70 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Generic management for the 'vcpu' property.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
__copyright__ = "Copyright 2016, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import Arguments, try_import
def transform_event(event):
"""Transform event to comply with the 'vcpu' property (if present)."""
if "vcpu" in event.properties:
# events with 'tcg-trans' and 'tcg-exec' are auto-generated from
# already-patched events
assert "tcg-trans" not in event.properties
assert "tcg-exec" not in event.properties
event.args = Arguments([("CPUState *", "__cpu"), event.args])
if "tcg" in event.properties:
fmt = "\"cpu=%p \""
event.fmt = [fmt + event.fmt[0],
fmt + event.fmt[1]]
else:
fmt = "\"cpu=%p \""
event.fmt = fmt + event.fmt
return event
def transform_args(format, event, *args, **kwargs):
"""Transforms the arguments to suit the specified format.
The format module must implement function 'vcpu_args', which receives the
implicit arguments added by the 'vcpu' property, and must return suitable
arguments for the given format.
The function is only called for events with the 'vcpu' property.
Parameters
==========
format : str
Format module name.
event : Event
args, kwargs
Passed to 'vcpu_transform_args'.
Returns
=======
Arguments
The transformed arguments, including the non-implicit ones.
"""
if "vcpu" in event.properties:
ok, func = try_import("tracetool.format." + format,
"vcpu_transform_args")
assert ok
assert func
return Arguments([func(event.args[:1], *args, **kwargs),
event.args[1:]])
else:
return event.args