]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
S390: Always use svc 0
authorStefan Liebler <stli@linux.ibm.com>
Thu, 25 Aug 2022 10:17:48 +0000 (12:17 +0200)
committerStefan Liebler <stli@linux.ibm.com>
Tue, 30 Aug 2022 08:54:46 +0000 (10:54 +0200)
On s390x syscalls are triggered by svc instruction. One can
pass the syscall number encoded in the instruction "svc 123"
or by storing it in r1:
lghi r1,123
svc 0

If the syscall number is encoded in the instruction, this can
cause broken syscall restarts.  Therefore this patch is now just
passing the syscall number in r1.

See also kernel-commit:
"s390/signal: switch to using vdso for sigreturn and syscall restart"
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/s390/[%e2%80%a6]call.c?h=v6.0-rc1&id=df29a7440c4b5c65765c8f60396b3b13063e24e9

As information, the "svc 0" feature was introduced in kernel 2.5.62:
commit b5aad611393ef2e132e3648fa4c6e56a9cfa8708

13 files changed:
sysdeps/unix/sysv/linux/s390/s390-32/clone.S
sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S
sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
sysdeps/unix/sysv/linux/s390/s390-32/vfork.S
sysdeps/unix/sysv/linux/s390/s390-64/clone.S
sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S
sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
sysdeps/unix/sysv/linux/s390/s390-64/vfork.S
sysdeps/unix/sysv/linux/s390/sysdep.h

index 8b7d8dd39bbe3a0ec6369a0dcaf81cca02e72bca..dc2d66338712b38583be47bc4c26dafec9d10e4f 100644 (file)
 
        .text
 ENTRY(__clone)
-       st      %r6,24(%r15)            /* store %r6 to save area */
+       stm     %r6,%r7,24(%r15)        /* Save registers.  */
+       cfi_offset (%r7, -68)
        cfi_offset (%r6, -72)
-       ltr     %r1,%r2                 /* check fn and move to %r1 */
+       ltr     %r7,%r2                 /* check fn and move to %r7 */
        jz      error                   /* no NULL function pointers */
        lhi     %r0,-8                  /* Align the child_stack to a ...  */
        nr      %r3,%r0                 /* double word boundary and ...  */
@@ -43,10 +44,11 @@ ENTRY(__clone)
        lr      %r4,%r6                 /* move parent_tid to %r4 */
        l       %r5,100(%r15)           /* load child_tid from stack */
        l       %r6,96(%r15)            /* load tls from stack */
-       svc     SYS_ify(clone)
+       lhi     %r1,SYS_ify(clone)
+       svc     0
        ltr     %r2,%r2                 /* check return code */
        jz      thread_start
-       l       %r6,24(%r15)            /* restore %r6 */
+       lm      %r6,%r7,24(%r15)        /* Load registers.  */
        jm      SYSCALL_ERROR_LABEL
        br      %r14
 error:
@@ -58,11 +60,11 @@ thread_start:
        cfi_startproc
        /* Mark r14 as undefined in order to stop unwinding here!  */
        cfi_undefined (r14)
-       /* fn is in gpr 1, arg in gpr 0 */
+       /* fn is in gpr 7, arg in gpr 0 */
        lr      %r2,%r0         /* set first parameter to void *arg */
        ahi     %r15,-96        /* make room on the stack for the save area */
        xc      0(4,%r15),0(%r15)
-       basr    %r14,%r1        /* jump to fn */
+       basr    %r14,%r7        /* jump to fn */
        DO_CALL (exit, 1)
        cfi_endproc
 
index 842ea28a4c4104d97829f8b449649a2c52c94d93..8825caa972a44465f77c1acaf379a3d9cd51ff1b 100644 (file)
   other than the PRESERVED state.  */
 
 ENTRY(__getcontext)
-       lr      %r1,%r2
+       lr      %r0,%r2
 
        /* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize).  */
+       la      %r4,SC_MASK(%r2)
        la      %r2,SIG_BLOCK
        slr     %r3,%r3
-       la      %r4,SC_MASK(%r1)
        lhi     %r5,_NSIG8
-       svc     SYS_ify(rt_sigprocmask)
+       lhi     %r1,SYS_ify(rt_sigprocmask)
+       svc     0
 
        /* Store fpu context.  */
+       lr      %r1,%r0
        stfpc   SC_FPC(%r1)
        std     %f0,SC_FPRS(%r1)
        std     %f1,SC_FPRS+8(%r1)
index 83fc2b436f58aa3e8d3df0223cf797f483d04faf..14251bc39ca8533f357efe3aff058d83c9667c65 100644 (file)
   other than the PRESERVED state.  */
 
 ENTRY(__setcontext)
-       lr      %r1,%r2
+       lr      %r0,%r2
 
        /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize).  */
+       la      %r3,SC_MASK(%r2)
        la      %r2,SIG_SETMASK
-       la      %r3,SC_MASK(%r1)
        slr     %r4,%r4
        lhi     %r5,_NSIG8
