All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/18] Misc target/ patches for 2026-09-24
@ 2026-09-24 15:23 Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 01/18] target/mips: Fix zero in gen_mxu_d8sum Philippe Mathieu-Daudé
                   ` (18 more replies)
  0 siblings, 19 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit 942229961efea74b153c44c59188eb08375f10f1:

  Merge tag 'pull-tcg-20260923-v2' of https://gitlab.com/rth7680/qemu into staging (2026-09-23 15:14:55 -0700)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/target-misc-20260924

for you to fetch changes up to cbbd4d74eb298e2b407018185a40cb813435527e:

  target/ppc: Stop vCPU thread before calling parent_unrealize (2026-09-24 17:22:06 +0200)

----------------------------------------------------------------
Misc target patches queue

- DOC: Improve SysemuCPUOps::has_work docstring
- MIPS: Let TCG middle-end optimize MXU opcodes (not front-end)
- S390x: Access S390CpuState atomically
- ARM: Access halt/PSCI states atomically
- X86: Access interrupt_request atomically
- PPC: Fix double-free in ppc_cpu_unrealize()
----------------------------------------------------------------

Anton Johansson (1):
  target/riscv: Stub out kvm functions

Janosch Frank (1):
  target/s390x: Extend comment about PV cpu load state

Philippe Mathieu-Daudé (9):
  system: Document has_work() synchronization requirements
  target/s390x: Use s390_cpu_get_state() consistently
  target/s390x: Make s390_cpu_set_state() return void
  target/s390x: Use S390CpuState for CPU state APIs
  target/s390x: Access S390CpuState atomically
  target/arm: Un-inline arm_set_cpu_power_state()
  target/arm: Access PSCI state atomically
  target/arm: Access halt state atomically
  target/i386: Use an acquire load for interrupt_request()

Richard Henderson (6):
  target/mips: Fix zero in gen_mxu_d8sum
  target/mips: Drop zero optimization in gen_mxu_s32mul
  target/mips: Split out gen_mxu_logic
  target/mips: Use gen_mxu_logic for gen_mxu_S32MAX_S32MIN
  target/mips: Use gen_mxu_logic for gen_mxu_S32SLT
  target/mips: Use gen_mxu_logic for gen_mxu_S32CPS

Shivang Upadhyay (1):
  target/ppc: Stop vCPU thread before calling parent_unrealize

 include/hw/core/sysemu-cpu-ops.h |   6 +-
 target/arm/internals.h           |   8 +-
 target/s390x/cpu.h               |   9 +-
 target/s390x/kvm/kvm_s390x.h     |   2 +-
 hw/intc/s390_flic.c              |   7 +-
 target/arm/arm-powerctl.c        |   7 +
 target/arm/cpu.c                 |  13 +-
 target/arm/tcg/op_helper.c       |   8 +-
 target/i386/cpu.c                |   4 +-
 target/mips/tcg/mxu_translate.c  | 265 +++++++------------------------
 target/ppc/cpu_init.c            |   4 +-
 target/riscv/kvm/kvm-stub.c      |  23 +++
 target/s390x/cpu-system.c        |  32 ++--
 target/s390x/cpu.c               |   2 +-
 target/s390x/kvm/kvm.c           |   4 +-
 target/s390x/kvm/stubs.c         |   2 +-
 target/s390x/machine.c           |   2 +-
 target/s390x/sigp.c              |   9 +-
 target/riscv/kvm/meson.build     |   1 +
 target/riscv/meson.build         |   3 +
 20 files changed, 156 insertions(+), 255 deletions(-)
 create mode 100644 target/riscv/kvm/kvm-stub.c

-- 
2.53.0



^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PULL 01/18] target/mips: Fix zero in gen_mxu_d8sum
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 02/18] target/mips: Drop zero optimization in gen_mxu_s32mul Philippe Mathieu-Daudé
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

This is obviously an attempt to set temps to 0,
but accidentally passed NULL to a regular move.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260914230901.1781309-2-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/mips/tcg/mxu_translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 7961b073144..9559b8aada3 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -3109,7 +3109,7 @@ static void gen_mxu_d8sum(DisasContext *ctx, bool sumc)
             tcg_gen_add_i32(t4, t4, t2);
             tcg_gen_add_i32(t4, t4, t3);
         } else {
-            tcg_gen_mov_i32(t4, 0);
+            tcg_gen_movi_i32(t4, 0);
         }
         if (XRc != 0) {
             tcg_gen_extract_i32(t0, mxu_gpr[XRc - 1],  0, 8);
@@ -3120,7 +3120,7 @@ static void gen_mxu_d8sum(DisasContext *ctx, bool sumc)
             tcg_gen_add_i32(t5, t5, t2);
             tcg_gen_add_i32(t5, t5, t3);
         } else {
-            tcg_gen_mov_i32(t5, 0);
+            tcg_gen_movi_i32(t5, 0);
         }
 
         if (sumc) {
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 02/18] target/mips: Drop zero optimization in gen_mxu_s32mul
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 01/18] target/mips: Fix zero in gen_mxu_d8sum Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 03/18] target/mips: Split out gen_mxu_logic Philippe Mathieu-Daudé
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

In the unlikely event of the architecturally valid case
of using the zero register as a multiply input, this will
be folded away during optimize.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260914230901.1781309-3-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/mips/tcg/mxu_translate.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 9559b8aada3..f30883f976f 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -964,18 +964,13 @@ static void gen_mxu_s32mul(DisasContext *ctx, bool mulu)
     rs  = extract32(ctx->opcode, 16, 5);
     rt  = extract32(ctx->opcode, 21, 5);
 
-    if (unlikely(rs == 0 || rt == 0)) {
-        tcg_gen_movi_i32(t0, 0);
-        tcg_gen_movi_i32(t1, 0);
-    } else {
-        gen_load_gpr(t0, rs);
-        gen_load_gpr(t1, rt);
+    gen_load_gpr(t0, rs);
+    gen_load_gpr(t1, rt);
 
-        if (mulu) {
-            tcg_gen_mulu2_i32(t0, t1, t0, t1);
-        } else {
-            tcg_gen_muls2_i32(t0, t1, t0, t1);
-        }
+    if (mulu) {
+        tcg_gen_mulu2_i32(t0, t1, t0, t1);
+    } else {
+        tcg_gen_muls2_i32(t0, t1, t0, t1);
     }
     tcg_gen_mov_i32(cpu_HI[0], t1);
     tcg_gen_mov_i32(cpu_LO[0], t0);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 03/18] target/mips: Split out gen_mxu_logic
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 01/18] target/mips: Fix zero in gen_mxu_d8sum Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 02/18] target/mips: Drop zero optimization in gen_mxu_s32mul Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 04/18] target/mips: Use gen_mxu_logic for gen_mxu_S32MAX_S32MIN Philippe Mathieu-Daudé
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

Split out a helper for common expansion of a 3-operand insns.
Drop all the special cases for 0 and let the optimizer handle them.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260914230901.1781309-4-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/mips/tcg/mxu_translate.c | 122 +++++++-------------------------
 1 file changed, 24 insertions(+), 98 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index f30883f976f..3f8acfcdb8f 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -1685,14 +1685,11 @@ static void gen_mxu_s32stxvx(DisasContext *ctx, bool reversed,
  *               S32NOR    S32AND    S32OR    S32XOR
  */
 
-/*
- *  S32NOR XRa, XRb, XRc
- *    Update XRa with the result of logical bitwise 'nor' operation
- *    applied to the content of XRb and XRc.
- */
-static void gen_mxu_S32NOR(DisasContext *ctx)
+static void gen_mxu_logic(DisasContext *ctx,
+                          void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
 {
     uint32_t pad, XRc, XRb, XRa;
+    TCGv_i32 t0, t1;
 
     pad = extract32(ctx->opcode, 21, 5);
     XRc = extract32(ctx->opcode, 14, 4);
@@ -1701,24 +1698,25 @@ static void gen_mxu_S32NOR(DisasContext *ctx)
 
     if (unlikely(pad != 0)) {
         /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 1s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just set destination to the negation of XRc */
-        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-    } else if (unlikely(XRc == 0)) {
-        /* XRa zero register -> just set destination to the negation of XRb */
-        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to the negation of XRb */
-        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
+        return;
     }
+
+    t0 = tcg_temp_new_i32();
+    t1 = tcg_temp_new_i32();
+    gen_load_mxu_gpr(t0, XRb);
+    gen_load_mxu_gpr(t1, XRc);
+    gen(t0, t0, t1);
+    gen_store_mxu_gpr(t0, XRa);
+}
+
+/*
+ *  S32NOR XRa, XRb, XRc
+ *    Update XRa with the result of logical bitwise 'nor' operation
+ *    applied to the content of XRb and XRc.
+ */
+static void gen_mxu_S32NOR(DisasContext *ctx)
+{
+    gen_mxu_logic(ctx, tcg_gen_nor_i32);
 }
 
 /*
@@ -1728,27 +1726,7 @@ static void gen_mxu_S32NOR(DisasContext *ctx)
  */
 static void gen_mxu_S32AND(DisasContext *ctx)
 {
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) || (XRc == 0))) {
-        /* one of operands zero register -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
+    gen_mxu_logic(ctx, tcg_gen_and_i32);
 }
 
 /*
@@ -1758,33 +1736,7 @@ static void gen_mxu_S32AND(DisasContext *ctx)
  */
 static void gen_mxu_S32OR(DisasContext *ctx)
 {
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just set destination to the content of XRc */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-    } else if (unlikely(XRc == 0)) {
-        /* XRc zero register -> just set destination to the content of XRb */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
+    gen_mxu_logic(ctx, tcg_gen_or_i32);
 }
 
 /*
@@ -1794,33 +1746,7 @@ static void gen_mxu_S32OR(DisasContext *ctx)
  */
 static void gen_mxu_S32XOR(DisasContext *ctx)
 {
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == 0)) {
-        /* XRb zero register -> just set destination to the content of XRc */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
-    } else if (unlikely(XRc == 0)) {
-        /* XRc zero register -> just set destination to the content of XRb */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to all 0s */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else {
-        /* the most general case */
-        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
-    }
+    gen_mxu_logic(ctx, tcg_gen_xor_i32);
 }
 
 /*
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 04/18] target/mips: Use gen_mxu_logic for gen_mxu_S32MAX_S32MIN
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (2 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 03/18] target/mips: Split out gen_mxu_logic Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 05/18] target/mips: Use gen_mxu_logic for gen_mxu_S32SLT Philippe Mathieu-Daudé
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

Split S32MAX, S32MIN to separate functions.
Fixes a bug in that "0" was passed in one of the zero reg cases,
aka NULL, instead of a proper zero constant.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260914230901.1781309-5-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/mips/tcg/mxu_translate.c | 47 +++++++--------------------------
 1 file changed, 9 insertions(+), 38 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 3f8acfcdb8f..4b2c264f031 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -2045,45 +2045,14 @@ static void gen_mxu_q16sxxv(DisasContext *ctx, bool right, bool arithmetic)
  *    Update XRa with the minimum of signed 32-bit integers contained
  *    in XRb and XRc.
  */
-static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
+static void gen_mxu_S32MAX(DisasContext *ctx)
 {
-    uint32_t pad, opc, XRc, XRb, XRa;
+    gen_mxu_logic(ctx, tcg_gen_smax_i32);
+}
 
-    pad = extract32(ctx->opcode, 21, 5);
-    opc = extract32(ctx->opcode, 18, 3);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely((XRb == 0) || (XRc == 0))) {
-        /* exactly one operand is zero register - find which one is not...*/
-        uint32_t XRx = XRb ? XRb : XRc;
-        /* ...and do max/min operation with one operand 0 */
-        if (opc == OPC_MXU_S32MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
-        }
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same -> just set destination to one of them */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        if (opc == OPC_MXU_S32MAX) {
-            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
-                                               mxu_gpr[XRc - 1]);
-        } else {
-            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
-                                               mxu_gpr[XRc - 1]);
-        }
-    }
+static void gen_mxu_S32MIN(DisasContext *ctx)
+{
+    gen_mxu_logic(ctx, tcg_gen_smin_i32);
 }
 
 /*
@@ -4328,8 +4297,10 @@ static void decode_opc_mxu__pool00(DisasContext *ctx)
 
     switch (opcode) {
     case OPC_MXU_S32MAX:
+        gen_mxu_S32MAX(ctx);
+        break;
     case OPC_MXU_S32MIN:
-        gen_mxu_S32MAX_S32MIN(ctx);
+        gen_mxu_S32MIN(ctx);
         break;
     case OPC_MXU_D16MAX:
     case OPC_MXU_D16MIN:
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 05/18] target/mips: Use gen_mxu_logic for gen_mxu_S32SLT
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (3 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 04/18] target/mips: Use gen_mxu_logic for gen_mxu_S32MAX_S32MIN Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 06/18] target/mips: Use gen_mxu_logic for gen_mxu_S32CPS Philippe Mathieu-Daudé
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260914230901.1781309-6-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/mips/tcg/mxu_translate.c | 33 +++++++--------------------------
 1 file changed, 7 insertions(+), 26 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 4b2c264f031..293eeb46c23 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -2313,34 +2313,15 @@ static void gen_mxu_q8slt(DisasContext *ctx, bool sltu)
  *    Update XRa with the signed "set less than" comparison of XRb and XRc.
  *    a.k.a. XRa = XRb < XRc ? 1 : 0;
  */
+
+static void gen_setcond_lt_i32(TCGv_i32 d, TCGv_i32 s1, TCGv_i32 s2)
+{
+    tcg_gen_setcond_i32(TCG_COND_LT, d, s1, s2);
+}
+
 static void gen_mxu_S32SLT(DisasContext *ctx)
 {
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely((XRb == 0) && (XRc == 0))) {
-        /* both operands zero registers -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRb == XRc)) {
-        /* both operands same registers -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else {
-        /* the most general case */
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        TCGv_i32 t1 = tcg_temp_new_i32();
-
-        gen_load_mxu_gpr(t0, XRb);
-        gen_load_mxu_gpr(t1, XRc);
-        tcg_gen_setcond_i32(TCG_COND_LT, mxu_gpr[XRa - 1], t0, t1);
-    }
+    gen_mxu_logic(ctx, gen_setcond_lt_i32);
 }
 
 /*
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 06/18] target/mips: Use gen_mxu_logic for gen_mxu_S32CPS
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (4 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 05/18] target/mips: Use gen_mxu_logic for gen_mxu_S32SLT Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 07/18] target/riscv: Stub out kvm functions Philippe Mathieu-Daudé
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Richard Henderson <richard.henderson@linaro.org>

Use movcond instead of a pair of branches to perform
the computation, packed in a new gen_cps_i32.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260914230901.1781309-7-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/mips/tcg/mxu_translate.c | 42 +++++++++------------------------
 1 file changed, 11 insertions(+), 31 deletions(-)

diff --git a/target/mips/tcg/mxu_translate.c b/target/mips/tcg/mxu_translate.c
index 293eeb46c23..a38f4da12ba 100644
--- a/target/mips/tcg/mxu_translate.c
+++ b/target/mips/tcg/mxu_translate.c
@@ -2640,39 +2640,19 @@ static void gen_mxu_s32movzn(DisasContext *ctx, TCGCond cond)
  *    Update XRa if XRc < 0 by value of 0 - XRb
  *    else XRa = XRb
  */
+
+static void gen_cps_i32(TCGv_i32 a, TCGv_i32 b, TCGv_i32 c)
+{
+    TCGv_i32 n = tcg_temp_new_i32();
+    TCGv_i32 z = tcg_constant_i32(0);
+
+    tcg_gen_neg_i32(n, b);
+    tcg_gen_movcond_i32(TCG_COND_LT, a, c, z, n, b);
+}
+
 static void gen_mxu_S32CPS(DisasContext *ctx)
 {
-    uint32_t pad, XRc, XRb, XRa;
-
-    pad = extract32(ctx->opcode, 21, 5);
-    XRc = extract32(ctx->opcode, 14, 4);
-    XRb = extract32(ctx->opcode, 10, 4);
-    XRa = extract32(ctx->opcode,  6, 4);
-
-    if (unlikely(pad != 0)) {
-        /* opcode padding incorrect -> do nothing */
-    } else if (unlikely(XRa == 0)) {
-        /* destination is zero register -> do nothing */
-    } else if (unlikely(XRb == 0)) {
-        /* XRc make no sense 0 - 0 = 0 -> just set destination to zero */
-        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
-    } else if (unlikely(XRc == 0)) {
-        /* condition always false -> just move XRb to XRa */
-        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
-    } else {
-        /* the most general case */
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        TCGLabel *l_not_less = gen_new_label();
-        TCGLabel *l_done = gen_new_label();
-
-        tcg_gen_brcondi_i32(TCG_COND_GE, mxu_gpr[XRc - 1], 0, l_not_less);
-        tcg_gen_neg_i32(t0, mxu_gpr[XRb - 1]);
-        tcg_gen_br(l_done);
-        gen_set_label(l_not_less);
-        gen_load_mxu_gpr(t0, XRb);
-        gen_set_label(l_done);
-        gen_store_mxu_gpr(t0, XRa);
-    }
+    gen_mxu_logic(ctx, gen_cps_i32);
 }
 
 /*
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 07/18] target/riscv: Stub out kvm functions
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (5 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 06/18] target/mips: Use gen_mxu_logic for gen_mxu_S32CPS Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 08/18] system: Document has_work() synchronization requirements Philippe Mathieu-Daudé
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Anton Johansson <anjo@rev.ng>

Functions used externally by hw/riscv are stubbed out for non-kvm
configurations, allowing a single compilation of hw/riscv.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Anton Johansson <anjo@rev.ng>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260918-hw-riscv-cpu-int-v5-5-f98c5a244636@rev.ng>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/riscv/kvm/kvm-stub.c  | 23 +++++++++++++++++++++++
 target/riscv/kvm/meson.build |  1 +
 target/riscv/meson.build     |  3 +++
 3 files changed, 27 insertions(+)
 create mode 100644 target/riscv/kvm/kvm-stub.c

diff --git a/target/riscv/kvm/kvm-stub.c b/target/riscv/kvm/kvm-stub.c
new file mode 100644
index 00000000000..64e39c96d89
--- /dev/null
+++ b/target/riscv/kvm/kvm-stub.c
@@ -0,0 +1,23 @@
+/*
+ * QEMU RISCV specific KVM stubs
+ *
+ *  Copyright (c) rev.ng Labs Srl.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "target/riscv/kvm/kvm_riscv.h"
+
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
+                          uint64_t aia_irq_num, uint64_t aia_msi_num,
+                          uint64_t aplic_base, uint64_t imsic_base,
+                          uint64_t guest_num)
+{
+    g_assert_not_reached();
+}
+
+uint64_t kvm_riscv_get_timebase_frequency(RISCVCPU *cpu)
+{
+    g_assert_not_reached();
+}
diff --git a/target/riscv/kvm/meson.build b/target/riscv/kvm/meson.build
index 7e924150912..75e35b21506 100644
--- a/target/riscv/kvm/meson.build
+++ b/target/riscv/kvm/meson.build
@@ -1 +1,2 @@
 riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm-cpu.c'))
+riscv_stubs_ss.add(files('kvm-stub.c'))
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 42d0f6d538a..e1b51d2bd4d 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -19,6 +19,8 @@ riscv_ss.add(files(
   'gdbstub.c',
 ))
 
+riscv_stubs_ss = ss.source_set()
+
 riscv_system_ss = ss.source_set()
 riscv_system_ss.add(files(
   'arch_dump.c',
@@ -33,3 +35,4 @@ subdir('kvm')
 
 target_arch += {'riscv': riscv_ss}
 target_system_arch += {'riscv': riscv_system_ss}
+target_stubs_arch += {'riscv': riscv_stubs_ss}
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 08/18] system: Document has_work() synchronization requirements
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (6 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 07/18] target/riscv: Stub out kvm functions Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 09/18] target/s390x: Use s390_cpu_get_state() consistently Philippe Mathieu-Daudé
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

Document that has_work() may be called with or without the BQL.

Require implementations to remain idempotent and avoid consuming
work, and to synchronize state shared with other threads without
acquiring the BQL unconditionally.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260923171116.31276-2-philmd@oss.qualcomm.com>
---
 include/hw/core/sysemu-cpu-ops.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h
index e56eea18b78..d125540262d 100644
--- a/include/hw/core/sysemu-cpu-ops.h
+++ b/include/hw/core/sysemu-cpu-ops.h
@@ -19,8 +19,10 @@ typedef struct SysemuCPUOps {
     /**
      * @has_work: Callback for checking if there is work to do.
      *
-     * This function should be idempotent (i.e. not change state) as
-     * it will likely be queried multiple times before a CPU resumes.
+     * This callback may be called with or without the BQL.  It must be
+     * idempotent, must not consume work, and must not assume that the BQL
+     * is held or acquire it unconditionally.  State shared with other
+     * threads must use appropriate synchronization.
      */
     bool (*has_work)(CPUState *cpu); /* MANDATORY NON-NULL */
     /**
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 09/18] target/s390x: Use s390_cpu_get_state() consistently
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (7 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 08/18] system: Document has_work() synchronization requirements Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 10/18] target/s390x: Extend comment about PV cpu load state Philippe Mathieu-Daudé
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

Replace direct reads of env::cpu_state with s390_cpu_get_state().
This keeps CPU state reads consistent across CPU transitions.

Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20260923171116.31276-3-philmd@oss.qualcomm.com>
---
 target/s390x/cpu-system.c | 2 +-
 target/s390x/cpu.c        | 2 +-
 target/s390x/kvm/kvm.c    | 2 +-
 target/s390x/machine.c    | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/s390x/cpu-system.c b/target/s390x/cpu-system.c
index cc9685221ae..c938c77d0bd 100644
--- a/target/s390x/cpu-system.c
+++ b/target/s390x/cpu-system.c
@@ -263,7 +263,7 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
                      cpu_state);
         exit(1);
     }
-    if (kvm_enabled() && cpu->env.cpu_state != cpu_state) {
+    if (kvm_enabled() && s390_cpu_get_state(cpu) != cpu_state) {
         kvm_s390_set_cpu_state(cpu, cpu_state);
     }
     cpu->env.cpu_state = cpu_state;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 7c725b8a4a4..85afc5dec9a 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -130,7 +130,7 @@ static void s390_query_cpu_fast(CPUState *cpu, CpuInfoFast *value)
 {
     S390CPU *s390_cpu = S390_CPU(cpu);
 
-    value->u.s390x.cpu_state = s390_cpu->env.cpu_state;
+    value->u.s390x.cpu_state = s390_cpu_get_state(s390_cpu);
 #if !defined(CONFIG_USER_ONLY)
     if (s390_has_topology()) {
         value->u.s390x.has_dedicated = true;
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index b34a9127141..6622886032e 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -407,7 +407,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 {
     unsigned int max_cpus = MACHINE(qdev_get_machine())->smp.max_cpus;
     S390CPU *cpu = S390_CPU(cs);
-    kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
+    kvm_s390_set_cpu_state(cpu, s390_cpu_get_state(cpu));
     cpu->irqstate = g_malloc0(VCPU_IRQ_BUF_SIZE(max_cpus));
     return 0;
 }
diff --git a/target/s390x/machine.c b/target/s390x/machine.c
index f714834a98a..b44fba43f14 100644
--- a/target/s390x/machine.c
+++ b/target/s390x/machine.c
@@ -32,7 +32,7 @@ static int cpu_post_load(void *opaque, int version_id)
      * than via cpu_synchronize_state, we need update kvm here.
      */
     if (kvm_enabled()) {
-        kvm_s390_set_cpu_state(cpu, cpu->env.cpu_state);
+        kvm_s390_set_cpu_state(cpu, s390_cpu_get_state(cpu));
         return kvm_s390_vcpu_interrupt_post_load(cpu);
     }
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 10/18] target/s390x: Extend comment about PV cpu load state
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (8 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 09/18] target/s390x: Use s390_cpu_get_state() consistently Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 11/18] target/s390x: Make s390_cpu_set_state() return void Philippe Mathieu-Daudé
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Janosch Frank <frankja@linux.ibm.com>

When implementing PV in KVM we chose to add the cpu load state to the
mp state solely to have a way to keep the UV happy. The UV requires us
to set that state before running the boot cpu since entering that
state sets the initial PSW.

Since entering that state in KVM only sets off the UV call which
causes the initial PSW load and does not set the KVM tracking to
operating, we need a second set mp state to reach operating state.

Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260923082146.62803-1-frankja@linux.ibm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/s390x/cpu-system.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/s390x/cpu-system.c b/target/s390x/cpu-system.c
index c938c77d0bd..f12ef1bd1cc 100644
--- a/target/s390x/cpu-system.c
+++ b/target/s390x/cpu-system.c
@@ -73,8 +73,12 @@ static void s390_cpu_load_normal(CPUState *s)
         cpu->env.psw.addr = spsw & PSW_MASK_SHORT_ADDR;
     } else {
         /*
-         * Firmware requires us to set the load state before we set
-         * the cpu to operating on protected guests.
+         * Firmware/UV requires us to set the load state before we run
+         * the cpu on (re)boots. The UV load includes operating so the
+         * second set state isn't really needed but KVM doesn't update
+         * its internal state to operating on load. So we have to set
+         * operating again. The UV doesn't mind that since it's
+         * effectively a NOP.
          */
         s390_cpu_set_state(S390_CPU_STATE_LOAD, cpu);
     }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 11/18] target/s390x: Make s390_cpu_set_state() return void
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (9 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 10/18] target/s390x: Extend comment about PV cpu load state Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 12/18] target/s390x: Use S390CpuState for CPU state APIs Philippe Mathieu-Daudé
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Philippe Mathieu-Daudé <philmd@linaro.org>

The return value of s390_cpu_set_state() is only used by the STOP
interrupt handler. Make the setter return void and count running
CPUs directly at that call site.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20260923171116.31276-4-philmd@oss.qualcomm.com>
---
 target/s390x/cpu.h        | 5 ++---
 target/s390x/cpu-system.c | 4 +---
 target/s390x/sigp.c       | 3 ++-
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 998bbb0d7ff..2d1dcc7045c 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -847,11 +847,10 @@ void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
 int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
                                 int vq, bool assign);
 #ifndef CONFIG_USER_ONLY
-unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu);
+void s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu);
 #else
-static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
+static inline void s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
 {
-    return 0;
 }
 #endif /* CONFIG_USER_ONLY */
 static inline uint8_t s390_cpu_get_state(const S390CPU *cpu)
diff --git a/target/s390x/cpu-system.c b/target/s390x/cpu-system.c
index f12ef1bd1cc..e1335d9be66 100644
--- a/target/s390x/cpu-system.c
+++ b/target/s390x/cpu-system.c
@@ -240,7 +240,7 @@ void s390_cpu_unhalt(S390CPU *cpu)
     }
 }
 
-unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
+void s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
  {
     trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);
 
@@ -271,8 +271,6 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
         kvm_s390_set_cpu_state(cpu, cpu_state);
     }
     cpu->env.cpu_state = cpu_state;
-
-    return s390_count_running_cpus();
 }
 
 void s390_cmma_reset(void)
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index b6d44c5c31b..1801b8caa6e 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -617,7 +617,8 @@ void do_stop_interrupt(CPUS390XState *env)
         s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
     }
     env->sigp_order = 0;
-    if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) {
+    s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
+    if (s390_count_running_cpus() == 0) {
         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
     }
     env->pending_int &= ~INTERRUPT_STOP;
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 12/18] target/s390x: Use S390CpuState for CPU state APIs
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (10 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 11/18] target/s390x: Make s390_cpu_set_state() return void Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 13/18] target/s390x: Access S390CpuState atomically Philippe Mathieu-Daudé
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

Use the QAPI S390CpuState enum for CPU state accessors instead
of uint8_t. Handle state checks with switch statements.

Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20260923171116.31276-5-philmd@oss.qualcomm.com>
---
 target/s390x/cpu.h           |  6 +++---
 target/s390x/kvm/kvm_s390x.h |  2 +-
 hw/intc/s390_flic.c          |  7 +++++--
 target/s390x/cpu-system.c    | 18 ++++++++++++------
 target/s390x/kvm/kvm.c       |  2 +-
 target/s390x/kvm/stubs.c     |  2 +-
 target/s390x/sigp.c          |  6 +++++-
 7 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 2d1dcc7045c..bf9f6ed1de2 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -847,13 +847,13 @@ void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
 int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
                                 int vq, bool assign);
 #ifndef CONFIG_USER_ONLY
-void s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu);
+void s390_cpu_set_state(S390CpuState cpu_state, S390CPU *cpu);
 #else
-static inline void s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
+static inline void s390_cpu_set_state(S390CpuState cpu_state, S390CPU *cpu)
 {
 }
 #endif /* CONFIG_USER_ONLY */
-static inline uint8_t s390_cpu_get_state(const S390CPU *cpu)
+static inline S390CpuState s390_cpu_get_state(const S390CPU *cpu)
 {
     return cpu->env.cpu_state;
 }
diff --git a/target/s390x/kvm/kvm_s390x.h b/target/s390x/kvm/kvm_s390x.h
index 3c4fa0489cf..b1ff66f04e3 100644
--- a/target/s390x/kvm/kvm_s390x.h
+++ b/target/s390x/kvm/kvm_s390x.h
@@ -22,7 +22,7 @@ int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, uint8_t ar, void *hostbuf,
 int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
                        bool is_write);
 void kvm_s390_program_interrupt(S390CPU *cpu, uint16_t code);
-int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
+int kvm_s390_set_cpu_state(S390CPU *cpu, S390CpuState cpu_state);
 void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
 int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
 int kvm_s390_get_hpage(void);
diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index 57fd4b2b81c..b5256b3ba88 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -193,8 +193,11 @@ static void qemu_s390_flic_notify(uint32_t type)
         cpu_set_interrupt(cs, CPU_INTERRUPT_HARD);
 
         /* ignore CPUs that are not sleeping */
-        if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING &&
-            s390_cpu_get_state(cpu) != S390_CPU_STATE_LOAD) {
+        switch (s390_cpu_get_state(cpu)) {
+        case S390_CPU_STATE_LOAD:
+        case S390_CPU_STATE_OPERATING:
+            break;
+        default:
             continue;
         }
 
diff --git a/target/s390x/cpu-system.c b/target/s390x/cpu-system.c
index e1335d9be66..e15775875f2 100644
--- a/target/s390x/cpu-system.c
+++ b/target/s390x/cpu-system.c
@@ -44,8 +44,11 @@ bool s390_cpu_has_work(CPUState *cs)
     S390CPU *cpu = S390_CPU(cs);
 
     /* STOPPED cpus can never wake up */
-    if (s390_cpu_get_state(cpu) != S390_CPU_STATE_LOAD &&
-        s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) {
+    switch (s390_cpu_get_state(cpu)) {
+    case S390_CPU_STATE_LOAD:
+    case S390_CPU_STATE_OPERATING:
+        break;
+    default:
         return false;
     }
 
@@ -206,12 +209,15 @@ unsigned s390_count_running_cpus(void)
     int nr_running = 0;
 
     CPU_FOREACH(cpu) {
-        uint8_t state = S390_CPU(cpu)->env.cpu_state;
-        if (state == S390_CPU_STATE_OPERATING ||
-            state == S390_CPU_STATE_LOAD) {
+        switch (s390_cpu_get_state(S390_CPU(cpu))) {
+        case S390_CPU_STATE_LOAD:
+        case S390_CPU_STATE_OPERATING:
             if (!disabled_wait(cpu)) {
                 nr_running++;
             }
+            break;
+        default:
+            break;
         }
     }
 
@@ -240,7 +246,7 @@ void s390_cpu_unhalt(S390CPU *cpu)
     }
 }
 
-void s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
+void s390_cpu_set_state(S390CpuState cpu_state, S390CPU *cpu)
  {
     trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state);
 
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 6622886032e..dc67e848864 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -2007,7 +2007,7 @@ int kvm_s390_get_ri(void)
     return cap_ri;
 }
 
-int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
+int kvm_s390_set_cpu_state(S390CPU *cpu, S390CpuState cpu_state)
 {
     struct kvm_mp_state mp_state = {};
     int ret;
diff --git a/target/s390x/kvm/stubs.c b/target/s390x/kvm/stubs.c
index ebf3c83994d..c5ec7d3f1d3 100644
--- a/target/s390x/kvm/stubs.c
+++ b/target/s390x/kvm/stubs.c
@@ -128,7 +128,7 @@ int kvm_s390_mem_op_pv(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
     g_assert_not_reached();
 }
 
-int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
+int kvm_s390_set_cpu_state(S390CPU *cpu, S390CpuState cpu_state)
 {
     g_assert_not_reached();
 }
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
index 1801b8caa6e..09004e98a21 100644
--- a/target/s390x/sigp.c
+++ b/target/s390x/sigp.c
@@ -39,7 +39,7 @@ static void set_sigp_status(SigpInfo *si, uint64_t status)
 
 static void sigp_sense(S390CPU *dst_cpu, SigpInfo *si)
 {
-    uint8_t state = s390_cpu_get_state(dst_cpu);
+    S390CpuState state = s390_cpu_get_state(dst_cpu);
     bool ext_call = dst_cpu->env.pending_int & INTERRUPT_EXTERNAL_CALL;
     uint64_t status = 0;
 
@@ -221,6 +221,8 @@ static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg)
         cpu_synchronize_state(cs);
         s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true);
         break;
+    default:
+        break;
     }
     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
 }
@@ -362,6 +364,8 @@ static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
     case S390_CPU_STATE_OPERATING:
         cpu_inject_restart(cpu);
         break;
+    default:
+        break;
     }
     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
 }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 13/18] target/s390x: Access S390CpuState atomically
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (11 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 12/18] target/s390x: Use S390CpuState for CPU state APIs Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 14/18] target/arm: Un-inline arm_set_cpu_power_state() Philippe Mathieu-Daudé
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

Use qatomic_read/set() in the S390 CPU state accessors.
This avoids non-atomic reads in s390_cpu_has_work().

Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20260923171116.31276-6-philmd@oss.qualcomm.com>
---
 target/s390x/cpu.h        | 2 +-
 target/s390x/cpu-system.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index bf9f6ed1de2..ef73b15218e 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -855,7 +855,7 @@ static inline void s390_cpu_set_state(S390CpuState cpu_state, S390CPU *cpu)
 #endif /* CONFIG_USER_ONLY */
 static inline S390CpuState s390_cpu_get_state(const S390CPU *cpu)
 {
-    return cpu->env.cpu_state;
+    return qatomic_read(&cpu->env.cpu_state);
 }
 
 
diff --git a/target/s390x/cpu-system.c b/target/s390x/cpu-system.c
index e15775875f2..d963d9e940e 100644
--- a/target/s390x/cpu-system.c
+++ b/target/s390x/cpu-system.c
@@ -276,7 +276,7 @@ void s390_cpu_set_state(S390CpuState cpu_state, S390CPU *cpu)
     if (kvm_enabled() && s390_cpu_get_state(cpu) != cpu_state) {
         kvm_s390_set_cpu_state(cpu, cpu_state);
     }
-    cpu->env.cpu_state = cpu_state;
+    qatomic_set(&cpu->env.cpu_state, cpu_state);
 }
 
 void s390_cmma_reset(void)
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 14/18] target/arm: Un-inline arm_set_cpu_power_state()
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (12 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 13/18] target/s390x: Access S390CpuState atomically Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 15/18] target/arm: Access PSCI state atomically Philippe Mathieu-Daudé
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

Move arm_set_cpu_power_state() from the header to arm-powerctl.c,
keeping the power-state helper with the other power-control code.
Restrict the call in arm_cpu_reset_hold() to system emulation.

Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260923171116.31276-7-philmd@oss.qualcomm.com>
---
 target/arm/internals.h    | 8 +-------
 target/arm/arm-powerctl.c | 7 +++++++
 target/arm/cpu.c          | 4 ++--
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 1775835ad50..1efda543270 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -2082,12 +2082,6 @@ bool arm_cpu_match_cpreg_mig_tolerance(ARMCPU *cpu, uint64_t kvmidx,
 /**
  * arm_set_cpu_power_state() - set power state synced with halt_reason
  */
-static inline void arm_set_cpu_power_state(ARMCPU *cpu, ARMPSCIState state)
-{
-    CPUARMState *env = &cpu->env;
-
-    cpu->power_state = state;
-    env->halt_reason = state == PSCI_OFF ? HALT_PSCI : NOT_HALTED;
-}
+void arm_set_cpu_power_state(ARMCPU *cpu, ARMPSCIState state);
 
 #endif
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
index a06be5cc997..213e7ae056c 100644
--- a/target/arm/arm-powerctl.c
+++ b/target/arm/arm-powerctl.c
@@ -45,6 +45,13 @@ struct CpuOnInfo {
     bool target_aa64;
 };
 
+void arm_set_cpu_power_state(ARMCPU *cpu, ARMPSCIState state)
+{
+    CPUARMState *env = &cpu->env;
+
+    cpu->power_state = state;
+    env->halt_reason = state == PSCI_OFF ? HALT_PSCI : NOT_HALTED;
+}
 
 static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
                                       run_on_cpu_data data)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f58a1db843a..76aa47ac503 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -351,8 +351,6 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type)
     env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.mvfr1;
     env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.mvfr2;
 
-    arm_set_cpu_power_state(cpu, cs->start_powered_off ? PSCI_OFF : PSCI_ON);
-
     if (arm_feature(env, ARM_FEATURE_AARCH64)) {
         /* 64 bit CPUs always start in 64 bit mode */
         env->aarch64 = true;
@@ -671,6 +669,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type)
     arm_set_ah_fp_behaviours(&env->vfp.fp_status[FPST_AH_F16]);
 
 #ifndef CONFIG_USER_ONLY
+    arm_set_cpu_power_state(cpu, cs->start_powered_off ? PSCI_OFF : PSCI_ON);
+
     if (kvm_enabled()) {
         kvm_arm_reset_vcpu(cpu);
     }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 15/18] target/arm: Access PSCI state atomically
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (13 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 14/18] target/arm: Un-inline arm_set_cpu_power_state() Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 16/18] target/arm: Access halt " Philippe Mathieu-Daudé
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

Use qatomic_set() when updating ARMCPU::power_state and
CPUARMState::halt_reason. Read ARMCPU::power_state atomically in
arm_cpu_has_work(), which can run without the BQL held.

Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260923171116.31276-9-philmd@oss.qualcomm.com>
---
 target/arm/arm-powerctl.c | 4 ++--
 target/arm/cpu.c          | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
index 213e7ae056c..ef14a1f8a94 100644
--- a/target/arm/arm-powerctl.c
+++ b/target/arm/arm-powerctl.c
@@ -49,8 +49,8 @@ void arm_set_cpu_power_state(ARMCPU *cpu, ARMPSCIState state)
 {
     CPUARMState *env = &cpu->env;
 
-    cpu->power_state = state;
-    env->halt_reason = state == PSCI_OFF ? HALT_PSCI : NOT_HALTED;
+    qatomic_set(&cpu->power_state, state);
+    qatomic_set(&env->halt_reason, state == PSCI_OFF ? HALT_PSCI : NOT_HALTED);
 }
 
 static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 76aa47ac503..5cfd3bcfc8e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -149,7 +149,7 @@ static bool arm_cpu_has_work(CPUState *cs)
      * Only another PSCI call can wake the CPU up in which case the
      * power_state would be set by arm_set_cpu_on_and_reset_async_work()
      */
-    if (cpu->power_state == PSCI_OFF) {
+    if (qatomic_read(&cpu->power_state) == PSCI_OFF) {
         g_assert(cpu->env.halt_reason == HALT_PSCI);
         return false;
     }
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 16/18] target/arm: Access halt state atomically
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (14 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 15/18] target/arm: Access PSCI state atomically Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 17/18] target/i386: Use an acquire load for interrupt_request() Philippe Mathieu-Daudé
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

arm_cpu_has_work() runs without the BQL held and can inspect
halt_reason and event_register while other CPU contexts update
them. The WFxT timer may also consume HALT_WFE asynchronously.

Use atomic accesses for the halt state, including the WFI/WFE
and halt-exit stores. This keeps the halt/wakeup protocol
race-free and matches the atomic state transitions used by the
asynchronous wake-up paths.

Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260923171116.31276-10-philmd@oss.qualcomm.com>
---
 target/arm/cpu.c           | 7 ++++---
 target/arm/tcg/op_helper.c | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5cfd3bcfc8e..090470da40a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -144,20 +144,21 @@ int arm_cpu_mmu_index(CPUState *cs, bool ifetch)
 static bool arm_cpu_has_work(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
+    ARMHaltReason halt_reason = qatomic_read(&cpu->env.halt_reason);
 
     /*
      * Only another PSCI call can wake the CPU up in which case the
      * power_state would be set by arm_set_cpu_on_and_reset_async_work()
      */
     if (qatomic_read(&cpu->power_state) == PSCI_OFF) {
-        g_assert(cpu->env.halt_reason == HALT_PSCI);
+        g_assert(halt_reason == HALT_PSCI);
         return false;
     }
 
     /*
      * A wake-up event should only wake us if we are halted on a WFE
      */
-    if (cpu->env.halt_reason == HALT_WFE && cpu->env.event_register) {
+    if (halt_reason == HALT_WFE && qatomic_read(&cpu->env.event_register)) {
         return true;
     }
 
@@ -882,7 +883,7 @@ bool arm_cpu_exec_halt(CPUState *cs)
             timer_del(cpu->wfxt_timer);
         }
         /* clear the halt reason */
-        cpu->env.halt_reason = NOT_HALTED;
+        qatomic_set(&cpu->env.halt_reason, NOT_HALTED);
     }
     return leave_halt;
 }
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index c2b09176cb1..643b1482523 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -398,7 +398,7 @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
                         target_el);
     }
 
-    env->halt_reason = HALT_WFI;
+    qatomic_set(&env->halt_reason, HALT_WFI);
     cs->exception_index = EXCP_HLT;
     cs->halted = 1;
     cpu_loop_exit(cs);
@@ -460,7 +460,7 @@ void HELPER(wfit)(CPUARMState *env, uint32_t rd)
     } else {
         timer_mod(cpu->wfxt_timer, nexttick);
     }
-    env->halt_reason = HALT_WFI;
+    qatomic_set(&env->halt_reason, HALT_WFI);
     cs->exception_index = EXCP_HLT;
     cs->halted = 1;
     cpu_loop_exit(cs);
@@ -629,7 +629,7 @@ void HELPER(wfe)(CPUARMState *env, uint32_t insn_len)
         }
     }
 
-    env->halt_reason = HALT_WFE;
+    qatomic_set(&env->halt_reason, HALT_WFE);
     cs->exception_index = EXCP_HLT;
     cs->halted = 1;
     cpu_loop_exit(cs);
@@ -723,7 +723,7 @@ void HELPER(wfet)(CPUARMState *env, uint32_t rd)
         }
     }
 
-    env->halt_reason = HALT_WFE;
+    qatomic_set(&env->halt_reason, HALT_WFE);
     cs->exception_index = EXCP_HLT;
     cs->halted = 1;
     cpu_loop_exit(cs);
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 17/18] target/i386: Use an acquire load for interrupt_request()
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (15 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 16/18] target/arm: Access halt " Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-24 15:23 ` [PULL 18/18] target/ppc: Stop vCPU thread before calling parent_unrealize Philippe Mathieu-Daudé
  2026-09-25  2:35 ` [PULL 00/18] Misc target/ patches for 2026-09-24 Richard Henderson
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

x86_cpu_has_work() may run without the BQL, but currently reads
CPUState::interrupt_request directly. Other threads update this
field with qatomic_or() in cpu_set_interrupt(), so the direct
read races with an atomic access.

Load the interrupt request with qatomic_load_acquire(), matching
cpu_test_interrupt(). This provides the acquire ordering required
before x86_cpu_pending_interrupt() inspects the CPU state.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260923171116.31276-18-philmd@oss.qualcomm.com>
---
 target/i386/cpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b97f144aea5..f3bc6911c10 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10640,7 +10640,9 @@ int x86_cpu_pending_interrupt(const CPUState *cs, int interrupt_request)
 
 static bool x86_cpu_has_work(CPUState *cs)
 {
-    return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0;
+    uint32_t pending_interrupts = qatomic_load_acquire(&cs->interrupt_request);
+
+    return x86_cpu_pending_interrupt(cs, pending_interrupts) != 0;
 }
 #endif /* !CONFIG_USER_ONLY */
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PULL 18/18] target/ppc: Stop vCPU thread before calling parent_unrealize
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (16 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 17/18] target/i386: Use an acquire load for interrupt_request() Philippe Mathieu-Daudé
@ 2026-09-24 15:23 ` Philippe Mathieu-Daudé
  2026-09-25  2:35 ` [PULL 00/18] Misc target/ patches for 2026-09-24 Richard Henderson
  18 siblings, 0 replies; 20+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-24 15:23 UTC (permalink / raw)
  To: qemu-devel

From: Shivang Upadhyay <shivangu@linux.ibm.com>

During CPU hot-unplug (e.g. via dynamic reconfiguration unplug),
ppc_cpu_unrealize() invoked pcc->parent_unrealize(dev) before calling
cpu_remove_sync(CPU(cpu)).

pcc->parent_unrealize() calls cpu_common_unrealize(), which triggers
accel_cpu_common_unrealize() -> tcg_exec_unrealizefn() -> tlb_destroy().
This immediately frees the CPU's TLB tables and structures. Because the
vCPU thread had not yet been stopped and joined via cpu_remove_sync(),
the vCPU thread was still actively running its event loop and processing
queued CPU work (such as tcg_commit_cpu / tlb_flush).

This resulted in a race where the running vCPU thread accessed and freed
already-destroyed TLB tables concurrently with tlb_destroy(), leading to
Segfault (due to heap corruption).

AddressSanitizer build reported a double-free:

=================================================================
==121930==ERROR: AddressSanitizer: attempting double-free on 0x7ef8f3438800 in thread T14:
    #0 0x7fe8f74e5beb in free.part.0 (/lib64/libasan.so.8+0xe5beb)
    #1 0x7fe8f6cb8f84 in g_free (/lib64/libglib-2.0.so.0+0x41f84)
    #2 0x558bf6a391b1 in tlb_mmu_resize_locked accel/tcg/cputlb.c:249
    #3 0x558bf6a396b5 in tlb_flush_one_mmuidx_locked accel/tcg/cputlb.c:296
    #4 0x558bf6a39f91 in tlb_flush_by_mmuidx_async_work accel/tcg/cputlb.c:390
    #5 0x558bf6a3a200 in tlb_flush_by_mmuidx accel/tcg/cputlb.c:417
    #6 0x558bf6a3a22a in tlb_flush accel/tcg/cputlb.c:422
    #7 0x558bf73f31ac in tcg_commit_cpu system/physmem.c:3068
    #8 0x558bf6987c55 in process_queued_cpu_work cpu-common.c:378
    #9 0x558bf73a9913 in qemu_process_cpu_events_common system/cpus.c:402
    #10 0x558bf73a9a46 in qemu_process_cpu_events system/cpus.c:421
    #11 0x558bf6a65974 in mttcg_cpu_thread_fn accel/tcg/tcg-accel-ops-mttcg.c:90

0x7ef8f3438800 is located 0 bytes inside of 65536-byte region [0x7ef8f3438800,0x7ef8f3448800)
freed by thread T9 here:
    #0 0x7fe8f74e5beb in free.part.0 (/lib64/libasan.so.8+0xe5beb)
    #1 0x7fe8f6cb8f84 in g_free (/lib64/libglib-2.0.so.0+0x41f84)
    #2 0x558bf6a39a91 in tlb_destroy accel/tcg/cputlb.c:345
    #3 0x558bf6a16354 in tcg_exec_unrealizefn accel/tcg/cpu-exec.c:1094
    #4 0x558bf693d073 in accel_cpu_common_unrealize accel/accel-common.c:117
    #5 0x558bf6980e37 in cpu_common_unrealize hw/core/cpu-common.c:279
    #6 0x558bf6980dfa in cpu_common_unrealizefn hw/core/cpu-common.c:267
    #7 0x558bf763ef65 in ppc_cpu_unrealize target/ppc/cpu_init.c:6965
    #8 0x558bf7872199 in device_set_realized hw/core/qdev.c:618
    #14 0x558bf756068f in spapr_unrealize_vcpu hw/ppc/spapr_cpu_core.c:209

Fix this by moving cpu_remove_sync() before pcc->parent_unrealize(dev)
in ppc_cpu_unrealize(), ensuring the vCPU thread is stopped, has
finished processing its events, and is joined before CPU resources
and accelerator state are destroyed.

Cc: qemu-stable@nongnu.org
Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Message-ID: <20260923121444.154175-1-shivangu@linux.ibm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/ppc/cpu_init.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 6c626843c93..b711f9c0a85 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6962,10 +6962,10 @@ static void ppc_cpu_unrealize(DeviceState *dev)
     PowerPCCPU *cpu = POWERPC_CPU(dev);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
 
-    pcc->parent_unrealize(dev);
-
     cpu_remove_sync(CPU(cpu));
 
+    pcc->parent_unrealize(dev);
+
     destroy_ppc_opcodes(cpu);
 }
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PULL 00/18] Misc target/ patches for 2026-09-24
  2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
                   ` (17 preceding siblings ...)
  2026-09-24 15:23 ` [PULL 18/18] target/ppc: Stop vCPU thread before calling parent_unrealize Philippe Mathieu-Daudé
@ 2026-09-25  2:35 ` Richard Henderson
  18 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2026-09-25  2:35 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel

