Pull request

This pull request contains Alex Bennée's vcpu trace events removal patches.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmR4tAMACgkQnKSrs4Gr
 c8ht/AgAiVslnH4vmD5IZloBHVRNEZKifODZbHW75yDgIirj/MhqlXPZ7bWoGwTN
 MLsTVuihhYnJBQKknN7lKyhkoQjgiJSkYhQbXSlcN7T3UE0+iG47FSudYTLDZSov
 M5wu1Edzi4q1uWr7ZIn/NS39iHVvQ7fdDMosHQmI0HKl25yx5936c0T2A4yyj96e
 LEtg4wLKo1uRgEMvCWrpiDz8ohNVwexAxCggwHE17tCebBmik+2cBEWAS+fcTbSr
 Nx3yWRat5VbqHOe3ghudLMNXHySQjNYrexULOVzyUUoaqUDt2eWCr9A4312BflEl
 8U9FFl99BZX5rWkyUzsHxEmPlRsazQ==
 =oMRe
 -----END PGP SIGNATURE-----

Merge tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu into staging

Pull request

This pull request contains Alex Bennée's vcpu trace events removal patches.

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCAAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmR4tAMACgkQnKSrs4Gr
# c8ht/AgAiVslnH4vmD5IZloBHVRNEZKifODZbHW75yDgIirj/MhqlXPZ7bWoGwTN
# MLsTVuihhYnJBQKknN7lKyhkoQjgiJSkYhQbXSlcN7T3UE0+iG47FSudYTLDZSov
# M5wu1Edzi4q1uWr7ZIn/NS39iHVvQ7fdDMosHQmI0HKl25yx5936c0T2A4yyj96e
# LEtg4wLKo1uRgEMvCWrpiDz8ohNVwexAxCggwHE17tCebBmik+2cBEWAS+fcTbSr
# Nx3yWRat5VbqHOe3ghudLMNXHySQjNYrexULOVzyUUoaqUDt2eWCr9A4312BflEl
# 8U9FFl99BZX5rWkyUzsHxEmPlRsazQ==
# =oMRe
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 01 Jun 2023 08:06:43 AM PDT
# gpg:                using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [full]
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>" [full]

* tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu:
  accel/tcg: include cs_base in our hash calculations
  hw/9pfs: use qemu_xxhash4
  tcg: remove the final vestiges of dstate
  trace: remove control-vcpu.h
  trace: remove code that depends on setting vcpu
  qapi: make the vcpu parameters deprecated for 8.1
  docs/deprecated: move QMP events bellow QMP command section
  scripts/qapi: document the tool that generated the file
  trace: remove vcpu_id from the TraceEvent structure
  trace-events: remove the remaining vcpu trace events
  *-user: remove the guest_user_syscall tracepoints

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-06-01 08:30:29 -07:00
commit 19a720b74f
28 changed files with 94 additions and 497 deletions

View File

@ -175,7 +175,6 @@ struct tb_desc {
tb_page_addr_t page_addr0;
uint32_t flags;
uint32_t cflags;
uint32_t trace_vcpu_dstate;
};
static bool tb_lookup_cmp(const void *p, const void *d)
@ -187,7 +186,6 @@ static bool tb_lookup_cmp(const void *p, const void *d)
tb_page_addr0(tb) == desc->page_addr0 &&
tb->cs_base == desc->cs_base &&
tb->flags == desc->flags &&
tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
tb_cflags(tb) == desc->cflags) {
/* check next page if needed */
tb_page_addr_t tb_phys_page1 = tb_page_addr1(tb);
@ -228,7 +226,6 @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
desc.cs_base = cs_base;
desc.flags = flags;
desc.cflags = cflags;
desc.trace_vcpu_dstate = *cpu->trace_dstate;
desc.pc = pc;
phys_pc = get_page_addr_code(desc.env, pc);
if (phys_pc == -1) {
@ -236,7 +233,7 @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
}
desc.page_addr0 = phys_pc;
h = tb_hash_func(phys_pc, (cflags & CF_PCREL ? 0 : pc),
flags, cflags, *cpu->trace_dstate);
flags, cs_base, cflags);
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
}
@ -263,7 +260,6 @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
jc->array[hash].pc == pc &&
tb->cs_base == cs_base &&
tb->flags == flags &&
tb->trace_vcpu_dstate == *cpu->trace_dstate &&
tb_cflags(tb) == cflags)) {
return tb;
}
@ -282,7 +278,6 @@ static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc,
tb->pc == pc &&
tb->cs_base == cs_base &&
tb->flags == flags &&
tb->trace_vcpu_dstate == *cpu->trace_dstate &&
tb_cflags(tb) == cflags)) {
return tb;
}

View File

