This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v2 1/3] aarch64: Re-implement setcontext without rt_sigreturn syscall


On 1 April 2014 12:32, Will Newton <will.newton@linaro.org> wrote:
> The current implementation of setcontext uses rt_sigreturn to restore
> the contents of registers. This contrasts with the way most other
> architectures implement setcontext:
>
>   powerpc64, mips, tile:
>
>   Call rt_sigreturn if context was created by a call to a signal handler,
>   otherwise restore in user code.
>
>   powerpc32:
>
>   Call swapcontext system call and don't call sigreturn or rt_sigreturn.
>
>   x86_64, sparc, hppa, sh, ia64, m68k, s390, arm:
>
>   Only support restoring "synchronous" contexts, that is contexts
>   created by getcontext, and restoring in user code and don't call
>   sigreturn or rt_sigreturn.
>
>   alpha:
>
>   Call sigreturn (but not rt_sigreturn) in all cases to do the restore.
>
> The text of the setcontext manpage suggests that the requirement to be
> able to restore a signal handler created context has been dropped from
> SUSv2:
>
>   If  the context was obtained by a call to a signal handler, then old
>   standard text says that "program execution continues with the program
>   instruction following the instruction interrupted by the signal".
>   However, this sentence was removed in SUSv2, and the present verdict
>   is "the result is unspecified".
>
> Implementing setcontext by calling rt_sigreturn unconditionally causes
> problems when used with sigaltstack as in BZ #16629. On this basis it
> seems that aarch64 is broken and that new ports should only support
> restoring contexts created with getcontext and do not need to call
> rt_sigreturn at all.
>
> This patch re-implements the aarch64 setcontext function to restore
> the context in user code in a similar manner to x86_64 and other ports.
>
> ChangeLog:
>
> 2014-04-01  Will Newton  <will.newton@linaro.org>
>
>         [BZ #16629]
>         * sysdeps/unix/sysv/linux/aarch64/setcontext.S (__setcontext):
>         Re-implement to restore registers in user code and avoid
>         rt_sigreturn system call.
> ---
>  NEWS                                         |   6 +-
>  sysdeps/unix/sysv/linux/aarch64/setcontext.S | 147 +++++++++++++++++----------
>  2 files changed, 95 insertions(+), 58 deletions(-)
>
> Changes in v2:
>  - Added NEWS entry
>  - Fixed bug in handling sigmask value
>  - Improved commit message

Ping?

> diff --git a/NEWS b/NEWS
> index 1574ab4..219198d 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -11,9 +11,9 @@ Version 2.20
>
>    6804, 15347, 15804, 15894, 16002, 16198, 16284, 16348, 16349, 16357,
>    16362, 16447, 16532, 16545, 16574, 16599, 16600, 16609, 16610, 16611,
> -  16613, 16623, 16632, 16634, 16639, 16642, 16648, 16649, 16670, 16674,
> -  16677, 16680, 16683, 16689, 16695, 16701, 16706, 16707, 16712, 16713,
> -  16714, 16731, 16743, 16758, 16759, 16760, 16770.
> +  16613, 16623, 16629, 16632, 16634, 16639, 16642, 16648, 16649, 16670,
> +  16674, 16677, 16680, 16683, 16689, 16695, 16701, 16706, 16707, 16712,
> +  16713, 16714, 16731, 16743, 16758, 16759, 16760, 16770.
>
>  * Running the testsuite no longer terminates as soon as a test fails.
>    Instead, a file tests.sum (xtests.sum from "make xcheck") is generated,
> diff --git a/sysdeps/unix/sysv/linux/aarch64/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/setcontext.S
> index d220c41..aef5149 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/setcontext.S
> +++ b/sysdeps/unix/sysv/linux/aarch64/setcontext.S
> @@ -22,68 +22,105 @@
>  #include "ucontext_i.h"
>  #include "ucontext-internal.h"
>
> -/* int setcontext (const ucontext_t *ucp) */
> +/*  int __setcontext (const ucontext_t *ucp)
>
> -       .text
> -
> -ENTRY(__setcontext)
> -
> -       /* Create a signal frame on the stack:
> -
> -               fp
> -               lr
> -               ...
> -          sp-> rt_sigframe
> -        */
> -
> -       stp     x29, x30, [sp, -16]!
> -       cfi_adjust_cfa_offset (16)
> -       cfi_rel_offset (x29, 0)
> -       cfi_rel_offset (x30, 8)
> -
> -        mov     x29, sp
> -       cfi_def_cfa_register (x29)
> -
> -       /* Allocate space for the sigcontext.  */
> -       mov     w3, #((RT_SIGFRAME_SIZE + SP_ALIGN_SIZE) & SP_ALIGN_MASK)
> -       sub     sp, sp, x3
> +  Restores the machine context in UCP and thereby resumes execution
> +  in that context.
>
> -       /* Compute the base address of the ucontext structure.  */
> -       add     x1, sp, #RT_SIGFRAME_UCONTEXT
> +  This implementation is intended to be used for *synchronous* context
> +  switches only.  Therefore, it does not have to restore anything
> +  other than the PRESERVED state.  */
>
> -       /* Only ucontext is required in the frame, *copy* it in.  */
> -
> -#if UCONTEXT_SIZE % 16
> -#error The implementation of setcontext.S assumes sizeof(ucontext_t) % 16 == 0
> -#endif
> -
> -       mov     x2, #UCONTEXT_SIZE / 16
> -0:
> -       ldp     x3, x4, [x0], #16
> -       stp     x3, x4, [x1], #16
> -       sub     x2, x2, 1
> -       cbnz    x2, 0b
> +       .text
>
> -       /* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe.  */
> -       mov     x8, SYS_ify (rt_sigreturn)
> +ENTRY (__setcontext)
> +       /* Save a copy of UCP.  */
> +       mov     x9, x0
> +
> +       /* Set the signal mask with
> +          rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8).  */
> +       mov     x0, #SIG_SETMASK
> +       add     x1, x9, #UCONTEXT_SIGMASK
> +       mov     x2, #0
> +       mov     x3, #_NSIG8
> +       mov     x8, SYS_ify (rt_sigprocmask)
>         svc     0
> -
> -       /* Ooops we failed.  Recover the stack */
> -
> -       mov     sp, x29
> -       cfi_def_cfa_register (sp)
> -
> -        ldp     x29, x30, [sp], 16
> -       cfi_adjust_cfa_offset (16)
> -       cfi_restore (x29)
> -       cfi_restore (x30)
> -       b       C_SYMBOL_NAME(__syscall_error)
> -
> +       cbz     x0, 1f
> +       b       C_SYMBOL_NAME (__syscall_error)
> +1:
> +       /* Restore the general purpose registers.  */
> +       mov     x0, x9
> +       cfi_def_cfa (x0, 0)
> +       cfi_offset (x18, oX0 + 18 * SZREG)
> +       cfi_offset (x19, oX0 + 19 * SZREG)
> +       cfi_offset (x20, oX0 + 20 * SZREG)
> +       cfi_offset (x21, oX0 + 21 * SZREG)
> +       cfi_offset (x22, oX0 + 22 * SZREG)
> +       cfi_offset (x23, oX0 + 23 * SZREG)
> +       cfi_offset (x24, oX0 + 24 * SZREG)
> +       cfi_offset (x25, oX0 + 25 * SZREG)
> +       cfi_offset (x26, oX0 + 26 * SZREG)
> +       cfi_offset (x27, oX0 + 27 * SZREG)
> +       cfi_offset (x28, oX0 + 28 * SZREG)
> +       cfi_offset (x29, oX0 + 29 * SZREG)
> +       cfi_offset (x30, oX0 + 30 * SZREG)
> +
> +       cfi_offset ( d8, oV0 + 8 * SZVREG)
> +       cfi_offset ( d9, oV0 + 9 * SZVREG)
> +       cfi_offset (d10, oV0 + 10 * SZVREG)
> +       cfi_offset (d11, oV0 + 11 * SZVREG)
> +       cfi_offset (d12, oV0 + 12 * SZVREG)
> +       cfi_offset (d13, oV0 + 13 * SZVREG)
> +       cfi_offset (d14, oV0 + 14 * SZVREG)
> +       cfi_offset (d15, oV0 + 15 * SZVREG)
> +       ldp     x18, x19, [x0, oX0 + 18 * SZREG]
> +       ldp     x20, x21, [x0, oX0 + 20 * SZREG]
> +       ldp     x22, x23, [x0, oX0 + 22 * SZREG]
> +       ldp     x24, x25, [x0, oX0 + 24 * SZREG]
> +       ldp     x26, x27, [x0, oX0 + 26 * SZREG]
> +       ldp     x28, x29, [x0, oX0 + 28 * SZREG]
> +       ldr     x30,      [x0, oX0 + 30 * SZREG]
> +       ldr     x2, [x0, oSP]
> +       mov     sp, x2
> +
> +       /* Check for FP SIMD context.  */
> +       add     x2, x0, #oEXTENSION
> +
> +       mov     w3, #(FPSIMD_MAGIC & 0xffff)
> +       movk    w3, #(FPSIMD_MAGIC >> 16), lsl #16
> +       ldr     w1, [x2, #oHEAD + oMAGIC]
> +       cmp     w1, w3
> +       b.ne    2f
> +
> +       /* Restore the FP SIMD context.  */
> +       add     x3, x2, #oV0 + 8 * SZVREG
> +       ldp      d8,  d9, [x3], #2 * SZVREG
> +       ldp     d10, d11, [x3], #2 * SZVREG
> +       ldp     d12, d13, [x3], #2 * SZVREG
> +       ldp     d14, d15, [x3], #2 * SZVREG
> +
> +       add     x3, x2, oFPSR
> +
> +       ldr     w4, [x3]
> +       msr     fpsr, x4
> +
> +       ldr     w4, [x3, oFPCR - oFPSR]
> +       msr     fpcr, x4
> +
> +2:
> +       ldr     x16, [x0, oPC]
> +       /* Restore arg registers.  */
> +       ldp     x2, x3, [x0, oX0 + 2 * SZREG]
> +       ldp     x4, x5, [x0, oX0 + 4 * SZREG]
> +       ldp     x6, x7, [x0, oX0 + 6 * SZREG]
> +       ldp     x0, x1, [x0, oX0 + 0 * SZREG]
> +       /* Jump to the new pc value.  */
> +       br      x16
>  PSEUDO_END (__setcontext)
>  weak_alias (__setcontext, setcontext)
>
> -ENTRY(__startcontext)
> +ENTRY (__startcontext)
>         mov     x0, x19
>         cbnz    x0, __setcontext
> -1:     b       HIDDEN_JUMPTARGET(_exit)
> -END(__startcontext)
> +1:     b       HIDDEN_JUMPTARGET (_exit)
> +END (__startcontext)
> --
> 1.8.1.4
>



-- 
Will Newton
Toolchain Working Group, Linaro


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]