Skip to content

Commit 1389f17

Browse files
hcahcaVasily Gorbik
authored andcommitted
s390/ftrace: fix arch_ftrace_get_regs implementation
arch_ftrace_get_regs is supposed to return a struct pt_regs pointer only if the pt_regs structure contains all register contents, which means it must have been populated when created via ftrace_regs_caller. If it was populated via ftrace_caller the contents are not complete (the psw mask part is missing), and therefore a NULL pointer needs be returned. The current code incorrectly always returns a struct pt_regs pointer. Fix this by adding another pt_regs flag which indicates if the contents are complete, and fix arch_ftrace_get_regs accordingly. Fixes: 8949796 ("s390/ftrace: provide separate ftrace_caller/ftrace_regs_caller implementations") Reported-by: Christophe Leroy <christophe.leroy@csgroup.eu> Reported-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Reviewed-by: Sven Schnelle <svens@linux.ibm.com> Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 9fa881f commit 1389f17

File tree

4 files changed

+18
-5
lines changed

4 files changed

+18
-5
lines changed

arch/s390/include/asm/ftrace.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,17 @@ struct ftrace_regs {
4747

4848
static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
4949
{
50-
return &fregs->regs;
50+
struct pt_regs *regs = &fregs->regs;
51+
52+
if (test_pt_regs_flag(regs, PIF_FTRACE_FULL_REGS))
53+
return regs;
54+
return NULL;
5155
}
5256

5357
static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *fregs,
5458
unsigned long ip)
5559
{
56-
struct pt_regs *regs = arch_ftrace_get_regs(fregs);
57-
58-
regs->psw.addr = ip;
60+
fregs->regs.psw.addr = ip;
5961
}
6062

6163
/*

arch/s390/include/asm/ptrace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
#define PIF_EXECVE_PGSTE_RESTART 1 /* restart execve for PGSTE binaries */
1616
#define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */
1717
#define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */
18+
#define PIF_FTRACE_FULL_REGS 4 /* all register contents valid (ftrace) */
1819

1920
#define _PIF_SYSCALL BIT(PIF_SYSCALL)
2021
#define _PIF_EXECVE_PGSTE_RESTART BIT(PIF_EXECVE_PGSTE_RESTART)
2122
#define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET)
2223
#define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT)
24+
#define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS)
2325

2426
#ifndef __ASSEMBLY__
2527

arch/s390/kernel/ftrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
326326

327327
regs = ftrace_get_regs(fregs);
328328
p = get_kprobe((kprobe_opcode_t *)ip);
329-
if (unlikely(!p) || kprobe_disabled(p))
329+
if (!regs || unlikely(!p) || kprobe_disabled(p))
330330
goto out;
331331

332332
if (kprobe_running()) {

arch/s390/kernel/mcount.S

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ ENDPROC(ftrace_stub)
2727
#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
2828
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
2929
#define STACK_PTREGS_ORIG_GPR2 (STACK_PTREGS + __PT_ORIG_GPR2)
30+
#define STACK_PTREGS_FLAGS (STACK_PTREGS + __PT_FLAGS)
3031
#ifdef __PACK_STACK
3132
/* allocate just enough for r14, r15 and backchain */
3233
#define TRACED_FUNC_FRAME_SIZE 24
@@ -57,6 +58,14 @@ ENDPROC(ftrace_stub)
5758
.if \allregs == 1
5859
stg %r14,(STACK_PTREGS_PSW)(%r15)
5960
stosm (STACK_PTREGS_PSW)(%r15),0
61+
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
62+
mvghi STACK_PTREGS_FLAGS(%r15),_PIF_FTRACE_FULL_REGS
63+
#else
64+
lghi %r14,_PIF_FTRACE_FULL_REGS
65+
stg %r14,STACK_PTREGS_FLAGS(%r15)
66+
#endif
67+
.else
68+
xc STACK_PTREGS_FLAGS(8,%r15),STACK_PTREGS_FLAGS(%r15)
6069
.endif
6170

6271
lg %r14,(__SF_GPRS+8*8)(%r1) # restore original return address

0 commit comments

Comments
 (0)