> On Dec 24, 2019, at 7:41 PM, christophe leroy <[email protected]> wrote:
>
>
>
>> Le 24/12/2019 à 03:24, Andy Lutomirski a écrit :
>>> On Mon, Dec 23, 2019 at 6:31 AM Christophe Leroy
>>> <[email protected]> wrote:
>>>
>>> On powerpc, VDSO functions and syscalls cannot be implemented in C
>>> because the Linux kernel ABI requires that CR[SO] bit is set in case
>>> of error and cleared when no error.
>>>
>>> As this cannot be done in C, C VDSO functions and syscall'based
>>> fallback need a trampoline in ASM.
>>>
>>> By moving the fallback calls out of the common code, arches like
>>> powerpc can implement both the call to C VDSO and the fallback call
>>> in a single trampoline function.
>> Maybe the issue is that I'm not a powerpc person, but I don't
>> understand this. The common vDSO code is in C. Presumably this means
>> that you need an asm trampoline no matter what to call the C code. Is
>> the improvement that, with this change, you can have the asm
>> trampoline do a single branch, so it's logically:
>> ret = [call the C code];
>> if (ret == 0) {
>> set success bit;
>> } else {
>> ret = fallback;
>> if (ret == 0)
>> set success bit;
>> else
>> set failure bit;
>> }
>
> More simple than above, in fact it is:
>
> ret = [call the C code];
> if (ret == 0) {
> set success bit;
> } else {
> ret = fallback [ which sets the success/failure bit];
> }
> return ret
Cute.
>
>
>> return ret;
>> instead of:
>> ret = [call the C code, which includes the fallback];
>
> C code cannot handle the success/failure bit so we need to do something which
> does:
>
> int assembly_to_fallback()
> {
> ret = [syscall the fallback]
> if (success bit set)
> return ret;
> else
> return -ret;
> }
Wait, your calling convention has syscalls return positive values on error?
But I think this is moot. The syscalls in question never return nonzero success
values, so you should be able to inline the syscall without worrying about this.
>
> Also means going back and forth between the success bit and negative return.
>
>> if (ret == 0)
>> set success bit;
>> else
>> set failure bit;
>> It's not obvious to me that the former ought to be faster.
>>>
>>> The two advantages are:
>>> - No need play back and forth with CR[SO] and negative return value.
>>> - No stack frame is required in VDSO C functions for the fallbacks.
>> How is no stack frame required? Do you mean that the presence of the
>> fallback causes worse code generation? Can you improve the fallback
>> instead?
>
> When function F1 calls function F2 (with BL insn), the link register (LR) is
> set with the return address in F1, so that at the end of F2, F2 branches to
> LR (with BLR insn), that's how you return from functions.
>
> When F2 calls function F3, the same happens, LR is set to the return of F3
> into F2. It means that F2 has to save LR in order to be able to return to F1,
> otherwise the return address from F2 into F1 is lost.
>
> But ... thinking about it once more, indeed fallback means doing a syscall,
> and in fact I realise that syscalls won't clobber LR, so it should be
> possible to do something. Let me try it.
>
With that plus assume that nonzero return means failure, I think you should
have all your bases covered.