* [PULL 00/10] x86, mtest2make changes for QEMU 10.2
@ 2025-11-20 0:16 Paolo Bonzini
2025-11-20 0:16 ` [PULL 01/10] ioapic: fix typo in irqfd check Paolo Bonzini
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel
The following changes since commit e88510fcdc13380bd4895a17d6f8a0b3a3325b85:
Merge tag 'pull-target-arm-20251114' of https://gitlab.com/pm215/qemu into staging (2025-11-14 17:59:05 +0100)
are available in the Git repository at:
https://gitlab.com/bonzini/qemu.git tags/for-upstream
for you to fetch changes up to 58f88d0bf7c4c0676b54f97ba91eecccbca968c9:
replay: add tracing events (2025-11-19 09:24:01 +0100)
----------------------------------------------------------------
* i386 fixes
* mtest2make cleanups to enable per-speed dependencies
* record/replay tracepoints
----------------------------------------------------------------
Nguyen Dinh Phi (1):
target/i386: emulate: Make sure fetch_instruction exist before calling it
Paolo Bonzini (8):
ioapic: fix typo in irqfd check
target/i386/tcg: validate segment registers
target/i386: svm: fix sign extension of exit code
target/i386: fix stack size when delivering real mode interrupts
mtest2make: cleanup mtest-suites variables
mtest2make: add dependencies to the "speed-qualified" suite
mtest2make: do not repeat the same speed over and over
replay: add tracing events
Peter Maydell (1):
target/i386: Mark VPERMILPS as not valid with prefix 0
Makefile | 4 ++-
meson.build | 1 +
replay/trace.h | 1 +
target/i386/tcg/helper-tcg.h | 2 +-
hw/intc/ioapic.c | 4 +--
replay/replay-internal.c | 70 ++++++++++++++++++++++++++++---------
target/i386/emulate/x86_decode.c | 6 +++-
target/i386/tcg/seg_helper.c | 4 +--
target/i386/tcg/system/svm_helper.c | 6 ++--
target/i386/tcg/decode-new.c.inc | 9 +++--
replay/trace-events | 12 +++++++
scripts/mtest2make.py | 46 ++++++++++++------------
12 files changed, 112 insertions(+), 53 deletions(-)
create mode 100644 replay/trace.h
create mode 100644 replay/trace-events
--
2.51.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PULL 01/10] ioapic: fix typo in irqfd check
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 02/10] target/i386: emulate: Make sure fetch_instruction exist before calling it Paolo Bonzini
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Cédric Le Goater, Magnus Kulke
Not registering the IEC notifier results in a regression with interrupt remapping
when running a VM configured with an intel-iommu device and an assigned
PCI VF. At boot, Linux complains with :
[ 15.416794] __common_interrupt: 2.37 No irq handler for vector
Reported-by: Cédric Le Goater <clg@redhat.com>
Analyzed-by: Magnus Kulke <magnuskulke@linux.microsoft.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/intc/ioapic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index e431d003117..38e43846486 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -216,7 +216,7 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s)
#endif
}
-#ifdef ACCEL_KERNEL_GSI_IRQFD_POSSIBLE
+#ifdef ACCEL_GSI_IRQFD_POSSIBLE
static void ioapic_iec_notifier(void *private, bool global,
uint32_t index, uint32_t mask)
{
@@ -434,7 +434,7 @@ static const MemoryRegionOps ioapic_io_ops = {
static void ioapic_machine_done_notify(Notifier *notifier, void *data)
{
-#ifdef ACCEL_KERNEL_GSI_IRQFD_POSSIBLE
+#ifdef ACCEL_GSI_IRQFD_POSSIBLE
IOAPICCommonState *s = container_of(notifier, IOAPICCommonState,
machine_done);
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 02/10] target/i386: emulate: Make sure fetch_instruction exist before calling it
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
2025-11-20 0:16 ` [PULL 01/10] ioapic: fix typo in irqfd check Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 03/10] target/i386: Mark VPERMILPS as not valid with prefix 0 Paolo Bonzini
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Nguyen Dinh Phi
From: Nguyen Dinh Phi <phind.uet@gmail.com>
Currently, this function is only available in MSHV. If a different accelerator
is used, and the code jumps to this section, a segfault will occur.
(I ran into this with HVF)
Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
Link: https://lore.kernel.org/r/20251114082915.71884-2-phind.uet@gmail.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/emulate/x86_decode.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/target/i386/emulate/x86_decode.c b/target/i386/emulate/x86_decode.c
index 97bd6f1a3be..d037ed11420 100644
--- a/target/i386/emulate/x86_decode.c
+++ b/target/i386/emulate/x86_decode.c
@@ -77,7 +77,11 @@ static inline uint64_t decode_bytes(CPUX86State *env, struct x86_decode *decode,
memcpy(&val, decode->stream->bytes + decode->len, size);
} else {
target_ulong va = linear_rip(env_cpu(env), env->eip) + decode->len;
- emul_ops->fetch_instruction(env_cpu(env), &val, va, size);
+ if (emul_ops->fetch_instruction) {
+ emul_ops->fetch_instruction(env_cpu(env), &val, va, size);
+ } else {
+ emul_ops->read_mem(env_cpu(env), &val, va, size);
+ }
}
decode->len += size;
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 03/10] target/i386: Mark VPERMILPS as not valid with prefix 0
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
2025-11-20 0:16 ` [PULL 01/10] ioapic: fix typo in irqfd check Paolo Bonzini
2025-11-20 0:16 ` [PULL 02/10] target/i386: emulate: Make sure fetch_instruction exist before calling it Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 04/10] target/i386/tcg: validate segment registers Paolo Bonzini
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, qemu-stable
From: Peter Maydell <peter.maydell@linaro.org>
There are a small set of binary SSE insns which have no MMX
equivalent, which we create the gen functions for with the
BINARY_INT_SSE() macro. This forwards to gen_binary_int_sse() with a
NULL pointer for 'mmx'.
For almost all of these insns we correctly mark them in the decode
table as not permitting a zero prefix byte; however we got this wrong
for VPERMILPS, with the result that a bogus instruction would get
through the decode checks and end up in gen_binary_int_sse() trying
to call a NULL pointer.
Correct the decode table entry for VPERMILPS so that we get the
expected #UD exception.
In the x86 SDM, table A-4 "Three-byte Opcode Map: 08H-FFH
(First Two Bytes are 0F 38H)" confirms that there is no pfx 0
version of VPERMILPS.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3199
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Link: https://lore.kernel.org/r/20251114175417.2794804-1-peter.maydell@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/decode-new.c.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index f4192f10068..805cfd08e83 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -643,7 +643,7 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = {
[0x0a] = X86_OP_ENTRY3(PSIGND, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66),
[0x0b] = X86_OP_ENTRY3(PMULHRSW, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66),
/* Listed incorrectly as type 4 */
- [0x0c] = X86_OP_ENTRY3(VPERMILPS, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX) p_00_66),
+ [0x0c] = X86_OP_ENTRY3(VPERMILPS, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
[0x0d] = X86_OP_ENTRY3(VPERMILPD, V,x, H,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
[0x0e] = X86_OP_ENTRY3(VTESTPS, None,None, V,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
[0x0f] = X86_OP_ENTRY3(VTESTPD, None,None, V,x, W,x, vex6 chk(W0) cpuid(AVX) p_66),
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 04/10] target/i386/tcg: validate segment registers
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (2 preceding siblings ...)
2025-11-20 0:16 ` [PULL 03/10] target/i386: Mark VPERMILPS as not valid with prefix 0 Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 05/10] target/i386: svm: fix sign extension of exit code Paolo Bonzini
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable
Correctly reject invalid segment registers, including CS when used as
the destination of a MOV. Ignore the REX prefix as well.
Fixes: 5e9e21bcc4d ("target/i386: move 60-BF opcodes to new decoder", 2024-05-07)
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3195
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/decode-new.c.inc | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 805cfd08e83..0f8c5d16938 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -2059,7 +2059,12 @@ static bool decode_op(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode,
case X86_TYPE_S: /* reg selects a segment register */
op->unit = X86_OP_SEG;
- goto get_reg;
+ op->n = (get_modrm(s, env) >> 3) & 7;
+ /* Values outside [CDEFGS]S, as well as storing to CS, are invalid. */
+ if (op->n >= 6 || (op->n == R_CS && op == &decode->op[0])) {
+ return false;
+ }
+ break;
case X86_TYPE_P:
op->unit = X86_OP_MMX;
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 05/10] target/i386: svm: fix sign extension of exit code
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (3 preceding siblings ...)
2025-11-20 0:16 ` [PULL 04/10] target/i386/tcg: validate segment registers Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 06/10] target/i386: fix stack size when delivering real mode interrupts Paolo Bonzini
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-stable
The exit_code parameter of cpu_vmexit is declared as uint32_t, but exit
codes are 64 bits wide according to the AMD SVM specification. And because
uint32_t is unsigned, this causes exit codes to be zero-extended, for example
writing SVM_EXIT_ERR as 0xffff_ffff instead of the expected 0xffff_ffff_ffff_ffff.
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2977
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/helper-tcg.h | 2 +-
target/i386/tcg/system/svm_helper.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index be011b06b7c..e41cbda407a 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -99,7 +99,7 @@ void cpu_load_eflags(CPUX86State *env, int eflags, int update_mask);
/* system/svm_helper.c */
#ifndef CONFIG_USER_ONLY
-G_NORETURN void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code,
+G_NORETURN void cpu_vmexit(CPUX86State *nenv, uint64_t exit_code,
uint64_t exit_info_1, uintptr_t retaddr);
void do_vmexit(CPUX86State *env);
#endif
diff --git a/target/i386/tcg/system/svm_helper.c b/target/i386/tcg/system/svm_helper.c
index 505788b0e26..4b86796518f 100644
--- a/target/i386/tcg/system/svm_helper.c
+++ b/target/i386/tcg/system/svm_helper.c
@@ -128,7 +128,7 @@ static inline bool virtual_gif_enabled(CPUX86State *env)
return false;
}
-static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint32_t exit_code, uintptr_t retaddr)
+static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint64_t exit_code, uintptr_t retaddr)
{
uint64_t lbr_ctl;
@@ -723,7 +723,7 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
}
}
-void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
+void cpu_vmexit(CPUX86State *env, uint64_t exit_code, uint64_t exit_info_1,
uintptr_t retaddr)
{
CPUState *cs = env_cpu(env);
@@ -732,7 +732,7 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016"
PRIx64 ", " TARGET_FMT_lx ")!\n",
- exit_code, exit_info_1,
+ (uint32_t)exit_code, exit_info_1,
x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
control.exit_info_2)),
env->eip);
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 06/10] target/i386: fix stack size when delivering real mode interrupts
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (4 preceding siblings ...)
2025-11-20 0:16 ` [PULL 05/10] target/i386: svm: fix sign extension of exit code Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 07/10] mtest2make: cleanup mtest-suites variables Paolo Bonzini
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel
The stack can be 32-bit even in real mode, and in this case
the stack pointer must be updated in its entirety rather than
just the bottom 16 bits. The same is true of real mode IRET,
for which there was even a comment suggesting the right thing
to do.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1506
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/seg_helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 667b1c38696..227336c4ef2 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -1161,7 +1161,7 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
sa.env = env;
sa.ra = 0;
sa.sp = env->regs[R_ESP];
- sa.sp_mask = 0xffff;
+ sa.sp_mask = get_sp_mask(env->segs[R_SS].flags);
sa.ss_base = env->segs[R_SS].base;
sa.mmu_index = x86_mmu_index_pl(env, 0);
@@ -1964,7 +1964,7 @@ void helper_iret_real(CPUX86State *env, int shift)
sa.env = env;
sa.ra = GETPC();
sa.mmu_index = x86_mmu_index_pl(env, 0);
- sa.sp_mask = 0xffff; /* XXXX: use SS segment size? */
+ sa.sp_mask = get_sp_mask(env->segs[R_SS].flags);
sa.sp = env->regs[R_ESP];
sa.ss_base = env->segs[R_SS].base;
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 07/10] mtest2make: cleanup mtest-suites variables
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (5 preceding siblings ...)
2025-11-20 0:16 ` [PULL 06/10] target/i386: fix stack size when delivering real mode interrupts Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 08/10] mtest2make: add dependencies to the "speed-qualified" suite Paolo Bonzini
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
Remove the "--suite" argument from the .*.mtest-suites variables, and
add it only when actually computing the arguments to "meson test".
This makes it possible to set ninja-cmd-goals from the set of suites,
instead of doing it via many different .ninja-goals.* variables.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
Makefile | 4 +++-
scripts/mtest2make.py | 40 +++++++++++++++++++---------------------
2 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/Makefile b/Makefile
index 74c2da20372..9fb55dcf330 100644
--- a/Makefile
+++ b/Makefile
@@ -96,6 +96,8 @@ meson.stamp: config-host.mak
# 3. ensure meson-generated build files are up-to-date
+ninja-cmd-goals =
+
ifneq ($(NINJA),)
Makefile.ninja: build.ninja
$(quiet-@){ \
@@ -150,7 +152,7 @@ NINJAFLAGS = \
$(or $(filter -l% -j%, $(MAKEFLAGS)), \
$(if $(filter --jobserver-auth=%, $(MAKEFLAGS)),, -j1))) \
-d keepdepfile
-ninja-cmd-goals = $(or $(MAKECMDGOALS), all)
+ninja-cmd-goals += $(or $(MAKECMDGOALS), all)
ninja-cmd-goals += $(foreach g, $(MAKECMDGOALS), $(.ninja-goals.$g))
makefile-targets := build.ninja ctags TAGS cscope dist clean
diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
index 2ef375fc6fb..d7c514243a5 100644
--- a/scripts/mtest2make.py
+++ b/scripts/mtest2make.py
@@ -8,24 +8,23 @@
import itertools
import json
import os
-import shlex
import sys
class Suite(object):
def __init__(self):
self.deps = set()
- self.speeds = ['quick']
+ self.speeds = []
def names(self, base):
- return [base if speed == 'quick' else f'{base}-{speed}' for speed in self.speeds]
+ return [f'{base}-{speed}' for speed in self.speeds]
-print('''
+print(r'''
SPEED = quick
-.speed.quick = $(foreach s,$(sort $(filter-out %-slow %-thorough, $1)), --suite $s)
-.speed.slow = $(foreach s,$(sort $(filter-out %-thorough, $1)), --suite $s)
-.speed.thorough = $(foreach s,$(sort $1), --suite $s)
+.speed.quick = $(sort $(filter-out %-slow %-thorough, $1))
+.speed.slow = $(sort $(filter-out %-thorough, $1))
+.speed.thorough = $(sort $1)
TIMEOUT_MULTIPLIER ?= 1
.mtestargs = --no-rebuild -t $(TIMEOUT_MULTIPLIER)
@@ -34,8 +33,10 @@ def names(self, base):
endif
.mtestargs += $(subst -j,--num-processes , $(filter-out -j, $(lastword -j1 $(filter -j%, $(MAKEFLAGS)))))
-.check.mtestargs = $(MTESTARGS) $(.mtestargs) $(if $(V),--verbose,--print-errorlogs)
-.bench.mtestargs = $(MTESTARGS) $(.mtestargs) --benchmark --verbose''')
+.check.mtestargs = $(MTESTARGS) $(.mtestargs) $(if $(V),--verbose,--print-errorlogs) \
+ $(foreach s, $(sort $(.check.mtest-suites)), --suite $s)
+.bench.mtestargs = $(MTESTARGS) $(.mtestargs) --benchmark --verbose \
+ $(foreach s, $(sort $(.bench.mtest-suites)), --suite $s)''')
introspect = json.load(sys.stdin)
@@ -72,29 +73,26 @@ def emit_prolog(suites, prefix):
print(f'all-{prefix}-targets = {all_targets}')
print(f'all-{prefix}-xml = {all_xml}')
print(f'.PHONY: {prefix} do-meson-{prefix} {prefix}-report.junit.xml $(all-{prefix}-targets) $(all-{prefix}-xml)')
- print(f'ifeq ($(filter {prefix}, $(MAKECMDGOALS)),)')
- print(f'.{prefix}.mtestargs += $(call .speed.$(SPEED), $(.{prefix}.mtest-suites))')
- print(f'endif')
+ print(f'ninja-cmd-goals += $(foreach s, $(.{prefix}.mtest-suites), $(.{prefix}-$s.deps))')
print(f'{prefix}-build: run-ninja')
print(f'{prefix} $(all-{prefix}-targets): do-meson-{prefix}')
print(f'do-meson-{prefix}: run-ninja; $(if $(MAKE.n),,+)$(MESON) test $(.{prefix}.mtestargs)')
print(f'{prefix}-report.junit.xml $(all-{prefix}-xml): {prefix}-report%.junit.xml: run-ninja')
print(f'\t$(MAKE) {prefix}$* MTESTARGS="$(MTESTARGS) --logbase {prefix}-report$*" && ln -f meson-logs/$@ .')
-def emit_suite_deps(name, suite, prefix):
+def emit_suite(name, suite, prefix):
deps = ' '.join(suite.deps)
- targets = [f'{prefix}-{name}', f'{prefix}-report-{name}.junit.xml', f'{prefix}', f'{prefix}-report.junit.xml',
- f'{prefix}-build']
print()
print(f'.{prefix}-{name}.deps = {deps}')
- for t in targets:
- print(f'.ninja-goals.{t} += $(.{prefix}-{name}.deps)')
+ print(f'.ninja-goals.check-build += $(.{prefix}-{name}.deps)')
-def emit_suite(name, suite, prefix):
- emit_suite_deps(name, suite, prefix)
- targets = f'{prefix}-{name} {prefix}-report-{name}.junit.xml {prefix} {prefix}-report.junit.xml'
+ names = ' '.join(suite.names(name))
+ targets = f'{prefix}-{name} {prefix}-report-{name}.junit.xml'
+ if not name.endswith('-slow') and not name.endswith('-thorough'):
+ targets += f' {prefix} {prefix}-report.junit.xml'
print(f'ifneq ($(filter {targets}, $(MAKECMDGOALS)),)')
- print(f'.{prefix}.mtest-suites += ' + ' '.join(suite.names(name)))
+ # for the "base" suite possibly add FOO-slow and FOO-thorough
+ print(f".{prefix}.mtest-suites += {name} $(call .speed.$(SPEED), {names})")
print(f'endif')
targets = {t['id']: [os.path.relpath(f) for f in t['filename']]
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 08/10] mtest2make: add dependencies to the "speed-qualified" suite
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (6 preceding siblings ...)
2025-11-20 0:16 ` [PULL 07/10] mtest2make: cleanup mtest-suites variables Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 09/10] mtest2make: do not repeat the same speed over and over Paolo Bonzini
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
Thorough tests may have more dependencies than faster ones.
Dependencies are now looked up based on the suites being
executed, not on the suites passed as goals to the makefile.
Therefore, it is possible to limit dependencies to the
speeds that need them.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/mtest2make.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
index d7c514243a5..38512046d97 100644
--- a/scripts/mtest2make.py
+++ b/scripts/mtest2make.py
@@ -58,13 +58,13 @@ def process_tests(test, targets, suites):
s = s.split(':')[1]
if s == 'slow' or s == 'thorough':
continue
+ suites[s].deps.update(deps)
if s.endswith('-slow'):
s = s[:-5]
suites[s].speeds.append('slow')
if s.endswith('-thorough'):
s = s[:-9]
suites[s].speeds.append('thorough')
- suites[s].deps.update(deps)
def emit_prolog(suites, prefix):
all_targets = ' '.join((f'{prefix}-{k}' for k in suites.keys()))
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 09/10] mtest2make: do not repeat the same speed over and over
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (7 preceding siblings ...)
2025-11-20 0:16 ` [PULL 08/10] mtest2make: add dependencies to the "speed-qualified" suite Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 0:16 ` [PULL 10/10] replay: add tracing events Paolo Bonzini
2025-11-20 21:56 ` [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Richard Henderson
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
There are just two of them (slow and thorough; quick is simply the
default). Avoid repeating them for as many times as there are tests.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
scripts/mtest2make.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
index 38512046d97..4b252defc3f 100644
--- a/scripts/mtest2make.py
+++ b/scripts/mtest2make.py
@@ -13,7 +13,7 @@
class Suite(object):
def __init__(self):
self.deps = set()
- self.speeds = []
+ self.speeds = set()
def names(self, base):
return [f'{base}-{speed}' for speed in self.speeds]
@@ -61,10 +61,10 @@ def process_tests(test, targets, suites):
suites[s].deps.update(deps)
if s.endswith('-slow'):
s = s[:-5]
- suites[s].speeds.append('slow')
+ suites[s].speeds.add('slow')
if s.endswith('-thorough'):
s = s[:-9]
- suites[s].speeds.append('thorough')
+ suites[s].speeds.add('thorough')
def emit_prolog(suites, prefix):
all_targets = ' '.join((f'{prefix}-{k}' for k in suites.keys()))
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PULL 10/10] replay: add tracing events
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (8 preceding siblings ...)
2025-11-20 0:16 ` [PULL 09/10] mtest2make: do not repeat the same speed over and over Paolo Bonzini
@ 2025-11-20 0:16 ` Paolo Bonzini
2025-11-20 21:56 ` [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Richard Henderson
10 siblings, 0 replies; 12+ messages in thread
From: Paolo Bonzini @ 2025-11-20 0:16 UTC (permalink / raw)
To: qemu-devel
The replay subsystem does not provide any way to see what's going on
and how the replay events interleave with other things happening in QEMU.
Add trace events to improve debuggability; to avoid having too many
events reimplement all functions in terms of (non-traced) replay_getc
and replay_putc and add a single trace event for each datum that is
extracted or written.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 1 +
replay/trace.h | 1 +
replay/replay-internal.c | 70 ++++++++++++++++++++++++++++++----------
replay/trace-events | 12 +++++++
4 files changed, 67 insertions(+), 17 deletions(-)
create mode 100644 replay/trace.h
create mode 100644 replay/trace-events
diff --git a/meson.build b/meson.build
index df4460035c3..95fcec9ba15 100644
--- a/meson.build
+++ b/meson.build
@@ -3678,6 +3678,7 @@ if have_system
'hw/gpio',
'migration',
'net',
+ 'replay',
'system',
'ui',
'hw/remote',
diff --git a/replay/trace.h b/replay/trace.h
new file mode 100644
index 00000000000..39ff481742e
--- /dev/null
+++ b/replay/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-replay.h"
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index c2a7200339f..4839f2b6321 100644
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -15,6 +15,7 @@
#include "replay-internal.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
+#include "trace.h"
/* Mutex to protect reading and writing events to the log.
data_kind and has_unread_data are also protected
@@ -44,7 +45,7 @@ static void replay_read_error(void)
exit(1);
}
-void replay_put_byte(uint8_t byte)
+static void replay_putc(uint8_t byte)
{
if (replay_file) {
if (putc(byte, replay_file) == EOF) {
@@ -53,29 +54,45 @@ void replay_put_byte(uint8_t byte)
}
}
+void replay_put_byte(uint8_t byte)
+{
+ trace_replay_put_byte(byte);
+ replay_putc(byte);
+}
+
void replay_put_event(uint8_t event)
{
+ trace_replay_put_event(event);
assert(event < EVENT_COUNT);
- replay_put_byte(event);
+ replay_putc(event);
}
void replay_put_word(uint16_t word)
{
- replay_put_byte(word >> 8);
- replay_put_byte(word);
+ trace_replay_put_word(word);
+ replay_putc(word >> 8);
+ replay_putc(word);
}
void replay_put_dword(uint32_t dword)
{
- replay_put_word(dword >> 16);
- replay_put_word(dword);
+ int i;
+
+ trace_replay_put_dword(dword);
+ for (i = 24; i >= 0; i -= 8) {
+ replay_putc(dword >> i);
+ }
}
void replay_put_qword(int64_t qword)
{
- replay_put_dword(qword >> 32);
- replay_put_dword(qword);
+ int i;
+
+ trace_replay_put_qword(qword);
+ for (i = 56; i >= 0; i -= 8) {
+ replay_putc(qword >> i);
+ }
}
void replay_put_array(const uint8_t *buf, size_t size)
@@ -88,7 +105,7 @@ void replay_put_array(const uint8_t *buf, size_t size)
}
}
-uint8_t replay_get_byte(void)
+static uint8_t replay_getc(void)
{
uint8_t byte = 0;
if (replay_file) {
@@ -101,36 +118,52 @@ uint8_t replay_get_byte(void)
return byte;
}
+uint8_t replay_get_byte(void)
+{
+ uint8_t byte = replay_getc();
+ trace_replay_get_byte(byte);
+ return byte;
+}
+
uint16_t replay_get_word(void)
{
uint16_t word = 0;
if (replay_file) {
- word = replay_get_byte();
- word = (word << 8) + replay_get_byte();
+ word = replay_getc();
+ word = (word << 8) + replay_getc();
}
+ trace_replay_get_word(word);
return word;
}
uint32_t replay_get_dword(void)
{
uint32_t dword = 0;
+ int i;
+
if (replay_file) {
- dword = replay_get_word();
- dword = (dword << 16) + replay_get_word();
+ for (i = 24; i >= 0; i -= 8) {
+ dword |= replay_getc() << i;
+ }
}
+ trace_replay_get_dword(dword);
return dword;
}
int64_t replay_get_qword(void)
{
- int64_t qword = 0;
+ uint64_t qword = 0;
+ int i;
+
if (replay_file) {
- qword = replay_get_dword();
- qword = (qword << 32) + replay_get_dword();
+ for (i = 56; i >= 0; i -= 8) {
+ qword |= (uint64_t)replay_getc() << i;
+ }
}
+ trace_replay_get_qword(qword);
return qword;
}
@@ -172,10 +205,12 @@ void replay_check_error(void)
void replay_fetch_data_kind(void)
{
+ trace_replay_fetch_data_kind();
if (replay_file) {
if (!replay_state.has_unread_data) {
- replay_state.data_kind = replay_get_byte();
+ replay_state.data_kind = replay_getc();
replay_state.current_event++;
+ trace_replay_get_event(replay_state.current_event, replay_state.data_kind);
if (replay_state.data_kind == EVENT_INSTRUCTION) {
replay_state.instruction_count = replay_get_dword();
}
@@ -246,6 +281,7 @@ void replay_advance_current_icount(uint64_t current_icount)
int diff = (int)(current_icount - replay_state.current_icount);
/* Time can only go forward */
+ trace_replay_advance_current_icount(replay_state.current_icount, diff);
assert(diff >= 0);
if (replay_mode == REPLAY_MODE_RECORD) {
diff --git a/replay/trace-events b/replay/trace-events
new file mode 100644
index 00000000000..e9c887a6c57
--- /dev/null
+++ b/replay/trace-events
@@ -0,0 +1,12 @@
+replay_put_byte(uint8_t event) "%02x"
+replay_put_event(uint8_t event) "%02x"
+replay_put_word(uint16_t event) "%04x"
+replay_put_dword(uint32_t event) "%08x"
+replay_put_qword(uint64_t event) "%016" PRIx64
+replay_get_byte(uint8_t byte) "%02x"
+replay_get_word(uint16_t word) "%04x"
+replay_get_dword(uint32_t dword) "%08x"
+replay_get_qword(uint64_t qword) "%016" PRIx64
+replay_fetch_data_kind(void) ""
+replay_get_event(uint32_t current, uint8_t data) "#%u data=%02x"
+replay_advance_current_icount(uint64_t current_icount, int diff) "current=%" PRIu64 " diff=%d"
--
2.51.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PULL 00/10] x86, mtest2make changes for QEMU 10.2
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
` (9 preceding siblings ...)
2025-11-20 0:16 ` [PULL 10/10] replay: add tracing events Paolo Bonzini
@ 2025-11-20 21:56 ` Richard Henderson
10 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2025-11-20 21:56 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel
On 11/20/25 01:16, Paolo Bonzini wrote:
> The following changes since commit e88510fcdc13380bd4895a17d6f8a0b3a3325b85:
>
> Merge tag 'pull-target-arm-20251114' ofhttps://gitlab.com/pm215/qemu into staging (2025-11-14 17:59:05 +0100)
>
> are available in the Git repository at:
>
> https://gitlab.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 58f88d0bf7c4c0676b54f97ba91eecccbca968c9:
>
> replay: add tracing events (2025-11-19 09:24:01 +0100)
>
> ----------------------------------------------------------------
> * i386 fixes
> * mtest2make cleanups to enable per-speed dependencies
> * record/replay tracepoints
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-11-20 21:57 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-20 0:16 [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Paolo Bonzini
2025-11-20 0:16 ` [PULL 01/10] ioapic: fix typo in irqfd check Paolo Bonzini
2025-11-20 0:16 ` [PULL 02/10] target/i386: emulate: Make sure fetch_instruction exist before calling it Paolo Bonzini
2025-11-20 0:16 ` [PULL 03/10] target/i386: Mark VPERMILPS as not valid with prefix 0 Paolo Bonzini
2025-11-20 0:16 ` [PULL 04/10] target/i386/tcg: validate segment registers Paolo Bonzini
2025-11-20 0:16 ` [PULL 05/10] target/i386: svm: fix sign extension of exit code Paolo Bonzini
2025-11-20 0:16 ` [PULL 06/10] target/i386: fix stack size when delivering real mode interrupts Paolo Bonzini
2025-11-20 0:16 ` [PULL 07/10] mtest2make: cleanup mtest-suites variables Paolo Bonzini
2025-11-20 0:16 ` [PULL 08/10] mtest2make: add dependencies to the "speed-qualified" suite Paolo Bonzini
2025-11-20 0:16 ` [PULL 09/10] mtest2make: do not repeat the same speed over and over Paolo Bonzini
2025-11-20 0:16 ` [PULL 10/10] replay: add tracing events Paolo Bonzini
2025-11-20 21:56 ` [PULL 00/10] x86, mtest2make changes for QEMU 10.2 Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).