All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>
To: qemu-devel@nongnu.org
Subject: [PULL 5/6] target/sparc: set reg window data structures currently after vmstate load
Date: Tue, 28 Jul 2026 11:40:54 +0200	[thread overview]
Message-ID: <20260728094055.12684-6-philmd@oss.qualcomm.com> (raw)
In-Reply-To: <20260728094055.12684-1-philmd@oss.qualcomm.com>

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

In the SPARC CPU state, env->regwptr points into the env->regbase
array at wherever the architectural CWP (current window pointer) says
we are in the register windows.  We don't migrate this directly,
since it's a host pointer, so we must ensure it is set up again
after migration load.

We also have to deal with a special case when CWP is (nwindows - 1).
In this case, while running we keep the "in" register data for this
window in a temporary location at the end of the regbase[] array, so
that generated code doesn't have to special case this "wrap around"
case.  In cpu_pre_save() we call cpu_set_cwp() to force a copy of the
wrapped data from its temporary location into the architectural
location in window 0's "out" registers.  We then migrate only
(nwindows * 16) entries in the regbase[] array.  So on the
destination we need to copy the "in" register data back to its
temporary location again.

For 32-bit SPARC we get this right, because the CWP is in the PSR.
The get_psr() function does:
     env->cwp = 0;
     cpu_put_psr_raw(env, val);
which causes cpu_put_psr_raw() to call cpu_set_cwp() in a way that
sets up both regwptr and the wrapped-register data.

However, for 64-bit SPARC the CWP is not in the PSR, and
cpu_put_psr_raw() will not call cpu_set_cwp().  This leaves the guest
register state in a corrupted state, and the guest will likely crash
on the destination if it didn't happen to be executing with CWP == 0.

Fix this by adding a custom vmstate_cwp VMStateInfo with corresponding
get_cwp() and put_cwp() helpers which does the same for the 64-bit
case.

Cc: qemu-stable@nongnu.org
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-ID: <20260725123411.993099-1-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 target/sparc/machine.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/target/sparc/machine.c b/target/sparc/machine.c
index 5f402e098cf..0d5d79b5e7b 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -151,6 +151,37 @@ static const VMStateInfo vmstate_xcc = {
     .get = get_xcc,
     .put = put_xcc,
 };
+
+static int get_cwp(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field)
+{
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
+    uint32_t val = qemu_get_be32(f);
+
+    /* needed to ensure that the wrapping registers are correctly updated */
+    env->cwp = 0;
+    cpu_set_cwp(env, val);
+
+    return 0;
+}
+
+static int put_cwp(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, JSONWriter *vmdesc)
+{
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
+    uint32_t val = env->cwp;
+
+    qemu_put_be32(f, val);
+    return 0;
+}
+
+static const VMStateInfo vmstate_cwp = {
+    .name = "uint32",
+    .get = get_cwp,
+    .put = put_cwp,
+};
 #else
 static bool fq_needed(void *opaque)
 {
@@ -286,7 +317,14 @@ const VMStateDescription vmstate_sparc_cpu = {
         VMSTATE_CPU_TIMER(env.hstick, SPARCCPU),
         /* On SPARC32 env.psrpil and env.cwp are migrated as part of the PSR */
         VMSTATE_UINT32(env.psrpil, SPARCCPU),
-        VMSTATE_UINT32(env.cwp, SPARCCPU),
+        {
+            .name = "env.cwp",
+            .version_id = 0,
+            .size = sizeof(uint32_t),
+            .info = &vmstate_cwp,
+            .flags = VMS_SINGLE,
+            .offset = 0,
+        },
 #endif
         VMSTATE_END_OF_LIST()
     },
-- 
2.53.0



  parent reply	other threads:[~2026-07-28  9:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28  9:40 [PULL 0/6] Misc HW patches for 2026-07-28 Philippe Mathieu-Daudé
2026-07-28  9:40 ` [PULL 1/6] hw/net/xilinx_axienet: Don't write checksums off end of packet Philippe Mathieu-Daudé
2026-07-28  9:40 ` [PULL 2/6] hw/sd/sdhci: Extract uSDHC-specific quirk Philippe Mathieu-Daudé
2026-07-28  9:40 ` [PULL 3/6] hw/net/e1000e: recalculate rx_desc_len on migration load Philippe Mathieu-Daudé
2026-07-28  9:40 ` [PULL 4/6] hw/net/igb: " Philippe Mathieu-Daudé
2026-07-28  9:40 ` Philippe Mathieu-Daudé [this message]
2026-07-28  9:40 ` [PULL 6/6] tests/functional/ppc: skip remote interrupts test if -net user not built Philippe Mathieu-Daudé
2026-07-28 15:31 ` [PULL 0/6] Misc HW patches for 2026-07-28 Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260728094055.12684-6-philmd@oss.qualcomm.com \
    --to=philmd@oss.qualcomm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.