On 9/24/26 08:23, Philippe Mathieu-Daudé wrote:
> The following changes since commit 942229961efea74b153c44c59188eb08375f10f1:
> 
>    Merge tag 'pull-tcg-20260923-v2' ofhttps://gitlab.com/rth7680/qemu into staging (2026-09-23 15:14:55 -0700)
> 
> are available in the Git repository at:
> 
>    https://github.com/philmd/qemu.git tags/target-misc-20260924
> 
> for you to fetch changes up to cbbd4d74eb298e2b407018185a40cb813435527e:
> 
>    target/ppc: Stop vCPU thread before calling parent_unrealize (2026-09-24 17:22:06 +0200)
> 
> ----------------------------------------------------------------
> Misc target patches queue
> 
> - DOC: Improve SysemuCPUOps::has_work docstring
> - MIPS: Let TCG middle-end optimize MXU opcodes (not front-end)
> - S390x: Access S390CpuState atomically
> - ARM: Access halt/PSCI states atomically
> - X86: Access interrupt_request atomically
> - PPC: Fix double-free in ppc_cpu_unrealize()

Applied, thanks.

r~


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-09-25  2:36 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-24 15:23 [PULL 00/18] Misc target/ patches for 2026-09-24 Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 01/18] target/mips: Fix zero in gen_mxu_d8sum Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 02/18] target/mips: Drop zero optimization in gen_mxu_s32mul Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 03/18] target/mips: Split out gen_mxu_logic Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 04/18] target/mips: Use gen_mxu_logic for gen_mxu_S32MAX_S32MIN Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 05/18] target/mips: Use gen_mxu_logic for gen_mxu_S32SLT Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 06/18] target/mips: Use gen_mxu_logic for gen_mxu_S32CPS Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 07/18] target/riscv: Stub out kvm functions Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 08/18] system: Document has_work() synchronization requirements Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 09/18] target/s390x: Use s390_cpu_get_state() consistently Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 10/18] target/s390x: Extend comment about PV cpu load state Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 11/18] target/s390x: Make s390_cpu_set_state() return void Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 12/18] target/s390x: Use S390CpuState for CPU state APIs Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 13/18] target/s390x: Access S390CpuState atomically Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 14/18] target/arm: Un-inline arm_set_cpu_power_state() Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 15/18] target/arm: Access PSCI state atomically Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 16/18] target/arm: Access halt " Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 17/18] target/i386: Use an acquire load for interrupt_request() Philippe Mathieu-Daudé
2026-09-24 15:23 ` [PULL 18/18] target/ppc: Stop vCPU thread before calling parent_unrealize Philippe Mathieu-Daudé
2026-09-25  2:35 ` [PULL 00/18] Misc target/ patches for 2026-09-24 Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.