Commit 5665bc35 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference...


powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls

The sc and scv 0 system calls have different ABI conventions, and
ptracers need to know which system call type is being used if they want
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: 7fa95f9a ("powerpc/64s: system call support for scv/rfscv instructions")
Cc: stable@vger.kernel.org # v5.9+
Reported-by: default avatar"Dmitry V. Levin" <ldv@altlinux.org>
Suggested-by: default avatar"Dmitry V. Levin" <ldv@altlinux.org>
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210520111931.2597127-1-npiggin@gmail.com
parent e2f5efd0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
========

+18 −9
Original line number Diff line number Diff line
@@ -1753,9 +1753,17 @@ TEST_F(TRACE_poke, getpid_runs_normally)
# define SYSCALL_RET_SET(_regs, _val)				\
	do {							\
		typeof(_val) _result = (_val);			\
		if ((_regs.trap & 0xfff0) == 0x3000) {		\
			/*					\
		 * A syscall error is signaled by CR0 SO bit	\
		 * and the code is stored as a positive value.	\
			 * scv 0 system call uses -ve result	\
			 * for error, so no need to adjust.	\
			 */					\
			SYSCALL_RET(_regs) = _result;		\
		} 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;	\
@@ -1764,6 +1772,7 @@ TEST_F(TRACE_poke, getpid_runs_normally)
				SYSCALL_RET(_regs) = _result;	\
				(_regs).ccr &= ~0x10000000;	\
			}					\
		}						\
	} while (0)
# define SYSCALL_RET_SET_ON_PTRACE_EXIT
#elif defined(__s390__)