powerpc Linux scv support and scv system call ABI proposal
npiggin at gmail.com
Tue Jan 28 21:50:48 AEDT 2020
I would like to enable support for the scv instruction to provide the Linux
This requires two things to be defined, firstly how to advertise support
for scv and how to allocate and advertise support for individual scv
vectors. Secondly, how to define a Linux system call ABI with this new
I have put together a rough proposal along with some options and
questions. Any thoughts or input would be welcome, I have probably
missed some things so please point them out.
(I will be on vacation for two weeks from the end of the week, may not
get to replying immediately)
System Call Vectored (scv) ABI
The scv instruction is introduced with POWER9 / ISA3, it comes with an
rfscv counter-part. The benefit of these instructions is performance
(trading slower SRR0/1 with faster LR/CTR registers, and entering the
kernel with MSR[EE] and MSR[RI] left enabled, which can avoid one mtmsrd
instruction. Another benefit is that the ABI can be changed if there is
a good reason to.
The scv instruction has 128 interrupt entry points (not enough to cover
the Linux system call space). The proposal is to assign scv numbers
conservatively. 'scv 0' could be used for the regular Linux system call
ABI initially. Examples of other assignments could be 32-bit compat
system calls, and firmware service calls.
Linux has not enabled FSCR[SCV] yet, so the instruction will trap with illegal
instruction on current environments. Linux has defined a HWCAP2 bit
PPC_FEATURE2_SCV for SCV support, but does not set it.
One option is for PPC_FEATURE2_SCV to indicate 'scv 0' support, and a new HWCAP
bit assigned for each new scv vector supported for userspace. This is the most
regular and flexible approach. It requires the most HWCAP space, but vector
usage is not expected to grow quickly.
Another option is for PPC_FEATURE2_SCV to indicate 'scv 0', and other vectors
will each return -ENOSYS, then when they are assigned to a new ABI, it will
define a particular way they can be queried for support (which would return
something other than -ENOSYS if supported). This will not require more HWCAP
bits, but it's less regular and more complicated to determine.
* Proposal is for PPC_FEATURE2_SCV to indicate 'scv 0' support, all other
vectors will return -ENOSYS, and the decision for how to add support for
a new vector deferred until we see the next user.
* Proposal is for scv 0 to provide the standard Linux system call ABI with some
- LR is volatile across scv calls. This is necessary for support because the
scv instruction clobbers LR.
- CR1 and CR5-CR7 are volatile. This matches the C ABI and would allow the
system call exit to avoid restoring the CR register.
- Error handling: use of CR0[SO] to indicate error requires a mtcr / mtocr
instruction on the kernel side, and it is currently not implemented well
in glibc, requiring a mfcr (mfocr should be possible and asm goto support
would allow a better implementation). Is it worth continuing this style of
error handling? Or just move to -ve return means error? Using a different
bit would allow the kernel to piggy back the CR return code setting with
a test for the error case exit.
- R2 could be volatile as though it's an external function call, which
would avoid one store in the system call entry path. However it would
require the caller to load R2 after the system call returns, where the
latency of the load can not be overlapped with the costly system call
exit sequence. On balance, it may be better to keep R2 as non-volatile.
- Number of volatile registers available seems sufficient. Linux's 'sc'
handler is badly constrained here, but that is because it is shared
between both hypercall and syscall handlers, which have different
call conventions that share no volatile GPR registers! r9-r12 should
be quite enough.
- Should this be for 64-bit only? 'scv 1' could be reserved for 32-bit
calls if there was interest in developing an ABI for 32-bit programs.
Marginal benefit in avoiding compat syscall selection.
More information about the Linuxppc-dev