powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls
commit 5665bc35c1ed917ac8fd06cb651317bb47a65b10 upstream.
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: 7fa95f9ada
("powerpc/64s: system call support for scv/rfscv instructions")
Cc: stable@vger.kernel.org # v5.9+
Reported-by: "Dmitry V. Levin" <ldv@altlinux.org>
Suggested-by: "Dmitry V. Levin" <ldv@altlinux.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210520111931.2597127-1-npiggin@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
3708b7a9c2
commit
105345b909
@@ -96,6 +96,16 @@ auxiliary vector.
|
|||||||
|
|
||||||
scv 0 syscalls will always behave as PPC_FEATURE2_HTM_NOSC.
|
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
|
vsyscall
|
||||||
========
|
========
|
||||||
|
|
||||||
|
@@ -1753,9 +1753,17 @@ TEST_F(TRACE_poke, getpid_runs_normally)
|
|||||||
# define SYSCALL_RET_SET(_regs, _val) \
|
# define SYSCALL_RET_SET(_regs, _val) \
|
||||||
do { \
|
do { \
|
||||||
typeof(_val) _result = (_val); \
|
typeof(_val) _result = (_val); \
|
||||||
|
if ((_regs.trap & 0xfff0) == 0x3000) { \
|
||||||
/* \
|
/* \
|
||||||
* A syscall error is signaled by CR0 SO bit \
|
* scv 0 system call uses -ve result \
|
||||||
* and the code is stored as a positive value. \
|
* 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) { \
|
if (_result < 0) { \
|
||||||
SYSCALL_RET(_regs) = -_result; \
|
SYSCALL_RET(_regs) = -_result; \
|
||||||
@@ -1764,6 +1772,7 @@ TEST_F(TRACE_poke, getpid_runs_normally)
|
|||||||
SYSCALL_RET(_regs) = _result; \
|
SYSCALL_RET(_regs) = _result; \
|
||||||
(_regs).ccr &= ~0x10000000; \
|
(_regs).ccr &= ~0x10000000; \
|
||||||
} \
|
} \
|
||||||
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define SYSCALL_RET_SET_ON_PTRACE_EXIT
|
# define SYSCALL_RET_SET_ON_PTRACE_EXIT
|
||||||
#elif defined(__s390__)
|
#elif defined(__s390__)
|
||||||
|
Reference in New Issue
Block a user