Implement support for restartable sequences on parisc, which requires three things: - Call rseq_handle_notify_resume() on return to userspace if TIF_NOTIFY_RESUME is set. - Call rseq_signal_deliver() to fixup the pre-signal stack frame when a signal is delivered whilst executing a restartable sequence critical section. - Select CONFIG_HAVE_RSEQ. Signed-off-by: Helge Deller <deller@xxxxxx> diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 17526bebcbd2..6275e4b5c38f 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -4,6 +4,7 @@ config PARISC select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_IDE select HAVE_OPROFILE + select HAVE_RSEQ select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER select HAVE_SYSCALL_TRACEPOINTS diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index dc77c5a51db7..da54c11164ed 100644 --- a/arch/parisc/include/uapi/asm/unistd.h +++ b/arch/parisc/include/uapi/asm/unistd.h @@ -365,8 +365,9 @@ #define __NR_pwritev2 (__NR_Linux + 348) #define __NR_statx (__NR_Linux + 349) #define __NR_io_pgetevents (__NR_Linux + 350) +#define __NR_rseq (__NR_Linux + 351) -#define __NR_Linux_syscalls (__NR_io_pgetevents + 1) +#define __NR_Linux_syscalls (__NR_rseq + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index e95207c0565e..939994ab4837 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1806,6 +1806,19 @@ ENTRY_CFI(syscall_exit) */ loadgp +#ifdef CONFIG_DEBUG_RSEQ + /* Check whether the syscall is issued inside a restartable sequence */ + #ifdef CONFIG_64BIT + ldo FRAME_SIZE(%r30), %r30 + BL rseq_syscall, %r2 + ldo -16(%r30),%r29 /* Reference param save area */ + #else + BL rseq_syscall, %r2 + ldo FRAME_SIZE(%r30), %r30 + #endif + ldo -FRAME_SIZE(%r30), %r30 +#endif + syscall_check_resched: /* check for reschedule */ diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 342073f44d3f..14a25de0e901 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -424,6 +424,8 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall) DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n", ksig->sig, ksig->ka, ksig->info, oldset, regs); + + rseq_signal_deliver(ksig, regs); /* Set up the stack frame */ ret = setup_rt_frame(ksig, oldset, regs, in_syscall); @@ -611,5 +613,6 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall) if (test_thread_flag(TIF_NOTIFY_RESUME)) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); + rseq_handle_notify_resume(NULL, regs); } } diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index fe3f2a49d2b1..f156b4589118 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -446,6 +446,7 @@ ENTRY_COMP(pwritev2) ENTRY_SAME(statx) ENTRY_COMP(io_pgetevents) /* 350 */ + ENTRY_SAME(rseq) .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b)) -- To unsubscribe from this list: send the line "unsubscribe linux-parisc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html