parisc: Add support for restartable sequences syscall
diff mbox

Message ID 20180628205300.GA22482@ls3530.fritz.box
State New
Headers show

Commit Message

Helge Deller June 28, 2018, 8:53 p.m. UTC
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@gmx.de>

--
To unsubscribe from this list: send the line "unsubscribe linux-parisc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

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))