Merge branch 'fixes' into features

This helps to avoid several merge conflicts later.

* fixes:
  s390/extable: fix exception table sorting
  s390/ftrace: fix arch_ftrace_get_regs implementation
  s390/ftrace: fix ftrace_caller/ftrace_regs_caller generation
  s390/setup: preserve memory at OLDMEM_BASE and OLDMEM_SIZE
  s390/cio: verify the driver availability for path_event call
  s390/module: fix building test_modules_helpers.o with clang
  MAINTAINERS: downgrade myself to Reviewer for s390
  MAINTAINERS: add Alexander Gordeev as maintainer for s390

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Vasily Gorbik 2022-03-01 21:02:48 +01:00
commit 9a4f03ad6d
10 changed files with 68 additions and 13 deletions

View File

@ -16817,8 +16817,8 @@ F: drivers/video/fbdev/savage/
S390
M: Heiko Carstens <hca@linux.ibm.com>
M: Vasily Gorbik <gor@linux.ibm.com>
M: Christian Borntraeger <borntraeger@linux.ibm.com>
R: Alexander Gordeev <agordeev@linux.ibm.com>
M: Alexander Gordeev <agordeev@linux.ibm.com>
R: Christian Borntraeger <borntraeger@linux.ibm.com>
R: Sven Schnelle <svens@linux.ibm.com>
L: linux-s390@vger.kernel.org
S: Supported

View File

@ -69,8 +69,13 @@ static inline void swap_ex_entry_fixup(struct exception_table_entry *a,
{
a->fixup = b->fixup + delta;
b->fixup = tmp.fixup - delta;
a->handler = b->handler + delta;
b->handler = tmp.handler - delta;
a->handler = b->handler;
if (a->handler)
a->handler += delta;
b->handler = tmp.handler;
if (b->handler)
b->handler -= delta;
}
#define swap_ex_entry_fixup swap_ex_entry_fixup
#endif

View File

@ -47,15 +47,17 @@ struct ftrace_regs {
static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
{
return &fregs->regs;
struct pt_regs *regs = &fregs->regs;
if (test_pt_regs_flag(regs, PIF_FTRACE_FULL_REGS))
return regs;
return NULL;
}
static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *fregs,
unsigned long ip)
{
struct pt_regs *regs = arch_ftrace_get_regs(fregs);
regs->psw.addr = ip;
fregs->regs.psw.addr = ip;
}
/*

View File

@ -15,11 +15,13 @@
#define PIF_EXECVE_PGSTE_RESTART 1 /* restart execve for PGSTE binaries */
#define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */
#define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */
#define PIF_FTRACE_FULL_REGS 4 /* all register contents valid (ftrace) */
#define _PIF_SYSCALL BIT(PIF_SYSCALL)
#define _PIF_EXECVE_PGSTE_RESTART BIT(PIF_EXECVE_PGSTE_RESTART)
#define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET)
#define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT)
#define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS)
#ifndef __ASSEMBLY__

View File

@ -158,9 +158,38 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
return 0;
}
static struct ftrace_hotpatch_trampoline *ftrace_get_trampoline(struct dyn_ftrace *rec)
{
struct ftrace_hotpatch_trampoline *trampoline;
struct ftrace_insn insn;
s64 disp;
u16 opc;
if (copy_from_kernel_nofault(&insn, (void *)rec->ip, sizeof(insn)))
return ERR_PTR(-EFAULT);
disp = (s64)insn.disp * 2;
trampoline = (void *)(rec->ip + disp);
if (get_kernel_nofault(opc, &trampoline->brasl_opc))
return ERR_PTR(-EFAULT);
if (opc != 0xc015)
return ERR_PTR(-EINVAL);
return trampoline;
}
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
struct ftrace_hotpatch_trampoline *trampoline;
u64 old;
trampoline = ftrace_get_trampoline(rec);
if (IS_ERR(trampoline))
return PTR_ERR(trampoline);
if (get_kernel_nofault(old, &trampoline->interceptor))
return -EFAULT;
if (old != old_addr)
return -EINVAL;
s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
return 0;
}
@ -188,6 +217,12 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
struct ftrace_hotpatch_trampoline *trampoline;
trampoline = ftrace_get_trampoline(rec);
if (IS_ERR(trampoline))
return PTR_ERR(trampoline);
s390_kernel_write(&trampoline->interceptor, &addr, sizeof(addr));
/* Expect brcl 0x0,... */
return ftrace_patch_branch_mask((void *)rec->ip, 0xc004, true);
}
@ -301,7 +336,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
regs = ftrace_get_regs(fregs);
p = get_kprobe((kprobe_opcode_t *)ip);
if (unlikely(!p) || kprobe_disabled(p))
if (!regs || unlikely(!p) || kprobe_disabled(p))
goto out;
if (kprobe_running()) {

View File

@ -25,6 +25,7 @@ ENDPROC(ftrace_stub)
#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
#define STACK_PTREGS_ORIG_GPR2 (STACK_PTREGS + __PT_ORIG_GPR2)
#define STACK_PTREGS_FLAGS (STACK_PTREGS + __PT_FLAGS)
#ifdef __PACK_STACK
/* allocate just enough for r14, r15 and backchain */
#define TRACED_FUNC_FRAME_SIZE 24
@ -55,6 +56,14 @@ ENDPROC(ftrace_stub)
.if \allregs == 1
stg %r14,(STACK_PTREGS_PSW)(%r15)
stosm (STACK_PTREGS_PSW)(%r15),0
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
mvghi STACK_PTREGS_FLAGS(%r15),_PIF_FTRACE_FULL_REGS
#else
lghi %r14,_PIF_FTRACE_FULL_REGS
stg %r14,STACK_PTREGS_FLAGS(%r15)
#endif
.else
xc STACK_PTREGS_FLAGS(8,%r15),STACK_PTREGS_FLAGS(%r15)
.endif
lg %r14,(__SF_GPRS+8*8)(%r1) # restore original return address

View File

@ -800,6 +800,8 @@ static void __init check_initrd(void)
static void __init reserve_kernel(void)
{
memblock_reserve(0, STARTUP_NORMAL_OFFSET);
memblock_reserve(OLDMEM_BASE, sizeof(unsigned long));
memblock_reserve(OLDMEM_SIZE, sizeof(unsigned long));
memblock_reserve(__amode31_base, __eamode31 - __samode31);
memblock_reserve(__pa(sclp_early_sccb), EXT_SCCB_READ_SCP);
memblock_reserve(__pa(_stext), _end - _stext);

View File

@ -5,9 +5,6 @@
#include "test_modules.h"
#define DECLARE_RETURN(i) int test_modules_return_ ## i(void)
REPEAT_10000(DECLARE_RETURN);
/*
* Test that modules with many relocations are loaded properly.
*/

View File

@ -47,4 +47,7 @@
__REPEAT_10000_1(f, 8); \
__REPEAT_10000_1(f, 9)
#define DECLARE_RETURN(i) int test_modules_return_ ## i(void)
REPEAT_10000(DECLARE_RETURN);
#endif

View File

@ -1180,7 +1180,7 @@ static int io_subchannel_chp_event(struct subchannel *sch,
else
path_event[chpid] = PE_NONE;
}
if (cdev)
if (cdev && cdev->drv && cdev->drv->path_event)
cdev->drv->path_event(cdev, path_event);
break;
}