diff options
| author | Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com> | 2025-07-22 17:37:36 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2025-08-01 16:48:50 +0100 |
| commit | 97b3d732afec9b165c33697452e31267a845338f (patch) | |
| tree | a6330d055f7060fcec343b7991d1c3da083270e8 | |
| parent | 35cca0f95ff5345f54c11d116efc8940a0dab8aa (diff) | |
| download | focaccia-qemu-97b3d732afec9b165c33697452e31267a845338f.tar.gz focaccia-qemu-97b3d732afec9b165c33697452e31267a845338f.zip | |
target/arm: Fix handling of setting SVE registers from gdb
The code to handle setting SVE registers via the gdbstub is broken: * it sets each pair of elements in the zregs[].d[] array in the wrong order for the most common (little endian) case: the least significant 64-bit value comes first * it makes no attempt to handle target_endian() * it does a simple copy out of the (target endian) gdbstub buffer into the (host endan) zregs data structure, which is wrong on big endian hosts Fix all these problems: * use ldq_p() to read from the gdbstub buffer * check target_big_endian() to see if we need to handle the 128-bit values the opposite way around Cc: qemu-stable@nongnu.org Signed-off-by: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com> Message-id: 20250722173736.2332529-3-vacha.bhavsar@oss.qualcomm.com [PMM: adjusted commit message, fixed spacing] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
| -rw-r--r-- | target/arm/gdbstub64.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c index 4fce58d895..08e2858539 100644 --- a/target/arm/gdbstub64.c +++ b/target/arm/gdbstub64.c @@ -206,10 +206,17 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg) case 0 ... 31: { int vq, len = 0; - uint64_t *p = (uint64_t *) buf; for (vq = 0; vq < cpu->sve_max_vq; vq++) { - env->vfp.zregs[reg].d[vq * 2 + 1] = *p++; - env->vfp.zregs[reg].d[vq * 2] = *p++; + if (target_big_endian()) { + env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf); + buf += 8; + env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf); + } else{ + env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf); + buf += 8; + env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf); + } + buf += 8; len += 16; } return len; @@ -224,9 +231,9 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg) { int preg = reg - 34; int vq, len = 0; - uint64_t *p = (uint64_t *) buf; for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) { - env->vfp.pregs[preg].p[vq / 4] = *p++; + env->vfp.pregs[preg].p[vq / 4] = ldq_p(buf); + buf += 8; len += 8; } return len; |