I would like to enable support for the scv instruction to provide the Linux system calls.
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 instruction. 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) Thanks, Nick 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 differences: - 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.