@ -61,10 +61,10 @@ static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
#endif /* CONFIG_SOFTMMU */
static inline
uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t flags,
uint32_t cf_mask, uint32_t trace_vcpu_dstate)
uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc,
uint32_t flags, uint64_t flags2, uint32_t cf_mask)
{
return qemu_xxhash7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate);
return qemu_xxhash8(phys_pc, pc, flags2, flags, cf_mask);
}
#endif

View File

@ -50,7 +50,6 @@ static bool tb_cmp(const void *ap, const void *bp)
a->cs_base == b->cs_base &&
a->flags == b->flags &&
(tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&
a->trace_vcpu_dstate == b->trace_vcpu_dstate &&
tb_page_addr0(a) == tb_page_addr0(b) &&
tb_page_addr1(a) == tb_page_addr1(b));
}
@ -888,7 +887,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
/* remove the TB from the hash list */
phys_pc = tb_page_addr0(tb);
h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb->pc),
tb->flags, orig_cflags, tb->trace_vcpu_dstate);
tb->flags, tb->cs_base, orig_cflags);
if (!qht_remove(&tb_ctx.htable, tb, h)) {
return;
}
@ -969,7 +968,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
/* add in the hash table */
h = tb_hash_func(phys_pc, (tb->cflags & CF_PCREL ? 0 : tb->pc),
tb->flags, tb->cflags, tb->trace_vcpu_dstate);
tb->flags, tb->cs_base, tb->cflags);
qht_insert(&tb_ctx.htable, tb, h, &existing_tb);
/* remove TB from the page(s) if we couldn't insert it */

View File

@ -65,11 +65,6 @@
#include "internal.h"
#include "perf.h"
/* Make sure all possible CPU event bits fit in tb->trace_vcpu_dstate */
QEMU_BUILD_BUG_ON(CPU_TRACE_DSTATE_MAX_EVENTS >
sizeof_field(TranslationBlock, trace_vcpu_dstate)
* BITS_PER_BYTE);
TBContext tb_ctx;
/*
@ -352,7 +347,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
tb->cs_base = cs_base;
tb->flags = flags;
tb->cflags = cflags;
tb->trace_vcpu_dstate = *cpu->trace_dstate;
tb_set_page_addr0(tb, phys_pc);
tb_set_page_addr1(tb, -1);
tcg_ctx->gen_tb = tb;

View File

@ -528,10 +528,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8)
{
CPUState *cpu = env_cpu(cpu_env);
abi_long ret;
trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
if (do_strace) {
print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
}
@ -541,7 +539,6 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
if (do_strace) {
print_freebsd_syscall_ret(num, ret);
}
trace_guest_user_syscall_ret(cpu, num, ret);
return ret;
}

View File

@ -218,6 +218,22 @@ instruction per translated block" mode (which can be set on the
command line or via the HMP, but not via QMP). The information remains
available via the HMP 'info jit' command.
QEMU Machine Protocol (QMP) events
----------------------------------
``MEM_UNPLUG_ERROR`` (since 6.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
``vcpu`` trace events (since 8.1)
'''''''''''''''''''''''''''''''''
The ability to instrument QEMU helper functions with vCPU-aware trace
points was removed in 7.0. However QMP still exposed the vcpu
parameter. This argument has now been deprecated and the remaining
remaining trace points that used it are selected just by name.
Human Monitor Protocol (HMP) commands
-------------------------------------
@ -251,15 +267,6 @@ it. Since all recent x86 hardware from the past >10 years is capable of the
64-bit x86 extensions, a corresponding 64-bit OS should be used instead.
QEMU API (QAPI) events
----------------------
``MEM_UNPLUG_ERROR`` (since 6.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use the more generic event ``DEVICE_UNPLUG_GUEST_ERROR`` instead.
System emulator machines
------------------------

View File

@ -738,15 +738,14 @@ static VariLenAffix affixForIndex(uint64_t index)
return invertAffix(&prefix); /* convert prefix to suffix */
}
/* creative abuse of tb_hash_func7, which is based on xxhash */
static uint32_t qpp_hash(QppEntry e)
{
return qemu_xxhash7(e.ino_prefix, e.dev, 0, 0, 0);
return qemu_xxhash4(e.ino_prefix, e.dev);
}
static uint32_t qpf_hash(QpfEntry e)
{
return qemu_xxhash7(e.ino, e.dev, 0, 0, 0);
return qemu_xxhash4(e.ino, e.dev);
}
static bool qpd_cmp_func(const void *obj, const void *userp)

View File

