On Thu, Jul 10, 2025 at 06:35:17PM +0200, Jens Remus wrote:
Add s390 support for unwinding of user space using SFrame. This
leverages the previous commits to address the following s390
particularities:
- The CFA is defined as the value of the stack pointer (SP) at call
site in the previous frame + 160. Therefore the SP unwinds as
SP = CFA - 160. Therefore use a SP value offset from CFA of -160.
- The return address (RA) is not saved on the stack at function entry.
It is also not saved in the function prologue, when in leaf functions.
Therefore the RA does not necessarily need to be unwound in the first
unwinding step for the topmost frame.
- The frame pointer (FP) and/or return address (RA) may be saved in
other registers when in leaf functions. GCC effectively uses
floating-point registers (FPR) for this purpose. Therefore DWARF
register numbers may be encoded in the SFrame FP/RA offsets.
...
quoted hunk ↗ jump to hunk
+static inline void __s390_get_dwarf_fpr(unsigned long *val, int regnum)
+{
+ switch (regnum) {
+ case 16:
+ fpu_std(0, (freg_t *)val);
+ break;
...
quoted hunk ↗ jump to hunk
+static inline int s390_unwind_user_get_reg(unsigned long *val, int regnum)
+{
+ if (0 <= regnum && regnum <= 15) {
+ struct pt_regs *regs = task_pt_regs(current);
+ *val = regs->gprs[regnum];
+ } else if (16 <= regnum && regnum <= 31) {
+ __s390_get_dwarf_fpr(val, regnum);
This won't work with other potential in-kernel fpu users. User space fpr
contents may have been written to the current task's fpu save area and fprs
may have been clobbered by in-kernel users; so you need to get register
contents from the correct location. See arch/s390/include/asm/fpu.h.