-       svc     SYS_ify(rt_sigprocmask)
+       lhi     %r1,SYS_ify(rt_sigprocmask)
+       svc     0
 
        /* Load fpu context.  */
+       lr      %r1,%r0
        lfpc    SC_FPC(%r1)
        ld      %f0,SC_FPRS(%r1)
        ld      %f1,SC_FPRS+8(%r1)
index def4e8b163cda17f1890ceb056c9265d41cfbaf9..b75bf7596bae2d38d53d8b8357df2b14411b04d8 100644 (file)
@@ -73,7 +73,8 @@ ENTRY(__swapcontext)
        la      %r3,SC_MASK(%r5)
        la      %r4,SC_MASK(%r1)
        lhi     %r5,_NSIG8
-       svc     SYS_ify(rt_sigprocmask)
+       lhi     %r1,SYS_ify(rt_sigprocmask)
+       svc     0
 
        /* Load fpu context.  */
        lr      %r5,%r0
index 967949f231098b6ef716b833f254bcb83dc932b1..e41106b377d89e62fca179ad086883c6dfdcc8f3 100644 (file)
     lr %r0,%r7;                                                                      \
     l %r7,96(%r15);                                                          \
   .endif;                                                                    \
-  .if SYS_ify (syscall) < 256;                                               \
-    svc SYS_ify (syscall);                                                   \
-  .else;                                                                     \
     lhi %r1,SYS_ify (syscall);                                               \
     svc 0;                                                                   \
-  .endif;                                                                    \
   .if args > 5;                                                                      \
     lr %r7,%r0;                                                                      \
   .endif
index bdf8cb94118fb4608496d5e20f774c09fe7b6726..76a55705176681eedb1a04c191bbd5bfd77a1bd3 100644 (file)
@@ -28,7 +28,8 @@
 
 ENTRY (__libc_vfork)
        /* Do vfork system call.  */
-       svc     SYS_ify (vfork)
+       lhi     %r1,SYS_ify (vfork)
+       svc     0
 
        /* Check for error.  */
        lhi     %r4,-4095
index 0941a38279497ddc9faef8e67de180c12b4620a2..8d33bc28ca0a85a0e8408cc7112405be78077dab 100644 (file)
 
        .text
 ENTRY(__clone)
-       stg     %r6,48(%r15)            /* store %r6 to save area */
+       stmg    %r6,%r7,48(%r15)        /* Save registers.  */
+       cfi_offset (%r7,-104)
        cfi_offset (%r6,-112)
-       ltgr    %r1,%r2                 /* check fn and move to %r1 */
+       ltgr    %r7,%r2                 /* check fn and move to %r7 */
        jz      error                   /* no NULL function pointers */
        lghi    %r0,-16                 /* Align the child_stack to a ...  */
        ngr     %r3,%r0                 /* double word boundary and ...  */
@@ -44,10 +45,11 @@ ENTRY(__clone)
        lgr     %r4,%r6                 /* move parent_tid to %r4 */
        lg      %r5,168(%r15)           /* load child_tid from stack */
        lg      %r6,160(%r15)           /* load tls from stack */
-       svc     SYS_ify(clone)
+       lghi    %r1,SYS_ify (clone)
+       svc     0
        ltgr    %r2,%r2                 /* check return code */
        jz      thread_start
-       lg      %r6,48(%r15)            /* restore %r6 */
+       lmg     %r6,%r7,48(%r15)        /* Restore registers.  */
        jgm     SYSCALL_ERROR_LABEL
        br      %r14
 error:
@@ -59,11 +61,11 @@ thread_start:
        cfi_startproc
        /* Mark r14 as undefined in order to stop unwinding here!  */
        cfi_undefined (r14)
-       /* fn is in gpr 1, arg in gpr 0 */
+       /* fn is in gpr 7, arg in gpr 0 */
        lgr     %r2,%r0         /* set first parameter to void *arg */
        aghi    %r15,-160       /* make room on the stack for the save area */
        xc      0(8,%r15),0(%r15)
-       basr    %r14,%r1        /* jump to fn */
+       basr    %r14,%r7        /* jump to fn */
        DO_CALL (exit, 1)
        cfi_endproc
 
index a0c70dc789b6d04ccd90951d15323a408a401d70..65a34fd3a2f38a9f17a36de8083a868cc4064a86 100644 (file)
   other than the PRESERVED state.  */
 
 ENTRY(__getcontext)
-       lgr     %r1,%r2
+       lgr     %r0,%r2
 
        /* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize).  */
+       la      %r4,SC_MASK(%r2)
        la      %r2,SIG_BLOCK
        slgr    %r3,%r3
-       la      %r4,SC_MASK(%r1)
        lghi    %r5,_NSIG8
-       svc     SYS_ify(rt_sigprocmask)
+       lghi    %r1,SYS_ify(rt_sigprocmask)
+       svc     0
 
        /* Store fpu context.  */