@ -32,7 +32,7 @@
#include "sysemu/tcg.h"
#include "hw/boards.h"
#include "hw/qdev-properties.h"
#include "trace/trace-root.h"
#include "trace.h"
#include "qemu/plugin.h"
CPUState *cpu_by_arch_id(int64_t id)
@ -113,7 +113,7 @@ void cpu_reset(CPUState *cpu)
{
device_cold_reset(DEVICE(cpu));
trace_guest_cpu_reset(cpu);
trace_cpu_reset(cpu->cpu_index);
}
static void cpu_common_reset_hold(Object *obj)
@ -211,7 +211,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
}
/* NOTE: latest generic point where the cpu is fully realized */
trace_init_vcpu(cpu);
}
static void cpu_common_unrealizefn(DeviceState *dev)
@ -219,7 +218,6 @@ static void cpu_common_unrealizefn(DeviceState *dev)
CPUState *cpu = CPU(dev);
/* NOTE: latest generic point before the cpu is fully unrealized */
trace_fini_vcpu(cpu);
cpu_exec_unrealizefn(cpu);
}

View File

@ -29,3 +29,6 @@ clock_set(const char *clk, uint64_t old, uint64_t new) "'%s', %"PRIu64"Hz->%"PRI
clock_propagate(const char *clk) "'%s'"
clock_update(const char *clk, const char *src, uint64_t hz, int cb) "'%s', src='%s', val=%"PRIu64"Hz cb=%d"
clock_set_mul_div(const char *clk, uint32_t oldmul, uint32_t mul, uint32_t olddiv, uint32_t div) "'%s', mul: %u -> %u, div: %u -> %u"
# cpu-common.c
cpu_reset(int cpu_index) "%d"

View File

