powerpc: Use scv instruction on clone when available

clone already uses r31 to temporarily save input arguments before doing the
syscall, so we use a different register to read from the TCB. We can also avoid
allocating another stack frame, which is not needed since we can simply extend
the usage of the red zone.

Tested-by: Lucas A. M. Magalhães <lamm@linux.ibm.com>
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
This commit is contained in:
Matheus Castanho 2020-12-03 14:15:28 -03:00 committed by Tulio Magno Quites Machado Filho
parent 68ab82f566
commit 41f013cef2

View File

@ -38,9 +38,11 @@ ENTRY (__clone)
beq- cr0,L(badargs)
/* Save some regs in the "red zone". */
std r28,-32(r1)
std r29,-24(r1)
std r30,-16(r1)
std r31,-8(r1)
cfi_offset(r28,-32)
cfi_offset(r29,-24)
cfi_offset(r30,-16)
cfi_offset(r31,-8)
@ -69,11 +71,26 @@ ENTRY (__clone)
/* Do the call. */
li r0,SYS_ify(clone)
DO_CALL_SC
CHECK_SCV_SUPPORT r28 0f
/* This is equivalent to DO_CALL_SCV, but we cannot use the macro here
because it uses CFI directives and we just called cfi_endproc. */
mflr r9
std r9,FRAME_LR_SAVE(r1)
scv 0
ld r9,FRAME_LR_SAVE(r1)
mtlr r9
/* Check for child process. */
/* When using scv, error is indicated by negative r3. */
cmpdi cr1,r3,0
b 1f
0: DO_CALL_SC
/* Check for child process. */
/* With sc, error is indicated by cr0.SO. */
cmpdi cr1,r3,0
crandc cr1*4+eq,cr1*4+eq,cr0*4+so
1:
bne- cr1,L(parent) /* The '-' is to minimise the race. */
std r2,FRAME_TOC_SAVE(r1)
@ -95,19 +112,29 @@ L(badargs):
TAIL_CALL_SYSCALL_ERROR
L(parent):
/* Check if scv is available. */
cmpdi cr1,r28,0
/* Parent. Restore registers & return. */
cfi_offset(r28,-32)
cfi_offset(r29,-24)
cfi_offset(r30,-16)
cfi_offset(r31,-8)
ld r28,-32(r1)
ld r29,-24(r1)
ld r30,-16(r1)
ld r31,-8(r1)
cfi_restore(r28)
cfi_restore(r29)
cfi_restore(r30)
cfi_restore(r31)
RET_SC
TAIL_CALL_SYSCALL_ERROR
beq cr1,0f
RET_SCV
b 1f
0: RET_SC
1: TAIL_CALL_SYSCALL_ERROR
END (__clone)