On 2026/10/20 下午10:23, Peter Maydell wrote:
In extframe_alloc() we allocate space on the guest stack for a
context struct, which consists of a target_sctx_info plus a more
specific struct such as target_lasx_context.  The specific struct may
have a higher alignment requirement than the basic target_sctx_info.

The Linux kernel code for this is in arch/loongarch/kernel/signal.c
in extframe_alloc():

        unsigned long new_base = base - size;

        new_base = round_down(new_base, (align < 16 ? 16 : align));
        new_base -= sizeof(struct sctx_info);

and it first adjusts the base (SP) address down by the size of the
specific struct, then rounds that down to provide the required
alignment, and finally subtracts the size of the sctx_info.

QEMU's version does this in the wrong order, subtracting both the
specific struct size and the sctx_info size before rounding down for
alignment.  This means that for the target_lasx_context which needs
32-alignment, we instead give the start of sctx_info 32-alignment,
which (since that is 16 bytes long) means that the
target_lasx_context is only 16-aligned.

This manifests as a failure in the TCG tests such as
loongarch64-linux-user-signals.test if you build with the clang
sanitizers enabled:

../../linux-user/loongarch64/signal.c:182:13: runtime error: member access 
within misaligned address 0x7dc793950b90 for type 'struct target_lasx_context', 
which requires 32 byte alignment
0x7dc793950b90: note: pointer points here
  00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 
00 00 00  00 00 00 00
               ^
     #0 0x57216113d881 in setup_sigframe 
/home/pm215/qemu/build/clang/../../linux-user/loongarch64/signal.c:182:13
     #1 0x57216113d881 in setup_rt_frame 
/home/pm215/qemu/build/clang/../../linux-user/loongarch64/signal.c:389:5
     #2 0x5721612a5041 in handle_pending_signal 
/home/pm215/qemu/build/clang/../../linux-user/signal.c:1349:9
     #3 0x5721612a46ef in process_pending_signals 
/home/pm215/qemu/build/clang/../../linux-user/signal.c:1401:17
     #4 0x57216113baa3 in cpu_loop 
/home/pm215/qemu/build/clang/../../linux-user/loongarch64/cpu_loop.c:121:9

Correct setup_extcontext() to match the order the kernel does it.

Cc: [email protected]
Fixes: 9d5cd6587a70d613 ("linux-user: Add LoongArch signal support")
Signed-off-by: Peter Maydell <[email protected]>
---
  linux-user/loongarch64/signal.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index eff75bcdc86..04015e06fda 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -111,9 +111,10 @@ static abi_ptr extframe_alloc(struct extctx_layout *extctx,
  {
      abi_ptr sp = orig_sp;
- sp -= sizeof(struct target_sctx_info) + size;
+    sp -= size;
      align = MAX(align, CONTEXT_INFO_ALIGN);
      sp = ROUND_DOWN(sp, align);
+    sp -= sizeof(struct target_sctx_info);
      sctx->gaddr = sp;
size = orig_sp - sp;

Reviewed-by: Bibo Mao <[email protected]>


Reply via email to