@ -545,9 +545,6 @@ struct TranslationBlock {
#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
#define CF_CLUSTER_SHIFT 24
/* Per-vCPU dynamic tracing state used to generate this TB */
uint32_t trace_vcpu_dstate;
/*
* Above fields used for comparing
*/

View File

@ -266,7 +266,6 @@ typedef void (*run_on_cpu_func)(CPUState *cpu, run_on_cpu_data data);
struct qemu_work_item;
#define CPU_UNSET_NUMA_NODE_ID -1
#define CPU_TRACE_DSTATE_MAX_EVENTS 32
/**
* CPUState:
@ -407,10 +406,6 @@ struct CPUState {
/* Use by accel-block: CPU is executing an ioctl() */
QemuLockCnt in_ioctl_lock;
/* Used for events with 'vcpu' and *without* the 'disabled' properties */
DECLARE_BITMAP(trace_dstate_delayed, CPU_TRACE_DSTATE_MAX_EVENTS);
DECLARE_BITMAP(trace_dstate, CPU_TRACE_DSTATE_MAX_EVENTS);
DECLARE_BITMAP(plugin_mask, QEMU_PLUGIN_EV_MAX);
#ifdef CONFIG_PLUGIN

View File

@ -48,8 +48,8 @@
* xxhash32, customized for input variables that are not guaranteed to be
* contiguous in memory.
*/
static inline uint32_t
qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
static inline uint32_t qemu_xxhash8(uint64_t ab, uint64_t cd, uint64_t ef,
uint32_t g, uint32_t h)
{
uint32_t v1 = QEMU_XXHASH_SEED + PRIME32_1 + PRIME32_2;
uint32_t v2 = QEMU_XXHASH_SEED + PRIME32_2;
@ -59,6 +59,8 @@ qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
uint32_t b = ab >> 32;
uint32_t c = cd;
uint32_t d = cd >> 32;
uint32_t e = ef;
uint32_t f = ef >> 32;
uint32_t h32;
v1 += a * PRIME32_2;
@ -89,6 +91,9 @@ qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
h32 += g * PRIME32_3;
h32 = rol32(h32, 17) * PRIME32_4;
h32 += h * PRIME32_3;
h32 = rol32(h32, 17) * PRIME32_4;
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
@ -100,23 +105,29 @@ qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
static inline uint32_t qemu_xxhash2(uint64_t ab)
{
return qemu_xxhash7(ab, 0, 0, 0, 0);
return qemu_xxhash8(ab, 0, 0, 0, 0);
}
static inline uint32_t qemu_xxhash4(uint64_t ab, uint64_t cd)
{
return qemu_xxhash7(ab, cd, 0, 0, 0);
return qemu_xxhash8(ab, cd, 0, 0, 0);
}
static inline uint32_t qemu_xxhash5(uint64_t ab, uint64_t cd, uint32_t e)
{
return qemu_xxhash7(ab, cd, e, 0, 0);
return qemu_xxhash8(ab, cd, 0, e, 0);
}
static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t cd, uint32_t e,
uint32_t f)
{
return qemu_xxhash7(ab, cd, e, f, 0);
return qemu_xxhash8(ab, cd, 0, e, f);
}
static inline uint32_t qemu_xxhash7(uint64_t ab, uint64_t cd, uint64_t ef,
uint32_t g)
{
return qemu_xxhash8(ab, cd, ef, g, 0);
}
/*

View File

@ -26,9 +26,6 @@ static inline void record_syscall_start(void *cpu, int num,
abi_long arg5, abi_long arg6,
abi_long arg7, abi_long arg8)
{
trace_guest_user_syscall(cpu, num,
arg1, arg2, arg3, arg4,
arg5, arg6, arg7, arg8);
qemu_plugin_vcpu_syscall(cpu, num,
arg1, arg2, arg3, arg4,
arg5, arg6, arg7, arg8);
@ -36,7 +33,6 @@ static inline void record_syscall_start(void *cpu, int num,
static inline void record_syscall_return(void *cpu, int num, abi_long ret)
{
trace_guest_user_syscall_ret(cpu, num, ret);
qemu_plugin_vcpu_syscall_ret(cpu, num, ret);
}

View File

@ -37,13 +37,14 @@
#
# @vcpu: Whether this is a per-vCPU event (since 2.7).
#
# An event is per-vCPU if it has the "vcpu" property in the
# "trace-events" files.
# Features:
# @deprecated: Member @vcpu is deprecated, and always ignored.
#
# Since: 2.2
##
{ 'struct': 'TraceEventInfo',
'data': {'name': 'str', 'state': 'TraceEventState', 'vcpu': 'bool'} }
'data': {'name': 'str', 'state': 'TraceEventState',
'vcpu': { 'type': 'bool', 'features': ['deprecated'] } } }
##
# @trace-event-get-state:
@ -52,19 +53,15 @@
#
# @name: Event name pattern (case-sensitive glob).
#
# @vcpu: The vCPU to query (any by default; since 2.7).
# @vcpu: The vCPU to query (since 2.7).
#
# Features:
# @deprecated: Member @vcpu is deprecated, and always ignored.
#
# Returns: a list of @TraceEventInfo for the matching events
#
# An event is returned if:
#
# - its name matches the @name pattern, and
# - if @vcpu is given, the event has the "vcpu" property.
#
# Therefore, if @vcpu is given, the operation will only match per-vCPU
# events, returning their state on the specified vCPU. Special case:
# if @name is an exact match, @vcpu is given and the event does not
# have the "vcpu" property, an error is returned.
# An event is returned if its name matches the @name pattern
# (There are no longer any per-vCPU events).
#
# Since: 2.2
#
@ -75,7 +72,8 @@
# <- { "return": [ { "name": "qemu_memalign", "state": "disabled", "vcpu": false } ] }
##
{ 'command': 'trace-event-get-state',
'data': {'name': 'str', '*vcpu': 'int'},
'data': {'name': 'str',
'*vcpu': {'type': 'int', 'features': ['deprecated'] } },
'returns': ['TraceEventInfo'] }
##
@ -91,15 +89,11 @@
#
# @vcpu: The vCPU to act upon (all by default; since 2.7).
#
# An event's state is modified if:
# Features:
# @deprecated: Member @vcpu is deprecated, and always ignored.
#
# - its name matches the @name pattern, and
# - if @vcpu is given, the event has the "vcpu" property.
#
# Therefore, if @vcpu is given, the operation will only match per-vCPU
# events, setting their state on the specified vCPU. Special case: if
# @name is an exact match, @vcpu is given and the event does not have
# the "vcpu" property, an error is returned.
# An event is enabled if its name matches the @name pattern
# (There are no longer any per-vCPU events).
#
# Since: 2.2
#
@ -111,4 +105,4 @@
##
{ 'command': 'trace-event-set-state',
'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool',
'*vcpu': 'int'} }
'*vcpu': {'type': 'int', 'features': ['deprecated'] } } }

View File

@ -13,6 +13,7 @@
from contextlib import contextmanager
import os
import sys
import re
from typing import (
Dict,
@ -162,7 +163,7 @@ class QAPIGenC(QAPIGenCCode):
def _top(self) -> str:
return mcgen('''
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
/* AUTOMATICALLY GENERATED by %(tool)s DO NOT MODIFY */
/*
%(blurb)s
@ -174,6 +175,7 @@ class QAPIGenC(QAPIGenCCode):
*/
''',
tool=os.path.basename(sys.argv[0]),
blurb=self._blurb, copyright=self._copyright)
def _bottom(self) -> str:
@ -195,7 +197,10 @@ class QAPIGenH(QAPIGenC):
class QAPIGenTrace(QAPIGen):
def _top(self) -> str:
return super()._top() + '# AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n'
return (super()._top()
+ '# AUTOMATICALLY GENERATED by '
+ os.path.basename(sys.argv[0])
+ ', DO NOT MODIFY\n\n')
@contextmanager

View File

@ -32,19 +32,13 @@ def generate(events, backend, group):
out('uint16_t %s;' % e.api(e.QEMU_DSTATE))
for e in events:
if "vcpu" in e.properties:
vcpu_id = 0
else:
vcpu_id = "TRACE_VCPU_EVENT_NONE"
out('TraceEvent %(event)s = {',
' .id = 0,',
' .vcpu_id = %(vcpu_id)s,',
' .name = \"%(name)s\",',
' .sstate = %(sstate)s,',
' .dstate = &%(dstate)s ',
'};',
event = e.api(e.QEMU_EVENT),
vcpu_id = vcpu_id,
name = e.name,
sstate = "TRACE_%s_ENABLED" % e.name.upper(),
dstate = e.api(e.QEMU_DSTATE))

View File

@ -16,10 +16,7 @@ from tracetool import out
def generate(events, backend, group):
if group == "root":
header = "trace/control-vcpu.h"
else:
header = "trace/control.h"
header = "trace/control.h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
@ -74,16 +71,7 @@ def generate(events, backend, group):
out('}')
# tracer wrapper with checks (per-vCPU tracing)
if "vcpu" in e.properties:
trace_cpu = next(iter(e.args))[1]
cond = "trace_event_get_vcpu_state(%(cpu)s,"\
" TRACE_%(id)s)"\
% dict(
cpu=trace_cpu,
id=e.name.upper())
else:
cond = "true"
cond = "true"
out('',
'static inline void %(api)s(%(args)s)',

View File

@ -36,16 +36,3 @@ void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
}
}
}
void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
TraceEvent *ev, bool state)
{
/* should never be called on non-target binaries */
abort();
}
void trace_init_vcpu(CPUState *vcpu)
{
/* should never be called on non-target binaries */
abort();
}

View File

@ -54,53 +54,3 @@ qmp_job_resume(void *job) "job %p"
qmp_job_complete(void *job) "job %p"
qmp_job_finalize(void *job) "job %p"
qmp_job_dismiss(void *job) "job %p"
### Guest events, keep at bottom
## vCPU
# trace/control-target.c
# Hot-plug a new virtual (guest) CPU
#
# Mode: user, softmmu
# Targets: all
vcpu guest_cpu_enter(void)
# trace/control.c
# Hot-unplug a virtual (guest) CPU
#
# Mode: user, softmmu
# Targets: all
vcpu guest_cpu_exit(void)
# hw/core/cpu.c
# Reset the state of a virtual (guest) CPU
#
# Mode: user, softmmu
# Targets: all
vcpu guest_cpu_reset(void)
# include/user/syscall-trace.h
# @num: System call number.
# @arg*: System call argument value.
#
# Start executing a guest system call in syscall emulation mode.
#
# Mode: user
# Targets: TCG(all)
vcpu guest_user_syscall(uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8) "num=0x%016"PRIx64" arg1=0x%016"PRIx64" arg2=0x%016"PRIx64" arg3=0x%016"PRIx64" arg4=0x%016"PRIx64" arg5=0x%016"PRIx64" arg6=0x%016"PRIx64" arg7=0x%016"PRIx64" arg8=0x%016"PRIx64
# @num: System call number.
# @ret: System call result value.
#
# Finish executing a guest system call in syscall emulation mode.
#
# Mode: user
# Targets: TCG(all)
vcpu guest_user_syscall_ret(uint64_t num, uint64_t ret) "num=0x%016"PRIx64" ret=0x%016"PRIx64

View File

@ -25,16 +25,6 @@ static inline uint32_t trace_event_get_id(TraceEvent *ev)
return ev->id;
}
static inline uint32_t trace_event_get_vcpu_id(TraceEvent *ev)
{
return ev->vcpu_id;
}
static inline bool trace_event_is_vcpu(TraceEvent *ev)
{
return ev->vcpu_id != TRACE_VCPU_EVENT_NONE;
}
static inline const char * trace_event_get_name(TraceEvent *ev)
{
assert(ev != NULL);

View File

@ -36,113 +36,22 @@ void trace_event_set_state_dynamic_init(TraceEvent *ev, bool state)
void trace_event_set_state_dynamic(TraceEvent *ev, bool state)
{
CPUState *vcpu;
assert(trace_event_get_state_static(ev));
if (trace_event_is_vcpu(ev) && likely(first_cpu != NULL)) {
CPU_FOREACH(vcpu) {
trace_event_set_vcpu_state_dynamic(vcpu, ev, state);
}
} else {
/*
* Without the "vcpu" property, dstate can only be 1 or 0. With it, we
* haven't instantiated any vCPU yet, so we will set a global state
* instead, and trace_init_vcpu will reconcile it afterwards.
*/
bool state_pre = *ev->dstate;
if (state_pre != state) {
if (state) {
trace_events_enabled_count++;
*ev->dstate = 1;
} else {
trace_events_enabled_count--;
*ev->dstate = 0;
}
}
}
}
static void trace_event_synchronize_vcpu_state_dynamic(
CPUState *vcpu, run_on_cpu_data ignored)
{
bitmap_copy(vcpu->trace_dstate, vcpu->trace_dstate_delayed,
CPU_TRACE_DSTATE_MAX_EVENTS);
tcg_flush_jmp_cache(vcpu);
}
void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
TraceEvent *ev, bool state)
{
uint32_t vcpu_id;
bool state_pre;
assert(trace_event_get_state_static(ev));
assert(trace_event_is_vcpu(ev));
vcpu_id = trace_event_get_vcpu_id(ev);
state_pre = test_bit(vcpu_id, vcpu->trace_dstate);
/*
* There is no longer a "vcpu" property, dstate can only be 1 or
* 0. With it, we haven't instantiated any vCPU yet, so we will
* set a global state instead, and trace_init_vcpu will reconcile
* it afterwards.
*/
bool state_pre = *ev->dstate;
if (state_pre != state) {
if (state) {
trace_events_enabled_count++;
set_bit(vcpu_id, vcpu->trace_dstate_delayed);
(*ev->dstate)++;
*ev->dstate = 1;
} else {
trace_events_enabled_count--;
clear_bit(vcpu_id, vcpu->trace_dstate_delayed);
(*ev->dstate)--;
}
if (vcpu->created) {
/*
* Delay changes until next TB; we want all TBs to be built from a
* single set of dstate values to ensure consistency of generated
* tracing code.
*/
async_run_on_cpu(vcpu, trace_event_synchronize_vcpu_state_dynamic,
RUN_ON_CPU_NULL);
} else {
trace_event_synchronize_vcpu_state_dynamic(vcpu, RUN_ON_CPU_NULL);
*ev->dstate = 0;
}
}
}
static bool adding_first_cpu1(void)
{
CPUState *cpu;
size_t count = 0;
CPU_FOREACH(cpu) {
count++;
if (count > 1) {
return false;
}
}
return true;
}
static bool adding_first_cpu(void)
{
QEMU_LOCK_GUARD(&qemu_cpu_list_lock);
return adding_first_cpu1();
}
void trace_init_vcpu(CPUState *vcpu)
{
TraceEventIter iter;
TraceEvent *ev;
trace_event_iter_init_all(&iter);
while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (trace_event_is_vcpu(ev) &&
trace_event_get_state_static(ev) &&
trace_event_get_state_dynamic(ev)) {
if (adding_first_cpu()) {
/* check preconditions */
assert(*ev->dstate == 1);
/* disable early-init state ... */
*ev->dstate = 0;
trace_events_enabled_count--;
/* ... and properly re-enable */
trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
} else {
trace_event_set_vcpu_state_dynamic(vcpu, ev, true);
}
}
}
trace_guest_cpu_enter(vcpu);
}

View File

@ -1,63 +0,0 @@
/*
* Interface for configuring and controlling the state of tracing events.
*
* Copyright (C) 2011-2016 Lluís Vilanova <vilanova@ac.upc.edu>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef TRACE__CONTROL_VCPU_H
#define TRACE__CONTROL_VCPU_H
#include "control.h"
#include "event-internal.h"
#include "hw/core/cpu.h"
/**
* trace_event_get_vcpu_state:
* @vcpu: Target vCPU.
* @id: Event identifier name.
*
* Get the tracing state of an event (both static and dynamic) for the given
* vCPU.
*
* If the event has the disabled property, the check will have no performance
* impact.
*/
#define trace_event_get_vcpu_state(vcpu, id) \
((id ##_ENABLED) && \
trace_event_get_vcpu_state_dynamic_by_vcpu_id( \
vcpu, _ ## id ## _EVENT.vcpu_id))
/**
* trace_event_get_vcpu_state_dynamic:
*
* Get the dynamic tracing state of an event for the given vCPU.
*/
static bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu, TraceEvent *ev);
#include "control-internal.h"
static inline bool
trace_event_get_vcpu_state_dynamic_by_vcpu_id(CPUState *vcpu,
uint32_t vcpu_id)
{
/* it's on fast path, avoid consistency checks (asserts) */
if (unlikely(trace_events_enabled_count)) {
return test_bit(vcpu_id, vcpu->trace_dstate);
} else {
return false;
}
}
static inline bool trace_event_get_vcpu_state_dynamic(CPUState *vcpu,
TraceEvent *ev)
{
uint32_t vcpu_id;
assert(trace_event_is_vcpu(ev));
vcpu_id = trace_event_get_vcpu_id(ev);
return trace_event_get_vcpu_state_dynamic_by_vcpu_id(vcpu, vcpu_id);
}
#endif

View File

@ -68,16 +68,6 @@ void trace_event_register_group(TraceEvent **events)
size_t i;
for (i = 0; events[i] != NULL; i++) {
events[i]->id = next_id++;
if (events[i]->vcpu_id == TRACE_VCPU_EVENT_NONE) {
continue;
}
if (likely(next_vcpu_id < CPU_TRACE_DSTATE_MAX_EVENTS)) {
events[i]->vcpu_id = next_vcpu_id++;
} else {
warn_report("too many vcpu trace events; dropping '%s'",
events[i]->name);
}
}
event_groups = g_renew(TraceEventGroup, event_groups, nevent_groups + 1);
event_groups[nevent_groups].events = events;
@ -272,24 +262,6 @@ void trace_init_file(void)
#endif
}
void trace_fini_vcpu(CPUState *vcpu)
{
TraceEventIter iter;
TraceEvent *ev;
trace_guest_cpu_exit(vcpu);
trace_event_iter_init_all(&iter);
while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (trace_event_is_vcpu(ev) &&
trace_event_get_state_static(ev) &&
trace_event_get_vcpu_state_dynamic(vcpu, ev)) {
/* must disable to affect the global counter */
trace_event_set_vcpu_state_dynamic(vcpu, ev, false);
}
}
}
bool trace_init_backends(void)
{
#ifdef CONFIG_TRACE_SIMPLE

View File

@ -89,23 +89,6 @@ static bool trace_event_is_pattern(const char *str);
*/
static uint32_t trace_event_get_id(TraceEvent *ev);
/**
* trace_event_get_vcpu_id:
*
* Get the per-vCPU identifier of an event.
*
* Special value #TRACE_VCPU_EVENT_NONE means the event is not vCPU-specific
* (does not have the "vcpu" property).
*/
static uint32_t trace_event_get_vcpu_id(TraceEvent *ev);
/**
* trace_event_is_vcpu:
*
* Whether this is a per-vCPU event.
*/
static bool trace_event_is_vcpu(TraceEvent *ev);
/**
* trace_event_get_name:
*
@ -172,21 +155,6 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev);
*/
void trace_event_set_state_dynamic(TraceEvent *ev, bool state);
/**
* trace_event_set_vcpu_state_dynamic:
*
* Set the dynamic tracing state of an event for the given vCPU.
*
* Pre-condition: trace_event_get_vcpu_state_static(ev) == true
*
* Note: Changes for execution-time events with the 'tcg' property will not be
* propagated until the next TB is executed (iff executing in TCG mode).
*/
void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
TraceEvent *ev, bool state);
/**
* trace_init_backends:
*
@ -205,22 +173,6 @@ bool trace_init_backends(void);
*/
void trace_init_file(void);
/**
* trace_init_vcpu:
* @vcpu: Added vCPU.
*
* Set initial dynamic event state for a hot-plugged vCPU.
*/
void trace_init_vcpu(CPUState *vcpu);
/**
* trace_fini_vcpu:
* @vcpu: Removed vCPU.
*
* Disable dynamic event state for a hot-unplugged vCPU.
*/
void trace_fini_vcpu(CPUState *vcpu);
/**
* trace_list_events:
* @f: Where to send output.

View File

@ -19,7 +19,6 @@
/**
* TraceEvent:
* @id: Unique event identifier.
* @vcpu_id: Unique per-vCPU event identifier.
* @name: Event name.
* @sstate: Static tracing state.
* @dstate: Dynamic tracing state
@ -33,7 +32,6 @@
*/
typedef struct TraceEvent {
uint32_t id;
uint32_t vcpu_id;
const char * name;
const bool sstate;
uint16_t *dstate;

View File

@ -10,23 +10,10 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-trace.h"
#include "control-vcpu.h"
#include "control.h"
static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
{
if (has_vcpu) {
CPUState *cpu = qemu_get_cpu(vcpu);
if (cpu == NULL) {
error_setg(errp, "invalid vCPU index %u", vcpu);
}
return cpu;
} else {
return NULL;
}
}
static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern,
static bool check_events(bool ignore_unavailable, bool is_pattern,
const char *name, Error **errp)
{
if (!is_pattern) {
@ -38,12 +25,6 @@ static bool check_events(bool has_vcpu, bool ignore_unavailable, bool is_pattern
return false;
}
/* error for non-vcpu event */
if (has_vcpu && !trace_event_is_vcpu(ev)) {
error_setg(errp, "event \"%s\" is not vCPU-specific", name);
return false;
}
/* error for unavailable event */
if (!ignore_unavailable && !trace_event_get_state_static(ev)) {
error_setg(errp, "event \"%s\" is disabled", name);
@ -70,22 +51,13 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name,
bool has_vcpu, int64_t vcpu,
Error **errp)
{
Error *err = NULL;
TraceEventInfoList *events = NULL;
TraceEventIter iter;
TraceEvent *ev;
bool is_pattern = trace_event_is_pattern(name);
CPUState *cpu;
/* Check provided vcpu */
cpu = get_cpu(has_vcpu, vcpu, &err);
if (err) {
error_propagate(errp, err);
return NULL;
}
/* Check events */
if (!check_events(has_vcpu, true, is_pattern, name, errp)) {
if (!check_events(true, is_pattern, name, errp)) {
return NULL;
}
@ -93,33 +65,17 @@ TraceEventInfoList *qmp_trace_event_get_state(const char *name,
trace_event_iter_init_pattern(&iter, name);
while ((ev = trace_event_iter_next(&iter)) != NULL) {
TraceEventInfo *value;
bool is_vcpu = trace_event_is_vcpu(ev);
if (has_vcpu && !is_vcpu) {
continue;
}
value = g_new(TraceEventInfo, 1);
value->vcpu = is_vcpu;
value->name = g_strdup(trace_event_get_name(ev));
if (!trace_event_get_state_static(ev)) {
value->state = TRACE_EVENT_STATE_UNAVAILABLE;
} else {
if (has_vcpu) {
if (is_vcpu) {
if (trace_event_get_vcpu_state_dynamic(cpu, ev)) {
value->state = TRACE_EVENT_STATE_ENABLED;
} else {
value->state = TRACE_EVENT_STATE_DISABLED;
}
}
/* else: already skipped above */
if (trace_event_get_state_dynamic(ev)) {
value->state = TRACE_EVENT_STATE_ENABLED;
} else {
if (trace_event_get_state_dynamic(ev)) {
value->state = TRACE_EVENT_STATE_ENABLED;
} else {
value->state = TRACE_EVENT_STATE_DISABLED;
}
value->state = TRACE_EVENT_STATE_DISABLED;
}
}
QAPI_LIST_PREPEND(events, value);
@ -133,21 +89,12 @@ void qmp_trace_event_set_state(const char *name, bool enable,
bool has_vcpu, int64_t vcpu,
Error **errp)
{
Error *err = NULL;
TraceEventIter iter;
TraceEvent *ev;
bool is_pattern = trace_event_is_pattern(name);
CPUState *cpu;
/* Check provided vcpu */
cpu = get_cpu(has_vcpu, vcpu, &err);
if (err) {
error_propagate(errp, err);
return;
}
/* Check events */
if (!check_events(has_vcpu, has_ignore_unavailable && ignore_unavailable,
if (!check_events(has_ignore_unavailable && ignore_unavailable,
is_pattern, name, errp)) {
return;
}
@ -155,14 +102,9 @@ void qmp_trace_event_set_state(const char *name, bool enable,
/* Apply changes (all errors checked above) */
trace_event_iter_init_pattern(&iter, name);
while ((ev = trace_event_iter_next(&iter)) != NULL) {
if (!trace_event_get_state_static(ev) ||
(has_vcpu && !trace_event_is_vcpu(ev))) {
if (!trace_event_get_state_static(ev)) {
continue;
}
if (has_vcpu) {
trace_event_set_vcpu_state_dynamic(cpu, ev, enable);
} else {
trace_event_set_state_dynamic(ev, enable);
}
trace_event_set_state_dynamic(ev, enable);
}
}

View File

@ -37,16 +37,10 @@ void hmp_trace_event(Monitor *mon, const QDict *qdict)
{
const char *tp_name = qdict_get_str(qdict, "name");
bool new_state = qdict_get_bool(qdict, "option");
bool has_vcpu = qdict_haskey(qdict, "vcpu");
int vcpu = qdict_get_try_int(qdict, "vcpu", 0);
Error *local_err = NULL;
if (vcpu < 0) {
monitor_printf(mon, "argument vcpu must be positive");
return;
}
qmp_trace_event_set_state(tp_name, new_state, true, true, has_vcpu, vcpu, &local_err);
qmp_trace_event_set_state(tp_name, new_state,
true, true, false, 0, &local_err);
if (local_err) {
error_report_err(local_err);
}
@ -80,8 +74,6 @@ void hmp_trace_file(Monitor *mon, const QDict *qdict)
void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
{
const char *name = qdict_get_try_str(qdict, "name");
bool has_vcpu = qdict_haskey(qdict, "vcpu");
int vcpu = qdict_get_try_int(qdict, "vcpu", 0);
TraceEventInfoList *events;
TraceEventInfoList *elem;
Error *local_err = NULL;
@ -89,12 +81,8 @@ void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
if (name == NULL) {
name = "*";
}
if (vcpu < 0) {
monitor_printf(mon, "argument vcpu must be positive");
return;
}
events = qmp_trace_event_get_state(name, has_vcpu, vcpu, &local_err);
events = qmp_trace_event_get_state(name, false, 0, &local_err);
if (local_err) {
error_report_err(local_err);
return;

View File

@ -144,7 +144,7 @@ uint32_t do_qsp_callsite_hash(const QSPCallSite *callsite, uint64_t ab)
uint32_t e = callsite->line;
uint32_t f = callsite->type;
return qemu_xxhash6(ab, cd, e, f);
return qemu_xxhash8(ab, cd, 0, e, f);
}
static inline