[PATCH v3 2/5] microblaze: reserve the ABI argument-home area in the signal frame
From: Ramin Moussavi
Date: Fri Aug 21 2026 - 11:24:39 EST
The MicroBlaze procedure call standard reserves [r1+0] for the return
address and lets a callee store its incoming register arguments r5..r10
into the caller-provided home slots at [r1+4]..[r1+24]. When the kernel
enters a signal handler it sets r1 to point at struct rt_sigframe, whose
leading member is the siginfo prepared for the handler. A handler that
homes its arguments - which an unoptimised (-O0) build always does -
therefore overwrites the first 24 bytes of that siginfo, so an
SA_SIGINFO handler reads corrupted values. The stores stay within
siginfo (128 bytes) and do not reach the ucontext behind it.
Reserve the home area by making a seven-word gap -- the return-address
slot plus the six argument slots, 28 bytes -- the first member of struct
rt_sigframe, so the handler's argument stores land in scratch space
instead of clobbering siginfo.
Tested on qemu-system-microblazeel (petalogix-s3adsp1800) with the
uClibc-ng NPTL test suite: tst-timer4, tst-timer5, tst-mqueue5 and
tst-signal6 pass; before this change they failed because the handler
clobbered the signal frame.
Fixes: 2148daa9c45f ("microblaze_v8: Signal support")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude:claude-opus-5
Signed-off-by: Ramin Moussavi <ramin.moussavi@xxxxxxxxx>
---
arch/microblaze/kernel/signal.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index c78a0ff48066..4956014a9937 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -49,6 +49,14 @@ struct sigframe {
};
struct rt_sigframe {
+ /*
+ * Home area for the handler's register arguments: the MicroBlaze
+ * ABI reserves [r1+0] for the return address and lets the callee
+ * store r5..r10 at [r1+4]..[r1+24], and r1 points at this frame
+ * when the handler is entered. Without the gap those stores
+ * corrupt frame->info.
+ */
+ unsigned long abi_gap[7];
struct siginfo info;
struct ucontext uc;
unsigned long tramp[2]; /* signal trampoline */
--
2.53.0