* [PULL 1/2] linux-user: don't print core dump message by default
2026-10-15 20:02 [PULL 0/2] Linux user next patches Helge Deller
@ 2026-10-15 20:02 ` Helge Deller
2026-10-15 20:02 ` [PULL 2/2] linux-user/riscv: preserve rs1 address for cbo.zero fault reporting Helge Deller
2026-10-16 6:00 ` [PULL 0/2] Linux user next patches Richard Henderson
2 siblings, 0 replies; 4+ messages in thread
From: Helge Deller @ 2026-10-15 20:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Schwab, wangyang, Helge Deller
From: Andreas Schwab <schwab@suse.de>
When the target binary is killed by a signal with core dump print a
message to the guest_errors log instead of stderr. This avoids breaking
various testsuites due to the extra output produced by the emulation.
Signed-off-by: Andreas Schwab <schwab@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/signal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index f0a22577e5..cabcc2bb28 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -839,8 +839,8 @@ void dump_core_and_abort(CPUArchState *env, int target_sig)
getrlimit(RLIMIT_CORE, &nodump);
nodump.rlim_cur=0;
setrlimit(RLIMIT_CORE, &nodump);
- (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) - %s\n",
- target_sig, strsignal(host_sig), "core dumped" );
+ qemu_log_mask(LOG_GUEST_ERROR, "qemu: uncaught target signal %d (%s) - %s\n",
+ target_sig, strsignal(host_sig), "core dumped" );
}
preexit_cleanup(env, 128 + target_sig);
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PULL 2/2] linux-user/riscv: preserve rs1 address for cbo.zero fault reporting
2026-10-15 20:02 [PULL 0/2] Linux user next patches Helge Deller
2026-10-15 20:02 ` [PULL 1/2] linux-user: don't print core dump message by default Helge Deller
@ 2026-10-15 20:02 ` Helge Deller
2026-10-16 6:00 ` [PULL 0/2] Linux user next patches Richard Henderson
2 siblings, 0 replies; 4+ messages in thread
From: Helge Deller @ 2026-10-15 20:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Schwab, wangyang, Helge Deller
From: wangyang <wangyang25@otcaix.iscas.ac.cn>
helper_cbo_zero() aligns the address down to the cache-block size before
probe_write(), and accel/tcg/user-exec.c:probe_access_internal() reports
that aligned address to cpu_loop_exit_sigsegv(), so a store fault from a
legal cbo.zero (e.g. on a read-only page) reports the aligned block base
as si_addr instead of the rs1 value supplied by the program. Native
RISC-V Linux reports the exact rs1 address. Keep the original address in
CPUState and use it when the fault is reported.
The saved address must not outlive the instruction that produced it. The
helper alone cannot guarantee that, because a store trigger or
breakpoint on the cbo.zero access leaves through the debug path instead
of one of the four fault consumers, and a later unrelated fault would
then report the stale cbo.zero address. Also drop the pending override
on every trap delivery: at the top of riscv_cpu_do_interrupt() and in
riscv_cpu_debug_excp_handler() for system mode, and right after
cpu_exec() returns in the linux-user cpu loop.
Tested: the read-only-page reproducer reports rs1 for offsets 1, 65 and
129; an mcontrol store-trigger reproducer reports the follow-up load's
own access-fault address instead of the earlier cbo.zero rs1.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4151
Suggested-by: David Harris <david.harris@gitlab.com>
Signed-off-by: wangyang <wangyang25@otcaix.iscas.ac.cn>
Signed-off-by: Helge Deller <deller@gmx.de>
---
accel/tcg/user-exec.c | 7 ++++++-
include/hw/core/cpu.h | 2 ++
linux-user/riscv/cpu_loop.c | 3 +++
target/riscv/tcg/cpu_helper.c | 27 ++++++++++++++++++++++++---
target/riscv/tcg/debug.c | 3 +++
target/riscv/tcg/op_helper.c | 5 +++++
6 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index a35aca7889..13c3845811 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -787,7 +787,12 @@ static int probe_access_internal(CPUArchState *env, vaddr addr,
return TLB_INVALID_MASK;
}
- cpu_loop_exit_sigsegv(env_cpu(env), addr, access_type, maperr, ra);
+ CPUState *cpu = env_cpu(env);
+ if (cpu->exception_addr_valid) {
+ addr = cpu->exception_addr;
+ cpu->exception_addr_valid = false;
+ }
+ cpu_loop_exit_sigsegv(cpu, addr, access_type, maperr, ra);
}
int probe_access_flags(CPUArchState *env, vaddr addr, int size,
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index ae66f5e33e..1fd68367f6 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -560,6 +560,8 @@ struct CPUState {
uint32_t tcg_cflags;
uint32_t halted;
int32_t exception_index;
+ vaddr exception_addr;
+ bool exception_addr_valid;
bool vcpu_dirty;
AccelCPUState *accel;
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 6f27a06da4..dbf1d42d33 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -38,6 +38,9 @@ void cpu_loop(CPURISCVState *env)
cpu_exec_end(cs);
qemu_process_cpu_events(cs);
+ /* A trap ends the pending cbo.zero address override window. */
+ cs->exception_addr_valid = false;
+
switch (trapnr) {
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c
index 07d9222652..4513c9bdbe 100644
--- a/target/riscv/tcg/cpu_helper.c
+++ b/target/riscv/tcg/cpu_helper.c
@@ -1537,7 +1537,12 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
default:
g_assert_not_reached();
}
- env->badaddr = address;
+ if (cs->exception_addr_valid) {
+ env->badaddr = cs->exception_addr;
+ cs->exception_addr_valid = false;
+ } else {
+ env->badaddr = address;
+ }
env->two_stage_lookup = two_stage;
env->two_stage_indirect_lookup = two_stage_indirect;
}
@@ -1588,7 +1593,12 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
}
- env->badaddr = addr;
+ if (cs->exception_addr_valid) {
+ env->badaddr = cs->exception_addr;
+ cs->exception_addr_valid = false;
+ } else {
+ env->badaddr = addr;
+ }
env->two_stage_lookup = mmuidx_2stage(mmu_idx);
env->two_stage_indirect_lookup = false;
cpu_loop_exit_restore(cs, retaddr);
@@ -1621,7 +1631,12 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
default:
g_assert_not_reached();
}
- env->badaddr = addr;
+ if (cs->exception_addr_valid) {
+ env->badaddr = cs->exception_addr;
+ cs->exception_addr_valid = false;
+ } else {
+ env->badaddr = addr;
+ }
env->two_stage_lookup = mmuidx_2stage(mmu_idx);
env->two_stage_indirect_lookup = false;
cpu_loop_exit_restore(cs, retaddr);
@@ -2047,6 +2062,12 @@ void riscv_cpu_do_interrupt(CPUState *cs)
{
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
+
+ /*
+ * A trap ends the pending cbo.zero address override window, so drop
+ * any saved rs1 that a store trigger or breakpoint left behind.
+ */
+ cs->exception_addr_valid = false;
bool virt = env->virt_enabled;
bool write_gva = false;
bool always_storeamo = (env->excp_uw2 & RISCV_UW2_ALWAYS_STORE_AMO);
diff --git a/target/riscv/tcg/debug.c b/target/riscv/tcg/debug.c
index e4d719a1da..6962557251 100644
--- a/target/riscv/tcg/debug.c
+++ b/target/riscv/tcg/debug.c
@@ -973,6 +973,9 @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
+ /* A debug exit ends the cbo.zero address override window too. */
+ cs->exception_addr_valid = false;
+
if (cs->watchpoint_hit) {
if (cs->watchpoint_hit->flags & BP_CPU) {
do_trigger_action(env, DBG_ACTION_BP);
diff --git a/target/riscv/tcg/op_helper.c b/target/riscv/tcg/op_helper.c
index b67c7718db..3fc993a207 100644
--- a/target/riscv/tcg/op_helper.c
+++ b/target/riscv/tcg/op_helper.c
@@ -188,9 +188,13 @@ void helper_cbo_zero(CPURISCVState *env, target_ulong address)
int mmu_idx = riscv_env_mmu_index(env, false);
uintptr_t ra = GETPC();
void *mem;
+ CPUState *cs = env_cpu(env);
check_zicbo_envcfg(env, MENVCFG_CBZE, ra);
+ cs->exception_addr = address;
+ cs->exception_addr_valid = true;
+
/* Mask off low-bits to align-down to the cache-block. */
address &= ~(cbozlen - 1);
@@ -218,6 +222,7 @@ void helper_cbo_zero(CPURISCVState *env, target_ulong address)
cpu_stb_mmuidx_ra(env, address + i, 0, mmu_idx, ra);
}
}
+ cs->exception_addr_valid = false;
}
/*
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread