Hi,
in testing qemu 10.1 since rc levels I've found yet another odd
behavior. As far as I can tell it's not your fault, but I wanted to
tell you for awareness and potentially to help me get the right debug
data.

A test that triggered when checking Ubuntu was the one of EDK2,
emulating riscv when running on ppc64, example log [1]. Yep, yet again
not the most common setup :-) and the same emulation in all other
Ubuntu architectures as host works fine.
Gladly this was reproducible and it eventually led me to a wild
journey which now makes me consider gcc-15 (15.2.0-1ubuntu1) as the
suspect here.

After confirming that I spotted that it only happens if qemu is
compiled with a particular optimization option.

The issue itself is as weird as jumping into an if, despite the
condition not being met :-/

Thread 3 "qemu-system-ris" hit Breakpoint 1,
riscv_pmu_icount_update_priv (env=0x10147c310, newpriv=1,
new_virt=false) at ../target/riscv/pmu.c:200
200 if (icount_enabled()) {
(gdb) n
203 current_icount = cpu_get_host_ticks();
(gdb) n
206 if (env->virt_enabled) {
(gdb) n
211 counter_arr = env->pmu_fixed_ctrs[1].counter;
(gdb) n
212 snapshot_prev = env->pmu_fixed_ctrs[1].counter_prev;
(gdb) n
215 if (new_virt) {
(gdb) n
216 g_assert(newpriv <= PRV_S);
(gdb) p new_virt
$1 = false

Since I know the arch, the function and the tunable - I can use a
rather surgical mitigation like this.

diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index a68809eef3..5317d8be57 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -189,6 +189,13 @@ static int riscv_pmu_incr_ctr_rv64(RISCVCPU *cpu,
uint32_t ctr_idx)
  * env->priv and env->virt_enabled contain old priv and old virt and
  * new priv and new virt values are passed in as arguments.
  */
+#if defined(__powerpc64__) || defined(__ppc64__)
+ #define NO_GCSE_ATTR __attribute__((optimize("no-gcse")))
+#else
+ #define NO_GCSE_ATTR
+#endif
+
+NO_GCSE_ATTR
 static void riscv_pmu_icount_update_priv(CPURISCVState *env,
                                          target_ulong newpriv, bool new_virt)
 {

But a mitigation is all that it is, ideally, I'd report this as a gcc bug.
Yet the - understandable - hard requirement of getting the
pre-processed files makes this quite complex. As I can't even exactly
point to where exactly things go wrong.
I'd ask if one of you has experience in providing gcc-bugs out of a
qemu build. Is it as obvious as throwing -save-temps into *flags or is
there more to consider get what would be needed?

P.S. If you are curious and want debug binaries and the journey to
find this, it is all at the related Ubuntu bug [2]

[1]: 
https://autopkgtest.ubuntu.com/results/autopkgtest-questing/questing/ppc64el/e/edk2/20250818_045238_153f0@/log.gz
[2]: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/2120835

-- 
Christian Ehrhardt
Director of Engineering, Ubuntu Server
Canonical Ltd

Reply via email to