Import QEMU upstream snapshot d2e570c

Upstream: https://gitlab.com/qemu-project/qemu.git

Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
This commit is contained in:
Yaya48 committed 2026-08-31 02:15:30 +02:00
commit cf256aa081
11315 files changed
+3598369

No files matched your search

+140
View File
@@ -0,0 +1,140 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Backend management.
Creating new backends
---------------------
A new backend named 'foo-bar' corresponds to Python module
'tracetool/backend/foo_bar.py'.
A backend module should provide a docstring, whose first non-empty line will be
considered its short description.
All backends must generate their contents through the 'tracetool.out' routine.
Backend attributes
------------------
=========================== ====================================================
Attribute Description
=========================== ====================================================
PUBLIC If exists and is set to 'True', the backend is
considered "public".
CHECK_TRACE_EVENT_GET_STATE If exists and is set to 'True', the backend-specific
code inside the tracepoint is emitted within an
``if trace_event_get_state()`` conditional.
=========================== ====================================================
Backend functions
-----------------
All the following functions are optional, and no output will be generated if
they do not exist.
=============================== ==============================================
Function Description
=============================== ==============================================
generate_<format>_begin(events) Generate backend- and format-specific file
header contents.
generate_<format>_end(events) Generate backend- and format-specific file
footer contents.
generate_<format>(event) Generate backend- and format-specific contents
for the given event.
=============================== ==============================================
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
import os
import tracetool
def get_list(only_public = False):
"""Get a list of (name, description) pairs."""
res = [("nop", "Tracing disabled.")]
modnames = []
for filename in os.listdir(tracetool.backend.__path__[0]):
if filename.endswith('.py') and filename != '__init__.py':
modnames.append(filename.rsplit('.', 1)[0])
for modname in sorted(modnames):
module = tracetool.try_import("tracetool.backend." + modname)
# just in case; should never fail unless non-module files are put there
if not module[0]:
continue
module = module[1]
public = getattr(module, "PUBLIC", False)
if only_public and not public:
continue
doc = module.__doc__
if doc is None:
doc = ""
doc = doc.strip().split("\n")[0]
name = modname.replace("_", "-")
res.append((name, doc))
return res
def exists(name):
"""Return whether the given backend exists."""
if len(name) == 0:
return False
if name == "nop":
return True
name = name.replace("-", "_")
return tracetool.try_import("tracetool.backend." + name)[0]
class Wrapper:
def __init__(self, backends, format):
self._backends = [backend.replace("-", "_") for backend in backends]
self._format = format.replace("-", "_")
self.check_trace_event_get_state = False
for backend in self._backends:
assert exists(backend)
assert tracetool.format.exists(self._format)
for backend in self.backend_modules():
check_trace_event_get_state = getattr(backend, "CHECK_TRACE_EVENT_GET_STATE", False)
self.check_trace_event_get_state = self.check_trace_event_get_state or check_trace_event_get_state
def backend_modules(self):
for backend in self._backends:
module = tracetool.try_import("tracetool.backend." + backend)[1]
if module is not None:
yield module
def _run_function(self, name, *args, check_trace_event_get_state=None, **kwargs):
for backend in self.backend_modules():
func = getattr(backend, name % self._format, None)
if func is not None and \
(check_trace_event_get_state is None or
check_trace_event_get_state == getattr(backend, 'CHECK_TRACE_EVENT_GET_STATE', False)):
func(*args, **kwargs)
def generate_begin(self, events, group):
self._run_function("generate_%s_begin", events, group)
def generate(self, event, group, check_trace_event_get_state=None):
self._run_function("generate_%s", event, group, check_trace_event_get_state=check_trace_event_get_state)
def generate_backend_dstate(self, event, group):
self._run_function("generate_%s_backend_dstate", event, group)
def generate_end(self, events, group):
self._run_function("generate_%s_end", events, group)
+103
View File
@@ -0,0 +1,103 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
DTrace/SystemTAP backend.
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2017, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
PUBLIC = True
PROBEPREFIX = None
def probeprefix():
if PROBEPREFIX is None:
raise ValueError("you must set PROBEPREFIX")
return PROBEPREFIX
BINARY = None
def binary():
if BINARY is None:
raise ValueError("you must set BINARY")
return BINARY
def generate_h_begin(events, group):
if group == "root":
header = "trace-dtrace-root.h"
else:
header = "trace-dtrace-%s.h" % group
# Workaround for ust backend, which also includes <sys/sdt.h> and may
# require SDT_USE_VARIADIC to be defined. If dtrace includes <sys/sdt.h>
# first without defining SDT_USE_VARIADIC then ust breaks because the
# STAP_PROBEV() macro is not defined.
out('#ifndef SDT_USE_VARIADIC')
out('#define SDT_USE_VARIADIC 1')
out('#endif')
out('#include "%s"' % header,
'')
out('#undef SDT_USE_VARIADIC')
# SystemTap defines <provider>_<name>_ENABLED() but other DTrace
# implementations might not.
for e in events:
out('#ifndef QEMU_%(uppername)s_ENABLED',
'#define QEMU_%(uppername)s_ENABLED() true',
'#endif',
uppername=e.name.upper())
def generate_h(event, group):
out(' QEMU_%(uppername)s(%(argnames)s);',
uppername=event.name.upper(),
argnames=", ".join(event.args.names()))
def generate_h_backend_dstate(event, group):
out(' QEMU_%(uppername)s_ENABLED() || \\',
uppername=event.name.upper())
def generate_rs_begin(events, group):
out('use std::cell::UnsafeCell;',
'',
'extern "C" {')
# These are the Rust declarations of the .probes section semaphores
# generated by dtrace(1) in its .o file output.
for e in events:
if 'disable' in e.properties:
continue
out(' #[allow(dead_code)]',
f' static qemu_{e.name}_semaphore: UnsafeCell<u16>;')
out('}',
'')
def generate_rs(event, group):
args = event.args.rust_call_extern()
if args:
args = ', ' + args
out(f' ::trace::probe!(qemu, {event.name}{args});')
def generate_rs_backend_dstate(event, group):
# Rust does not have access to the <provider>_<name>_ENABLED() macro from
# the dtrace(1) generated .h file. Use the matching semaphore declarations
# generated by generate_rs_begin() instead.
out(' (unsafe {qemu_%(n)s_semaphore.get().read_volatile()}) != 0 ||',
n=event.name)
+51
View File
@@ -0,0 +1,51 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Ftrace built-in backend.
"""
__author__ = "Eiichi Tsukata <[email protected]>"
__copyright__ = "Copyright (C) 2013 Hitachi, Ltd."
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out, expand_format_string
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
def generate_h_begin(events, group):
out('#include "trace/ftrace.h"',
'')
def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
out('#line %(event_lineno)d "%(event_filename)s"',
' ftrace_write("%(name)s " %(fmt)s "\\n" %(argnames)s);',
'#line %(out_next_lineno)d "%(out_filename)s"',
name=event.name,
args=event.args,
event_lineno=event.lineno,
event_filename=event.filename,
fmt=event.fmt.rstrip("\n"),
argnames=argnames)
def generate_h_backend_dstate(event, group):
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
def generate_rs(event, group):
out(' let format_string = c"%(fmt)s";',
' unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, %(args)s);}',
fmt=expand_format_string(event.fmt),
args=event.args.rust_call_varargs())
+54
View File
@@ -0,0 +1,54 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Stderr built-in backend.
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2017, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out, expand_format_string
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
def generate_h_begin(events, group):
out('#include "qemu/log-for-trace.h"',
'')
def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
out(' if (qemu_loglevel_mask(LOG_TRACE)) {',
'#line %(event_lineno)d "%(event_filename)s"',
' qemu_log("%(name)s " %(fmt)s "\\n"%(argnames)s);',
'#line %(out_next_lineno)d "%(out_filename)s"',
' }',
event_lineno=event.lineno,
event_filename=event.filename,
name=event.name,
fmt=event.fmt.rstrip("\n"),
argnames=argnames)
def generate_h_backend_dstate(event, group):
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
def generate_rs(event, group):
out(' let format_string = c"%(fmt)s\\n";',
' if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 {',
' unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, %(args)s);}',
' }',
fmt=expand_format_string(event.fmt, event.name + " "),
args=event.args.rust_call_varargs())
+107
View File
@@ -0,0 +1,107 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Simple built-in backend.
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2017, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
def is_string(arg):
strtype = ('const char*', 'char*', 'const char *', 'char *')
arg_strip = arg.lstrip()
if arg_strip.startswith(strtype) and arg_strip.count('*') == 1:
return True
else:
return False
def generate_h_begin(events, group):
for event in events:
out('void _simple_%(api)s(%(args)s);',
api=event.api(),
args=event.args)
out('')
def generate_h(event, group):
out(' _simple_%(api)s(%(args)s);',
api=event.api(),
args=", ".join(event.args.names()))
def generate_h_backend_dstate(event, group):
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
def generate_c_begin(events, group):
out('#include "qemu/osdep.h"',
'#include "trace/control.h"',
'#include "trace/simple.h"',
'')
def generate_c(event, group):
out('void _simple_%(api)s(%(args)s)',
'{',
' TraceBufferRecord rec;',
api=event.api(),
args=event.args)
sizes = []
for type_, name in event.args:
if is_string(type_):
out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
name=name)
strsizeinfo = "4 + arg%s_len" % name
sizes.append(strsizeinfo)
else:
sizes.append("8")
sizestr = " + ".join(sizes)
if len(event.args) == 0:
sizestr = '0'
out('',
' if (trace_record_start(&rec, %(event_obj)s.id, %(size_str)s)) {',
' return; /* Trace Buffer Full, Event Dropped ! */',
' }',
event_obj=event.api(event.QEMU_EVENT),
size_str=sizestr)
if len(event.args) > 0:
for type_, name in event.args:
# string
if is_string(type_):
out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
name=name)
# pointer var (not string)
elif type_.endswith('*'):
out(' trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
name=name)
# primitive data type
else:
out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
name=name)
out(' trace_record_finish(&rec);',
'}',
'')
def generate_rs(event, group):
out(' extern "C" { fn _simple_%(api)s(%(rust_args)s); }',
' unsafe { _simple_%(api)s(%(args)s); }',
api=event.api(),
rust_args=event.args.rust_decl_extern(),
args=event.args.rust_call_extern())
+49
View File
@@ -0,0 +1,49 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Syslog built-in backend.
"""
__author__ = "Paul Durrant <[email protected]>"
__copyright__ = "Copyright 2016, Citrix Systems Inc."
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out, expand_format_string
PUBLIC = True
CHECK_TRACE_EVENT_GET_STATE = True
def generate_h_begin(events, group):
out('#include <syslog.h>',
'')
def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
out('#line %(event_lineno)d "%(event_filename)s"',
' syslog(LOG_INFO, "%(name)s " %(fmt)s %(argnames)s);',
'#line %(out_next_lineno)d "%(out_filename)s"',
event_lineno=event.lineno,
event_filename=event.filename,
name=event.name,
fmt=event.fmt.rstrip("\n"),
argnames=argnames)
def generate_rs(event, group):
out(' let format_string = c"%(fmt)s";',
' unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, %(args)s);}',
fmt=expand_format_string(event.fmt),
args=event.args.rust_call_varargs())
def generate_h_backend_dstate(event, group):
out(' trace_event_get_state_dynamic_by_id(%(event_id)s) || \\',
event_id="TRACE_" + event.name.upper())
+45
View File
@@ -0,0 +1,45 @@
# SPDX-License-Identifier: GPL-2.0-or-later
"""
LTTng User Space Tracing backend.
"""
__author__ = "Lluís Vilanova <[email protected]>"
__copyright__ = "Copyright 2012-2017, Lluís Vilanova <[email protected]>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "[email protected]"
from tracetool import out
PUBLIC = True
def generate_h_begin(events, group):
header = 'trace-ust-' + group + '.h'
out('#include <lttng/tracepoint.h>',
'#include "%s"' % header,
'',
'/* tracepoint_enabled() was introduced in LTTng UST 2.7 */',
'#ifndef tracepoint_enabled',
'#define tracepoint_enabled(a, b) true',
'#endif',
'')
def generate_h(event, group):
argnames = ", ".join(event.args.names())
if len(event.args) > 0:
argnames = ", " + argnames
out(' tracepoint(qemu, %(name)s%(tp_args)s);',
name=event.name,
tp_args=argnames)
def generate_h_backend_dstate(event, group):
out(' tracepoint_enabled(qemu, %(name)s) || \\',
name=event.name)