+       lgr     %r1,%r0
        stfpc   SC_FPC(%r1)
        std     %f0,SC_FPRS(%r1)
        std     %f1,SC_FPRS+8(%r1)
index b5626b686eb0282e4bfe847051b6536cfc846959..3e32370236264c40af85d8b9b26114d68bd89b84 100644 (file)
   other than the PRESERVED state.  */
 
 ENTRY(__setcontext)
-       lgr     %r1,%r2
+       lgr     %r0,%r2
 
        /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL).  */
+       la      %r3,SC_MASK(%r2)
        la      %r2,SIG_SETMASK
-       la      %r3,SC_MASK(%r1)
        slgr    %r4,%r4
        lghi    %r5,_NSIG8
-       svc     SYS_ify(rt_sigprocmask)
+       lghi    %r1,SYS_ify(rt_sigprocmask)
+       svc     0
 
        /* Load fpu context.  */
+       lgr     %r1,%r0
        lfpc    SC_FPC(%r1)
        ld      %f0,SC_FPRS(%r1)
        ld      %f1,SC_FPRS+8(%r1)
index 29ee1fb47ead58d43f7a1091b1e32d1777b18d66..7b56b6cc19c4a1859dabed4f2acf94cd13529f2b 100644 (file)
@@ -73,7 +73,8 @@ ENTRY(__swapcontext)
        la      %r3,SC_MASK(%r5)
        la      %r4,SC_MASK(%r1)
        lghi    %r5,_NSIG8
-       svc     SYS_ify(rt_sigprocmask)
+       lghi    %r1,SYS_ify(rt_sigprocmask)
+       svc     0
 
        /* Load fpu context.  */
        lgr     %r5,%r0
index 1779af0a0f6bcb1c9595ec80dc0346833e4229e9..150e33981ae6128b87931e9394fc82fdb4b1d90b 100644 (file)
     lgr %r0,%r7;                                                             \
     lg %r7,160(%r15);                                                        \
   .endif;                                                                    \
-  .if SYS_ify (syscall) < 256;                                               \
-    svc SYS_ify (syscall);                                                   \
-  .else;                                                                     \
     lghi %r1,SYS_ify (syscall);                                                      \
     svc 0;                                                                   \
-  .endif;                                                                    \
   .if args > 5;                                                                      \
     lgr %r7,%r0;                                                             \
   .endif
index ddc1044fd31d477ace308a237621561f8dc18937..52625fb92e0a4c7eb488840c8d5bd7cd7d7a8412 100644 (file)
@@ -28,7 +28,8 @@
 
 ENTRY (__libc_vfork)
        /* Do vfork system call.  */
-       svc     SYS_ify (vfork)
+       lghi    %r1,SYS_ify (vfork)
+       svc     0
 
        /* Check for error.  */
        lghi    %r4,-4095
index 2d0a26779c2c496919faa458d4ac6839039baa7a..930d7efe03f15f0b3541308ffe75489f010b3f24 100644 (file)
 #undef SYS_ify
 #define SYS_ify(syscall_name)  __NR_##syscall_name
 
-#undef INTERNAL_SYSCALL_DIRECT
-#define INTERNAL_SYSCALL_DIRECT(name, nr, args...)                           \
-  ({                                                                         \
-    DECLARGS_##nr(args)                                                              \
-    register long int _ret __asm__("2");                                     \
-    __asm__ __volatile__ (                                                   \
-                         "svc    %b1\n\t"                                    \
-                         : "=d" (_ret)                                       \
-                         : "i" (__NR_##name) ASMFMT_##nr                     \
-                         : "memory" );                                       \
-    _ret; })
-
-#undef INTERNAL_SYSCALL_SVC0
-#define INTERNAL_SYSCALL_SVC0(name, nr, args...)                             \
-  ({                                                                         \
-    DECLARGS_##nr(args)                                                              \
-    register unsigned long int _nr __asm__("1") =                            \
-      (unsigned long int)(__NR_##name);                                              \
-    register long int _ret __asm__("2");                                     \
-    __asm__ __volatile__ (                                                   \
-                         "svc    0\n\t"                                      \
-                         : "=d" (_ret)                                       \
-                         : "d" (_nr) ASMFMT_##nr                             \
-                         : "memory" );                                       \
-    _ret; })
-
 #undef INTERNAL_SYSCALL_NCS
 #define INTERNAL_SYSCALL_NCS(no, nr, args...)                                \
   ({                                                                         \
     _ret; })
 
 #undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, nr, args...)                                  \
-  (((__NR_##name) < 256)                                                     \
-   ? INTERNAL_SYSCALL_DIRECT(name, nr, args)                                 \
-   : INTERNAL_SYSCALL_SVC0(name, nr, args))
+#define INTERNAL_SYSCALL(name, nr, args...)                            \
+  INTERNAL_SYSCALL_NCS(__NR_##name, nr, args)
 
 #define DECLARGS_0()
 #define DECLARGS_1(arg1) \