diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2025-10-17 14:04:47 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2025-10-17 14:04:47 -0700 |
commit | c85ba2d7a4056595166689890285105579db446a (patch) | |
tree | 49506692a14754719c205f2170fac34e8b3a6edd /linux-user/hexagon/signal.c | |
parent | 18f6f30b0089b470f3e737637a86dfb81ebd6eae (diff) | |
parent | f97700e0752753e294db11de8462aef5d8009a89 (diff) | |
download | qemu-master.zip qemu-master.tar.gz qemu-master.tar.bz2 |
Fixes for linux-user sigcontext save/restore, etc.
misc: avoid inconsistencies w/indent on macOS
fix hexagon linux-user sigcontext discrepancy, found by Alex @ Zig
# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEPWaq5HRZSCTIjOD4GlSvuOVkbDIFAmjyq24ACgkQGlSvuOVk
# bDIF9g/9FEllcwJFFOmyb+fsS0NkLFGRccCvowgjYCw5SaxC0+JBq58tWVkukCcK
# s+8eQ6TUfrgbxJziCoMWbP8UddMhNz9haUFGZ4wA8yq6Cxxmib092vdLj9YdfBdL
# TpMoXB1goWbPQ3EW2EyXr+Hsrlr/sb/hIrtSCvs2Xy1kRjc4xoAbHprgCz3C6oz4
# aiLJJy2uxWVDVEggWg7kSb2ZVmu/NrfReyv49kjEsuXiyHeQDBEDNYdRN5B6A9/F
# iznCSgTFBcDaV4UPaem6yEDuXCLucovmfLyvR+P6K/JtpOfX8nzWvk88j0WFeEmU
# kRZIpfR9un2GrndVeuxuoMGAZcha/LpajMr20OTfrKhJDPKp/kL5S3VqmBmZMsQx
# PjoBYFzBvg2FiMCQS1wQR4LGQ28/awz4ZnyeML02FRzDjmcFbZ0z5y4q1A9NnQEJ
# CZNnTjpUCdAVxymTnXCXVf/aS1T5v/iPWCu0BiebIlGP6/Eya364u60c0n/ABd1W
# bY3K1d2LZTYyi9dlT151pIOZ04S0k4E4g3jAyL578PfEpoJ7bXOmF8PL5DAAz1b8
# JRZjZLNXQlvNmcxTRs7wUzJlZ8AaudEZv5c+EnUcgLPcrBSMwvYdoXV7nyj+PKL1
# 3SwpRsgQimz7XtXAEUGmsSKUEIefF/yk/4laXHaGth3rMUDDi5U=
# =+ULY
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 17 Oct 2025 01:47:42 PM PDT
# gpg: using RSA key 3D66AAE474594824C88CE0F81A54AFB8E5646C32
# gpg: Good signature from "Brian Cain (QUIC) <quic_bcain@quicinc.com>" [unknown]
# gpg: aka "Brian Cain <bcain@kernel.org>" [unknown]
# gpg: aka "Brian Cain (QuIC) <bcain@quicinc.com>" [unknown]
# gpg: aka "Brian Cain (CAF) <bcain@codeaurora.org>" [unknown]
# gpg: aka "bcain" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6350 20F9 67A7 7164 79EF 49E0 175C 464E 541B 6D47
# Subkey fingerprint: 3D66 AAE4 7459 4824 C88C E0F8 1A54 AFB8 E564 6C32
* tag 'pull-hex-20251017' of https://github.com/quic/qemu:
target/hexagon: Only indent on linux
target/hexagon: Replace `prepare` script with meson target
target/hexagon: s/pkt_has_store/pkt_has_scalar_store
target/hexagon: handle .new values
tests/tcg/hexagon: Add cs{0,1} coverage
linux-user/hexagon: Use an array for GPRs
linux-user/hexagon: use abi_ulong
linux-user/hexagon: Fix sigcontext
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/hexagon/signal.c')
-rw-r--r-- | linux-user/hexagon/signal.c | 184 |
1 files changed, 72 insertions, 112 deletions
diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c index 492b51f..183ecfa 100644 --- a/linux-user/hexagon/signal.c +++ b/linux-user/hexagon/signal.c @@ -23,30 +23,32 @@ #include "signal-common.h" #include "linux-user/trace.h" -struct target_sigcontext { - target_ulong r0, r1, r2, r3; - target_ulong r4, r5, r6, r7; - target_ulong r8, r9, r10, r11; - target_ulong r12, r13, r14, r15; - target_ulong r16, r17, r18, r19; - target_ulong r20, r21, r22, r23; - target_ulong r24, r25, r26, r27; - target_ulong r28, r29, r30, r31; - target_ulong sa0; - target_ulong lc0; - target_ulong sa1; - target_ulong lc1; - target_ulong m0; - target_ulong m1; - target_ulong usr; - target_ulong gp; - target_ulong ugp; - target_ulong pc; - target_ulong cause; - target_ulong badva; - target_ulong pred[NUM_PREGS]; +struct target_user_regs_struct { + abi_ulong gpr[32]; + abi_ulong sa0; + abi_ulong lc0; + abi_ulong sa1; + abi_ulong lc1; + abi_ulong m0; + abi_ulong m1; + abi_ulong usr; + abi_ulong p3_0; + abi_ulong gp; + abi_ulong ugp; + abi_ulong pc; + abi_ulong cause; + abi_ulong badva; + abi_ulong cs0; + abi_ulong cs1; + abi_ulong pad1; /* pad to 48 words */ }; +QEMU_BUILD_BUG_ON(sizeof(struct target_user_regs_struct) != 48 * 4); + +struct target_sigcontext { + struct target_user_regs_struct sc_regs; +} QEMU_ALIGNED(8); + struct target_ucontext { unsigned long uc_flags; target_ulong uc_link; /* target pointer */ @@ -76,53 +78,34 @@ static abi_ulong get_sigframe(struct target_sigaction *ka, static void setup_sigcontext(struct target_sigcontext *sc, CPUHexagonState *env) { - __put_user(env->gpr[HEX_REG_R00], &sc->r0); - __put_user(env->gpr[HEX_REG_R01], &sc->r1); - __put_user(env->gpr[HEX_REG_R02], &sc->r2); - __put_user(env->gpr[HEX_REG_R03], &sc->r3); - __put_user(env->gpr[HEX_REG_R04], &sc->r4); - __put_user(env->gpr[HEX_REG_R05], &sc->r5); - __put_user(env->gpr[HEX_REG_R06], &sc->r6); - __put_user(env->gpr[HEX_REG_R07], &sc->r7); - __put_user(env->gpr[HEX_REG_R08], &sc->r8); - __put_user(env->gpr[HEX_REG_R09], &sc->r9); - __put_user(env->gpr[HEX_REG_R10], &sc->r10); - __put_user(env->gpr[HEX_REG_R11], &sc->r11); - __put_user(env->gpr[HEX_REG_R12], &sc->r12); - __put_user(env->gpr[HEX_REG_R13], &sc->r13); - __put_user(env->gpr[HEX_REG_R14], &sc->r14); - __put_user(env->gpr[HEX_REG_R15], &sc->r15); - __put_user(env->gpr[HEX_REG_R16], &sc->r16); - __put_user(env->gpr[HEX_REG_R17], &sc->r17); - __put_user(env->gpr[HEX_REG_R18], &sc->r18); - __put_user(env->gpr[HEX_REG_R19], &sc->r19); - __put_user(env->gpr[HEX_REG_R20], &sc->r20); - __put_user(env->gpr[HEX_REG_R21], &sc->r21); - __put_user(env->gpr[HEX_REG_R22], &sc->r22); - __put_user(env->gpr[HEX_REG_R23], &sc->r23); - __put_user(env->gpr[HEX_REG_R24], &sc->r24); - __put_user(env->gpr[HEX_REG_R25], &sc->r25); - __put_user(env->gpr[HEX_REG_R26], &sc->r26); - __put_user(env->gpr[HEX_REG_R27], &sc->r27); - __put_user(env->gpr[HEX_REG_R28], &sc->r28); - __put_user(env->gpr[HEX_REG_R29], &sc->r29); - __put_user(env->gpr[HEX_REG_R30], &sc->r30); - __put_user(env->gpr[HEX_REG_R31], &sc->r31); - __put_user(env->gpr[HEX_REG_SA0], &sc->sa0); - __put_user(env->gpr[HEX_REG_LC0], &sc->lc0); - __put_user(env->gpr[HEX_REG_SA1], &sc->sa1); - __put_user(env->gpr[HEX_REG_LC1], &sc->lc1); - __put_user(env->gpr[HEX_REG_M0], &sc->m0); - __put_user(env->gpr[HEX_REG_M1], &sc->m1); - __put_user(env->gpr[HEX_REG_USR], &sc->usr); - __put_user(env->gpr[HEX_REG_GP], &sc->gp); - __put_user(env->gpr[HEX_REG_UGP], &sc->ugp); - __put_user(env->gpr[HEX_REG_PC], &sc->pc); + abi_ulong preds = 0; - int i; - for (i = 0; i < NUM_PREGS; i++) { - __put_user(env->pred[i], &(sc->pred[i])); + for (int i = 0; i < 32; i++) { + __put_user(env->gpr[HEX_REG_R00 + i], &sc->sc_regs.gpr[i]); + } + __put_user(env->gpr[HEX_REG_SA0], &sc->sc_regs.sa0); + __put_user(env->gpr[HEX_REG_LC0], &sc->sc_regs.lc0); + __put_user(env->gpr[HEX_REG_SA1], &sc->sc_regs.sa1); + __put_user(env->gpr[HEX_REG_LC1], &sc->sc_regs.lc1); + __put_user(env->gpr[HEX_REG_M0], &sc->sc_regs.m0); + __put_user(env->gpr[HEX_REG_M1], &sc->sc_regs.m1); + __put_user(env->gpr[HEX_REG_USR], &sc->sc_regs.usr); + __put_user(env->gpr[HEX_REG_GP], &sc->sc_regs.gp); + __put_user(env->gpr[HEX_REG_UGP], &sc->sc_regs.ugp); + __put_user(env->gpr[HEX_REG_PC], &sc->sc_regs.pc); + + /* Consolidate predicates into p3_0 */ + for (int i = 0; i < NUM_PREGS; i++) { + preds |= (env->pred[i] & 0xff) << (i * 8); } + __put_user(preds, &sc->sc_regs.p3_0); + + /* Set cause and badva to 0 - these are set by kernel on exceptions */ + __put_user(0, &sc->sc_regs.cause); + __put_user(0, &sc->sc_regs.badva); + + __put_user(env->gpr[HEX_REG_CS0], &sc->sc_regs.cs0); + __put_user(env->gpr[HEX_REG_CS1], &sc->sc_regs.cs1); } static void setup_ucontext(struct target_ucontext *uc, @@ -192,53 +175,30 @@ badframe: static void restore_sigcontext(CPUHexagonState *env, struct target_sigcontext *sc) { - __get_user(env->gpr[HEX_REG_R00], &sc->r0); - __get_user(env->gpr[HEX_REG_R01], &sc->r1); - __get_user(env->gpr[HEX_REG_R02], &sc->r2); - __get_user(env->gpr[HEX_REG_R03], &sc->r3); - __get_user(env->gpr[HEX_REG_R04], &sc->r4); - __get_user(env->gpr[HEX_REG_R05], &sc->r5); - __get_user(env->gpr[HEX_REG_R06], &sc->r6); - __get_user(env->gpr[HEX_REG_R07], &sc->r7); - __get_user(env->gpr[HEX_REG_R08], &sc->r8); - __get_user(env->gpr[HEX_REG_R09], &sc->r9); - __get_user(env->gpr[HEX_REG_R10], &sc->r10); - __get_user(env->gpr[HEX_REG_R11], &sc->r11); - __get_user(env->gpr[HEX_REG_R12], &sc->r12); - __get_user(env->gpr[HEX_REG_R13], &sc->r13); - __get_user(env->gpr[HEX_REG_R14], &sc->r14); - __get_user(env->gpr[HEX_REG_R15], &sc->r15); - __get_user(env->gpr[HEX_REG_R16], &sc->r16); - __get_user(env->gpr[HEX_REG_R17], &sc->r17); - __get_user(env->gpr[HEX_REG_R18], &sc->r18); - __get_user(env->gpr[HEX_REG_R19], &sc->r19); - __get_user(env->gpr[HEX_REG_R20], &sc->r20); - __get_user(env->gpr[HEX_REG_R21], &sc->r21); - __get_user(env->gpr[HEX_REG_R22], &sc->r22); - __get_user(env->gpr[HEX_REG_R23], &sc->r23); - __get_user(env->gpr[HEX_REG_R24], &sc->r24); - __get_user(env->gpr[HEX_REG_R25], &sc->r25); - __get_user(env->gpr[HEX_REG_R26], &sc->r26); - __get_user(env->gpr[HEX_REG_R27], &sc->r27); - __get_user(env->gpr[HEX_REG_R28], &sc->r28); - __get_user(env->gpr[HEX_REG_R29], &sc->r29); - __get_user(env->gpr[HEX_REG_R30], &sc->r30); - __get_user(env->gpr[HEX_REG_R31], &sc->r31); - __get_user(env->gpr[HEX_REG_SA0], &sc->sa0); - __get_user(env->gpr[HEX_REG_LC0], &sc->lc0); - __get_user(env->gpr[HEX_REG_SA1], &sc->sa1); - __get_user(env->gpr[HEX_REG_LC1], &sc->lc1); - __get_user(env->gpr[HEX_REG_M0], &sc->m0); - __get_user(env->gpr[HEX_REG_M1], &sc->m1); - __get_user(env->gpr[HEX_REG_USR], &sc->usr); - __get_user(env->gpr[HEX_REG_GP], &sc->gp); - __get_user(env->gpr[HEX_REG_UGP], &sc->ugp); - __get_user(env->gpr[HEX_REG_PC], &sc->pc); + abi_ulong preds; - int i; - for (i = 0; i < NUM_PREGS; i++) { - __get_user(env->pred[i], &(sc->pred[i])); + for (int i = 0; i < 32; i++) { + __get_user(env->gpr[HEX_REG_R00 + i], &sc->sc_regs.gpr[i]); } + __get_user(env->gpr[HEX_REG_SA0], &sc->sc_regs.sa0); + __get_user(env->gpr[HEX_REG_LC0], &sc->sc_regs.lc0); + __get_user(env->gpr[HEX_REG_SA1], &sc->sc_regs.sa1); + __get_user(env->gpr[HEX_REG_LC1], &sc->sc_regs.lc1); + __get_user(env->gpr[HEX_REG_M0], &sc->sc_regs.m0); + __get_user(env->gpr[HEX_REG_M1], &sc->sc_regs.m1); + __get_user(env->gpr[HEX_REG_USR], &sc->sc_regs.usr); + __get_user(env->gpr[HEX_REG_GP], &sc->sc_regs.gp); + __get_user(env->gpr[HEX_REG_UGP], &sc->sc_regs.ugp); + __get_user(env->gpr[HEX_REG_PC], &sc->sc_regs.pc); + + /* Restore predicates from p3_0 */ + __get_user(preds, &sc->sc_regs.p3_0); + for (int i = 0; i < NUM_PREGS; i++) { + env->pred[i] = (preds >> (i * 8)) & 0xff; + } + + __get_user(env->gpr[HEX_REG_CS0], &sc->sc_regs.cs0); + __get_user(env->gpr[HEX_REG_CS1], &sc->sc_regs.cs1); } static void restore_ucontext(CPUHexagonState *env, struct target_ucontext *uc) |