All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls
@ 2021-05-20 11:19 Nicholas Piggin
  2021-05-20 11:19 ` [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with " Nicholas Piggin
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Nicholas Piggin @ 2021-05-20 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin, Dmitry V. Levin

The sc and scv 0 system calls have different ABI conventions, and
ptracers need to know which system call type is being used if it wants
to look at the syscall registers.

Document that pt_regs.trap can be used for this, and fix one in-tree user
to work with scv 0 syscalls.

Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions")
Reported-by: "Dmitry V. Levin" <ldv@altlinux.org>
Suggested-by: "Dmitry V. Levin" <ldv@altlinux.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 Documentation/powerpc/syscall64-abi.rst       | 10 +++++++
 tools/testing/selftests/seccomp/seccomp_bpf.c | 27 ++++++++++++-------
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/Documentation/powerpc/syscall64-abi.rst b/Documentation/powerpc/syscall64-abi.rst
index dabee3729e5a..56490c4c0c07 100644
--- a/Documentation/powerpc/syscall64-abi.rst
+++ b/Documentation/powerpc/syscall64-abi.rst
@@ -109,6 +109,16 @@ auxiliary vector.
 
 scv 0 syscalls will always behave as PPC_FEATURE2_HTM_NOSC.
 
+ptrace
+------
+When ptracing system calls (PTRACE_SYSCALL), the pt_regs.trap value contains
+the system call type that can be used to distinguish between sc and scv 0
+system calls, and the different register conventions can be accounted for.
+
+If the value of (pt_regs.trap & 0xfff0) is 0xc00 then the system call was
+performed with the sc instruction, if it is 0x3000 then the system call was
+performed with the scv 0 instruction.
+
 vsyscall
 ========
 
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 98c3b647f54d..e3d5c77a8612 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1753,16 +1753,25 @@ TEST_F(TRACE_poke, getpid_runs_normally)
 # define SYSCALL_RET_SET(_regs, _val)				\
 	do {							\
 		typeof(_val) _result = (_val);			\
-		/*						\
-		 * A syscall error is signaled by CR0 SO bit	\
-		 * and the code is stored as a positive value.	\
-		 */						\
-		if (_result < 0) {				\
-			SYSCALL_RET(_regs) = -_result;		\
-			(_regs).ccr |= 0x10000000;		\
-		} else {					\
+		if ((_regs.trap & 0xfff0) == 0x3000) {		\
+			/*					\
+			 * scv 0 system call uses -ve result	\
+			 * for error, so no need to adjust.	\
+			 */					\
 			SYSCALL_RET(_regs) = _result;		\
-			(_regs).ccr &= ~0x10000000;		\
+		} else {					\
+			/*					\
+			 * A syscall error is signaled by the	\
+			 * CR0 SO bit and the code is stored as	\
+			 * a positive value.			\
+			 */					\
+			if (_result < 0) {			\
+				SYSCALL_RET(_regs) = -_result;	\
+				(_regs).ccr |= 0x10000000;	\
+			} else {				\
+				SYSCALL_RET(_regs) = _result;	\
+				(_regs).ccr &= ~0x10000000;	\
+			}					\
 		}						\
 	} while (0)
 # define SYSCALL_RET_SET_ON_PTRACE_EXIT
-- 
2.23.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with scv syscalls
  2021-05-20 11:19 [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls Nicholas Piggin
@ 2021-05-20 11:19 ` Nicholas Piggin
  2021-05-20 11:45   ` Dmitry V. Levin
  2021-05-20 11:41 ` [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and " Dmitry V. Levin
  2021-05-21 12:44 ` Michael Ellerman
  2 siblings, 1 reply; 5+ messages in thread
From: Nicholas Piggin @ 2021-05-20 11:19 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin, Dmitry V. Levin

The scv implementation missed updating syscall return value and error
value get/set functions to deal with the changed register ABI. This
broke ptrace PTRACE_GET_SYSCALL_INFO as well as some kernel auditing
and tracing functions.

Fix. tools/testing/selftests/ptrace/get_syscall_info now passes when
scv is used.

Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions")
Reported-by: "Dmitry V. Levin" <ldv@altlinux.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/ptrace.h  | 45 +++++++++++++++++-------------
 arch/powerpc/include/asm/syscall.h | 42 +++++++++++++++++-----------
 2 files changed, 52 insertions(+), 35 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 9c9ab2746168..b476a685f066 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -19,6 +19,7 @@
 #ifndef _ASM_POWERPC_PTRACE_H
 #define _ASM_POWERPC_PTRACE_H
 
+#include <linux/err.h>
 #include <uapi/asm/ptrace.h>
 #include <asm/asm-const.h>
 
@@ -152,25 +153,6 @@ extern unsigned long profile_pc(struct pt_regs *regs);
 long do_syscall_trace_enter(struct pt_regs *regs);
 void do_syscall_trace_leave(struct pt_regs *regs);
 
-#define kernel_stack_pointer(regs) ((regs)->gpr[1])
-static inline int is_syscall_success(struct pt_regs *regs)
-{
-	return !(regs->ccr & 0x10000000);
-}
-
-static inline long regs_return_value(struct pt_regs *regs)
-{
-	if (is_syscall_success(regs))
-		return regs->gpr[3];
-	else
-		return -regs->gpr[3];
-}
-
-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
-{
-	regs->gpr[3] = rc;
-}
-
 #ifdef __powerpc64__
 #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
 #else
@@ -235,6 +217,31 @@ static __always_inline void set_trap_norestart(struct pt_regs *regs)
 	regs->trap |= 0x1;
 }
 
+#define kernel_stack_pointer(regs) ((regs)->gpr[1])
+static inline int is_syscall_success(struct pt_regs *regs)
+{
+	if (trap_is_scv(regs))
+		return !IS_ERR_VALUE((unsigned long)regs->gpr[3]);
+	else
+		return !(regs->ccr & 0x10000000);
+}
+
+static inline long regs_return_value(struct pt_regs *regs)
+{
+	if (trap_is_scv(regs))
+		return regs->gpr[3];
+
+	if (is_syscall_success(regs))
+		return regs->gpr[3];
+	else
+		return -regs->gpr[3];
+}
+
+static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
+{
+	regs->gpr[3] = rc;
+}
+
 #define arch_has_single_step()	(1)
 #define arch_has_block_step()	(true)
 #define ARCH_HAS_USER_SINGLE_STEP_REPORT
diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h
index fd1b518eed17..ba0f88f3a30d 100644
--- a/arch/powerpc/include/asm/syscall.h
+++ b/arch/powerpc/include/asm/syscall.h
@@ -41,11 +41,17 @@ static inline void syscall_rollback(struct task_struct *task,
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
-	/*
-	 * If the system call failed,
-	 * regs->gpr[3] contains a positive ERRORCODE.
-	 */
-	return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0;
+	if (trap_is_scv(regs)) {
+		unsigned long error = regs->gpr[3];
+
+		return IS_ERR_VALUE(error) ? error : 0;
+	} else {
+		/*
+		 * If the system call failed,
+		 * regs->gpr[3] contains a positive ERRORCODE.
+		 */
+		return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0;
+	}
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
@@ -58,18 +64,22 @@ static inline void syscall_set_return_value(struct task_struct *task,
 					    struct pt_regs *regs,
 					    int error, long val)
 {
-	/*
-	 * In the general case it's not obvious that we must deal with CCR
-	 * here, as the syscall exit path will also do that for us. However
-	 * there are some places, eg. the signal code, which check ccr to
-	 * decide if the value in r3 is actually an error.
-	 */
-	if (error) {
-		regs->ccr |= 0x10000000L;
-		regs->gpr[3] = error;
+	if (trap_is_scv(regs)) {
+		regs->gpr[3] = (long) error ?: val;
 	} else {
-		regs->ccr &= ~0x10000000L;
-		regs->gpr[3] = val;
+		/*
+		 * In the general case it's not obvious that we must deal with
+		 * CCR here, as the syscall exit path will also do that for us.
+		 * However there are some places, eg. the signal code, which
+		 * check ccr to decide if the value in r3 is actually an error.
+		 */
+		if (error) {
+			regs->ccr |= 0x10000000L;
+			regs->gpr[3] = error;
+		} else {
+			regs->ccr &= ~0x10000000L;
+			regs->gpr[3] = val;
+		}
 	}
 }
 
-- 
2.23.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls
  2021-05-20 11:19 [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls Nicholas Piggin
  2021-05-20 11:19 ` [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with " Nicholas Piggin
@ 2021-05-20 11:41 ` Dmitry V. Levin
  2021-05-21 12:44 ` Michael Ellerman
  2 siblings, 0 replies; 5+ messages in thread
From: Dmitry V. Levin @ 2021-05-20 11:41 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: linuxppc-dev

On Thu, May 20, 2021 at 09:19:30PM +1000, Nicholas Piggin wrote:
> The sc and scv 0 system calls have different ABI conventions, and
> ptracers need to know which system call type is being used if it wants
> to look at the syscall registers.

typo: s/if it wants/if they want/

> Document that pt_regs.trap can be used for this, and fix one in-tree user
> to work with scv 0 syscalls.
> 
> Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions")
> Reported-by: "Dmitry V. Levin" <ldv@altlinux.org>
> Suggested-by: "Dmitry V. Levin" <ldv@altlinux.org>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Also consider adding
Cc: stable@vger.kernel.org # 5.9+

Besides that, looks good, thanks!


-- 
ldv

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with scv syscalls
  2021-05-20 11:19 ` [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with " Nicholas Piggin
@ 2021-05-20 11:45   ` Dmitry V. Levin
  0 siblings, 0 replies; 5+ messages in thread
From: Dmitry V. Levin @ 2021-05-20 11:45 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: linuxppc-dev

On Thu, May 20, 2021 at 09:19:31PM +1000, Nicholas Piggin wrote:
> The scv implementation missed updating syscall return value and error
> value get/set functions to deal with the changed register ABI. This
> broke ptrace PTRACE_GET_SYSCALL_INFO as well as some kernel auditing
> and tracing functions.
> 
> Fix. tools/testing/selftests/ptrace/get_syscall_info now passes when
> scv is used.
> 
> Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions")
> Reported-by: "Dmitry V. Levin" <ldv@altlinux.org>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Thanks, feel free to add
Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>

Also consider adding
Cc: stable@vger.kernel.org # 5.9+


-- 
ldv

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls
  2021-05-20 11:19 [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls Nicholas Piggin
  2021-05-20 11:19 ` [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with " Nicholas Piggin
  2021-05-20 11:41 ` [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and " Dmitry V. Levin
@ 2021-05-21 12:44 ` Michael Ellerman
  2 siblings, 0 replies; 5+ messages in thread
From: Michael Ellerman @ 2021-05-21 12:44 UTC (permalink / raw)
  To: linuxppc-dev, Nicholas Piggin; +Cc: Dmitry V. Levin

On Thu, 20 May 2021 21:19:30 +1000, Nicholas Piggin wrote:
> The sc and scv 0 system calls have different ABI conventions, and
> ptracers need to know which system call type is being used if it wants
> to look at the syscall registers.
> 
> Document that pt_regs.trap can be used for this, and fix one in-tree user
> to work with scv 0 syscalls.

Applied to powerpc/fixes.

[1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls
      https://git.kernel.org/powerpc/c/5665bc35c1ed917ac8fd06cb651317bb47a65b10
[2/2] powerpc/64s/syscall: Fix ptrace syscall info with scv syscalls
      https://git.kernel.org/powerpc/c/d72500f992849d31ebae8f821a023660ddd0dcc2

cheers

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-05-21 12:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-20 11:19 [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls Nicholas Piggin
2021-05-20 11:19 ` [PATCH 2/2] powerpc/64s/syscall: Fix ptrace syscall info with " Nicholas Piggin
2021-05-20 11:45   ` Dmitry V. Levin
2021-05-20 11:41 ` [PATCH 1/2] powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and " Dmitry V. Levin
2021-05-21 12:44 ` Michael Ellerman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.