Add FUTEX_CMP_REQUEUE futex op
Subsystems (2)
Quoted 11 lines
Quoted 10 lines
My personal preference is:
1) change s390* entry*.S so that all syscalls can use up to 6 arguments, otherwise we'll have the same problem every now and then (last syscall before this one wasfadvise64_64if I remember well)
2) allowsys_futexto have 6 arguments (the 6th on the stack, get_user'ed from an s390 wrapper)
3) special structure passed in 5th argument forFUTEX_CMP_REQUEUE
4) your solution
(you have a special wrapper around futex anyway, so why not to handle it there already and create completely new syscall).
Quoted 6 lines
I have talked to Martin about it (he won't be online for one more week), and he proposed a variant of 2):
sys_futex, and possibly further new syscalls that might get added, pass their sixth argument in %r7, which is easier to get by than the user stack. Unlike doing it in the standard system call path, this won't cause any overhead for the other syscalls, but we need some wrappers.
I prefer to store the additional argument in %r7 for ALL system calls to avoid addtitional system call wrappers. That way new system calls with 6 arguments can be added without problems. The store for the additional 6th argument can be hidden in a agi slot so this is pretty much the perfect solution.
blue skies,
Martin.
---
[PATCH] s390: add support for 6 system call arguments (FUTEX_CMP_REQUEUE).
This patch adds support for 6 system call arguments on s390. The first exploiter of this will be the sys_futex system call for the FUTEX_CMP_REQUEUE operation. The idea is simple: use register %r7 for the 6th argument. This can be extended to 7/8/9/... arguments if there ever will be the need for it. To call the system call function in the kernel the additional arguments needs to get stored on the stack. 8 bytes are added to the head of struct pt_regs. %r7 is stored to the additional field for all system calls. The store is hidden in a address-generation-interlock slot, it doesn't slow down the system call path.
diffstat:
arch/s390/kernel/asm-offsets.c | 1 + arch/s390/kernel/compat_wrapper.S | 2 ++ arch/s390/kernel/entry.S | 10 +++++++--- arch/s390/kernel/entry64.S | 10 +++++++--- arch/s390/kernel/ptrace.c | 10 +++++----- include/asm-s390/ptrace.h | 1 + 6 files changed, 23 insertions(+), 11 deletions(-)
arch/s390/kernel/asm-offsets.c +1 -0
@@ -32,6 +32,7 @@ DEFINE(__TI_cpu, offsetof(struct thread_info, cpu),); DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count),);BLANK (); + DEFINE(__PT_ARGS, offsetof(struct pt_regs, args),); DEFINE(__PT_PSW, offsetof(struct pt_regs, psw),); DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs),); DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2),);
arch/s390/kernel/compat_wrapper.S +2 -0
@@ -1097,6 +1097,8 @@ lgfr %r4,%r4 # int llgtr %r5,%r5 # struct compat_timespec * llgtr %r6,%r6 # u32 * + lgf %r0,164(%r15) # int + stg %r0,160(%r15) jg compat_sys_futex # branch to system call .globl sys32_setxattr_wrapper
arch/s390/kernel/entry.S +7 -3
@@ -24,7 +24,8 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4
@@ -230,12 +231,14 @@ sysc_enter: GET_THREAD_INFO # load pointer to task_struct to R9 sla %r7,2 # *4 and test for svc 0 - bnz BASED(sysc_do_restart) # svc number > 0 + bnz BASED(sysc_nr_ok) # svc number > 0 # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) - bnl BASED(sysc_do_restart) + bnl BASED(sysc_nr_ok) lr %r7,%r1 # copy svc number to %r7 sla %r7,2 # *4 +sysc_nr_ok: + mvc SP_ARGS(4,%r15),SP_R7(%r15) sysc_do_restart: tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
@@ -510,6 +513,7 @@ lr %r7,%r1 # copy svc number to %r7 sla %r7,2 # *4 pgm_svcstd: + mvc SP_ARGS(4,%r15),SP_R7(%r15) tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. bnz BASED(pgm_tracesys)
arch/s390/kernel/entry64.S +7 -3
@@ -24,7 +24,8 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8
@@ -214,13 +215,15 @@ sysc_enter: GET_THREAD_INFO # load pointer to task_struct to R9 slag %r7,%r7,2 # *4 and test for svc 0 - jnz sysc_do_restart + jnz sysc_nr_ok # svc 0: system call number in %r1 lghi %r0,NR_syscalls clr %r1,%r0 - jnl sysc_do_restart + jnl sysc_nr_ok lgfr %r7,%r1 # clear high word in r1 slag %r7,%r7,2 # svc 0: system call number in %r1 +sysc_nr_ok: + mvc SP_ARGS(8,%r15),SP_R7(%r15) sysc_do_restart: larl %r10,sys_call_table #ifdef CONFIG_S390_SUPPORT
@@ -542,6 +545,7 @@ clr %r1,%r0 slag %r7,%r1,2 pgm_svcstd: + mvc SP_ARGS(8,%r15),SP_R7(%r15) larl %r10,sys_call_table #ifdef CONFIG_S390_SUPPORT tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ?
arch/s390/kernel/ptrace.c +5 -5
@@ -141,7 +141,7 @@/* * psw and gprs are stored on the stack */ - tmp = *(addr_t *)((addr_t )__KSTK_PTREGS (child) + addr); + tmp = *(addr_t *)((addr_t ) &__KSTK_PTREGS (child)->psw + addr);if (addr == (addr_t) &dummy->regs.psw.mask)/* Remove per bit from user psw. */ tmp &= ~PSW_MASK_PER ;
@@ -215,7 +215,7 @@high order bit but older gdb's rely on it */ data |=PSW_ADDR_AMODE ;#endif - *(addr_t *)((addr_t )__KSTK_PTREGS (child) + addr) = data; + *(addr_t *)((addr_t ) &__KSTK_PTREGS (child)->psw + addr) = data; }else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {/*
@@ -360,7 +360,7 @@PSW32_ADDR_AMODE31 ; }else {/* gpr 0-15 */ - tmp = *(__u32 *)((addr_t )__KSTK_PTREGS (child) + + tmp = *(__u32 *)((addr_t ) &__KSTK_PTREGS (child)->psw + addr*2 +4 ); } }else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
@@ -439,8 +439,8 @@ (__u64 ) tmp &PSW32_ADDR_INSN ; }else {/* gpr 0-15 */ - *(__u32 *)((addr_t )__KSTK_PTREGS (child) + addr*2 +4 ) = - tmp; + *(__u32 *)((addr_t ) &__KSTK_PTREGS (child)->psw + + addr*2 +4 ) = tmp; } }else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {/*
include/asm-s390/ptrace.h +1 -0
@@ -303,6 +303,7 @@*/ struct pt_regs { +unsigned long args[1 ];psw_t psw;unsigned long gprs[NUM_GPRS ];unsigned long orig_gpr2;