1caab277bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 22c020ed8SCatalin Marinas /* 32c020ed8SCatalin Marinas * Based on arch/arm/kernel/signal.c 42c020ed8SCatalin Marinas * 52c020ed8SCatalin Marinas * Copyright (C) 1995-2009 Russell King 62c020ed8SCatalin Marinas * Copyright (C) 2012 ARM Ltd. 72c020ed8SCatalin Marinas */ 82c020ed8SCatalin Marinas 994b07c1fSDave Martin #include <linux/cache.h> 10fd92d4a5SAKASHI Takahiro #include <linux/compat.h> 112c020ed8SCatalin Marinas #include <linux/errno.h> 1220987de3SDave Martin #include <linux/kernel.h> 132c020ed8SCatalin Marinas #include <linux/signal.h> 142c020ed8SCatalin Marinas #include <linux/personality.h> 152c020ed8SCatalin Marinas #include <linux/freezer.h> 1647ccb028SDave Martin #include <linux/stddef.h> 172c020ed8SCatalin Marinas #include <linux/uaccess.h> 1833f08261SDave Martin #include <linux/sizes.h> 19bb4891a6SDave Martin #include <linux/string.h> 202c020ed8SCatalin Marinas #include <linux/tracehook.h> 212c020ed8SCatalin Marinas #include <linux/ratelimit.h> 22cf7de27aSThomas Garnier #include <linux/syscalls.h> 232c020ed8SCatalin Marinas 248d66772eSJames Morse #include <asm/daifflags.h> 252c020ed8SCatalin Marinas #include <asm/debug-monitors.h> 262c020ed8SCatalin Marinas #include <asm/elf.h> 272c020ed8SCatalin Marinas #include <asm/cacheflush.h> 282c020ed8SCatalin Marinas #include <asm/ucontext.h> 292c020ed8SCatalin Marinas #include <asm/unistd.h> 302c020ed8SCatalin Marinas #include <asm/fpsimd.h> 3117c28958SDave Martin #include <asm/ptrace.h> 32e30e8d46SMark Rutland #include <asm/syscall.h> 332c020ed8SCatalin Marinas #include <asm/signal32.h> 34f71016a8SWill Deacon #include <asm/traps.h> 352c020ed8SCatalin Marinas #include <asm/vdso.h> 362c020ed8SCatalin Marinas 372c020ed8SCatalin Marinas /* 382c020ed8SCatalin Marinas * Do a signal return; undo the signal stack. These are aligned to 128-bit. 392c020ed8SCatalin Marinas */ 402c020ed8SCatalin Marinas struct rt_sigframe { 412c020ed8SCatalin Marinas struct siginfo info; 422c020ed8SCatalin Marinas struct ucontext uc; 4320987de3SDave Martin }; 4420987de3SDave Martin 4520987de3SDave Martin struct frame_record { 46304ef4e8SWill Deacon u64 fp; 47304ef4e8SWill Deacon u64 lr; 482c020ed8SCatalin Marinas }; 492c020ed8SCatalin Marinas 5020987de3SDave Martin struct rt_sigframe_user_layout { 5120987de3SDave Martin struct rt_sigframe __user *sigframe; 5220987de3SDave Martin struct frame_record __user *next_frame; 53bb4891a6SDave Martin 54bb4891a6SDave Martin unsigned long size; /* size of allocated sigframe data */ 55bb4891a6SDave Martin unsigned long limit; /* largest allowed size */ 56bb4891a6SDave Martin 57bb4891a6SDave Martin unsigned long fpsimd_offset; 58bb4891a6SDave Martin unsigned long esr_offset; 598cd969d2SDave Martin unsigned long sve_offset; 6033f08261SDave Martin unsigned long extra_offset; 61bb4891a6SDave Martin unsigned long end_offset; 6220987de3SDave Martin }; 6320987de3SDave Martin 6433f08261SDave Martin #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) 6533f08261SDave Martin #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) 6633f08261SDave Martin #define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) 6733f08261SDave Martin 68bb4891a6SDave Martin static void init_user_layout(struct rt_sigframe_user_layout *user) 69bb4891a6SDave Martin { 7033f08261SDave Martin const size_t reserved_size = 7133f08261SDave Martin sizeof(user->sigframe->uc.uc_mcontext.__reserved); 7233f08261SDave Martin 73bb4891a6SDave Martin memset(user, 0, sizeof(*user)); 74bb4891a6SDave Martin user->size = offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved); 75bb4891a6SDave Martin 7633f08261SDave Martin user->limit = user->size + reserved_size; 7733f08261SDave Martin 7833f08261SDave Martin user->limit -= TERMINATOR_SIZE; 7933f08261SDave Martin user->limit -= EXTRA_CONTEXT_SIZE; 8033f08261SDave Martin /* Reserve space for extension and terminator ^ */ 81bb4891a6SDave Martin } 82bb4891a6SDave Martin 83bb4891a6SDave Martin static size_t sigframe_size(struct rt_sigframe_user_layout const *user) 84bb4891a6SDave Martin { 85bb4891a6SDave Martin return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); 86bb4891a6SDave Martin } 87bb4891a6SDave Martin 88bb4322f7SDave Martin /* 8933f08261SDave Martin * Sanity limit on the approximate maximum size of signal frame we'll 9033f08261SDave Martin * try to generate. Stack alignment padding and the frame record are 9133f08261SDave Martin * not taken into account. This limit is not a guarantee and is 9233f08261SDave Martin * NOT ABI. 9333f08261SDave Martin */ 9433f08261SDave Martin #define SIGFRAME_MAXSZ SZ_64K 9533f08261SDave Martin 9633f08261SDave Martin static int __sigframe_alloc(struct rt_sigframe_user_layout *user, 9733f08261SDave Martin unsigned long *offset, size_t size, bool extend) 9833f08261SDave Martin { 9933f08261SDave Martin size_t padded_size = round_up(size, 16); 10033f08261SDave Martin 10133f08261SDave Martin if (padded_size > user->limit - user->size && 10233f08261SDave Martin !user->extra_offset && 10333f08261SDave Martin extend) { 10433f08261SDave Martin int ret; 10533f08261SDave Martin 10633f08261SDave Martin user->limit += EXTRA_CONTEXT_SIZE; 10733f08261SDave Martin ret = __sigframe_alloc(user, &user->extra_offset, 10833f08261SDave Martin sizeof(struct extra_context), false); 10933f08261SDave Martin if (ret) { 11033f08261SDave Martin user->limit -= EXTRA_CONTEXT_SIZE; 11133f08261SDave Martin return ret; 11233f08261SDave Martin } 11333f08261SDave Martin 11433f08261SDave Martin /* Reserve space for the __reserved[] terminator */ 11533f08261SDave Martin user->size += TERMINATOR_SIZE; 11633f08261SDave Martin 11733f08261SDave Martin /* 11833f08261SDave Martin * Allow expansion up to SIGFRAME_MAXSZ, ensuring space for 11933f08261SDave Martin * the terminator: 12033f08261SDave Martin */ 12133f08261SDave Martin user->limit = SIGFRAME_MAXSZ - TERMINATOR_SIZE; 12233f08261SDave Martin } 12333f08261SDave Martin 12433f08261SDave Martin /* Still not enough space? Bad luck! */ 12533f08261SDave Martin if (padded_size > user->limit - user->size) 12633f08261SDave Martin return -ENOMEM; 12733f08261SDave Martin 12833f08261SDave Martin *offset = user->size; 12933f08261SDave Martin user->size += padded_size; 13033f08261SDave Martin 13133f08261SDave Martin return 0; 13233f08261SDave Martin } 13333f08261SDave Martin 13433f08261SDave Martin /* 135bb4322f7SDave Martin * Allocate space for an optional record of <size> bytes in the user 136bb4322f7SDave Martin * signal frame. The offset from the signal frame base address to the 137bb4322f7SDave Martin * allocated block is assigned to *offset. 138bb4322f7SDave Martin */ 139bb4322f7SDave Martin static int sigframe_alloc(struct rt_sigframe_user_layout *user, 140bb4322f7SDave Martin unsigned long *offset, size_t size) 141bb4322f7SDave Martin { 14233f08261SDave Martin return __sigframe_alloc(user, offset, size, true); 14333f08261SDave Martin } 144bb4322f7SDave Martin 14533f08261SDave Martin /* Allocate the null terminator record and prevent further allocations */ 14633f08261SDave Martin static int sigframe_alloc_end(struct rt_sigframe_user_layout *user) 14733f08261SDave Martin { 14833f08261SDave Martin int ret; 149bb4322f7SDave Martin 15033f08261SDave Martin /* Un-reserve the space reserved for the terminator: */ 15133f08261SDave Martin user->limit += TERMINATOR_SIZE; 15233f08261SDave Martin 15333f08261SDave Martin ret = sigframe_alloc(user, &user->end_offset, 15433f08261SDave Martin sizeof(struct _aarch64_ctx)); 15533f08261SDave Martin if (ret) 15633f08261SDave Martin return ret; 15733f08261SDave Martin 15833f08261SDave Martin /* Prevent further allocation: */ 15933f08261SDave Martin user->limit = user->size; 160bb4322f7SDave Martin return 0; 161bb4322f7SDave Martin } 162bb4322f7SDave Martin 163bb4891a6SDave Martin static void __user *apply_user_offset( 164bb4891a6SDave Martin struct rt_sigframe_user_layout const *user, unsigned long offset) 165bb4891a6SDave Martin { 166bb4891a6SDave Martin char __user *base = (char __user *)user->sigframe; 167bb4891a6SDave Martin 168bb4891a6SDave Martin return base + offset; 169bb4891a6SDave Martin } 170bb4891a6SDave Martin 1712c020ed8SCatalin Marinas static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) 1722c020ed8SCatalin Marinas { 17365896545SDave Martin struct user_fpsimd_state const *fpsimd = 17465896545SDave Martin ¤t->thread.uw.fpsimd_state; 1752c020ed8SCatalin Marinas int err; 1762c020ed8SCatalin Marinas 1772c020ed8SCatalin Marinas /* copy the FP and status/control registers */ 1782c020ed8SCatalin Marinas err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); 1792c020ed8SCatalin Marinas __put_user_error(fpsimd->fpsr, &ctx->fpsr, err); 1802c020ed8SCatalin Marinas __put_user_error(fpsimd->fpcr, &ctx->fpcr, err); 1812c020ed8SCatalin Marinas 1822c020ed8SCatalin Marinas /* copy the magic/size information */ 1832c020ed8SCatalin Marinas __put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err); 1842c020ed8SCatalin Marinas __put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err); 1852c020ed8SCatalin Marinas 1862c020ed8SCatalin Marinas return err ? -EFAULT : 0; 1872c020ed8SCatalin Marinas } 1882c020ed8SCatalin Marinas 1892c020ed8SCatalin Marinas static int restore_fpsimd_context(struct fpsimd_context __user *ctx) 1902c020ed8SCatalin Marinas { 1910abdeff5SDave Martin struct user_fpsimd_state fpsimd; 1922c020ed8SCatalin Marinas __u32 magic, size; 1932c020ed8SCatalin Marinas int err = 0; 1942c020ed8SCatalin Marinas 1952c020ed8SCatalin Marinas /* check the magic/size information */ 1962c020ed8SCatalin Marinas __get_user_error(magic, &ctx->head.magic, err); 1972c020ed8SCatalin Marinas __get_user_error(size, &ctx->head.size, err); 1982c020ed8SCatalin Marinas if (err) 1992c020ed8SCatalin Marinas return -EFAULT; 2002c020ed8SCatalin Marinas if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context)) 2012c020ed8SCatalin Marinas return -EINVAL; 2022c020ed8SCatalin Marinas 2032c020ed8SCatalin Marinas /* copy the FP and status/control registers */ 2042c020ed8SCatalin Marinas err = __copy_from_user(fpsimd.vregs, ctx->vregs, 2052c020ed8SCatalin Marinas sizeof(fpsimd.vregs)); 2062c020ed8SCatalin Marinas __get_user_error(fpsimd.fpsr, &ctx->fpsr, err); 2072c020ed8SCatalin Marinas __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); 2082c020ed8SCatalin Marinas 2098cd969d2SDave Martin clear_thread_flag(TIF_SVE); 2108cd969d2SDave Martin 2112c020ed8SCatalin Marinas /* load the hardware registers from the fpsimd_state structure */ 212c51f9269SArd Biesheuvel if (!err) 213c51f9269SArd Biesheuvel fpsimd_update_current_state(&fpsimd); 2142c020ed8SCatalin Marinas 2152c020ed8SCatalin Marinas return err ? -EFAULT : 0; 2162c020ed8SCatalin Marinas } 2172c020ed8SCatalin Marinas 2188cd969d2SDave Martin 21947ccb028SDave Martin struct user_ctxs { 22047ccb028SDave Martin struct fpsimd_context __user *fpsimd; 2218cd969d2SDave Martin struct sve_context __user *sve; 22247ccb028SDave Martin }; 22347ccb028SDave Martin 2248cd969d2SDave Martin #ifdef CONFIG_ARM64_SVE 2258cd969d2SDave Martin 2268cd969d2SDave Martin static int preserve_sve_context(struct sve_context __user *ctx) 2278cd969d2SDave Martin { 2288cd969d2SDave Martin int err = 0; 2298cd969d2SDave Martin u16 reserved[ARRAY_SIZE(ctx->__reserved)]; 2300423eedcSMark Brown unsigned int vl = task_get_sve_vl(current); 2318cd969d2SDave Martin unsigned int vq = 0; 2328cd969d2SDave Martin 2338cd969d2SDave Martin if (test_thread_flag(TIF_SVE)) 2348cd969d2SDave Martin vq = sve_vq_from_vl(vl); 2358cd969d2SDave Martin 2368cd969d2SDave Martin memset(reserved, 0, sizeof(reserved)); 2378cd969d2SDave Martin 2388cd969d2SDave Martin __put_user_error(SVE_MAGIC, &ctx->head.magic, err); 2398cd969d2SDave Martin __put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16), 2408cd969d2SDave Martin &ctx->head.size, err); 2418cd969d2SDave Martin __put_user_error(vl, &ctx->vl, err); 2428cd969d2SDave Martin BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved)); 2438cd969d2SDave Martin err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved)); 2448cd969d2SDave Martin 2458cd969d2SDave Martin if (vq) { 2468cd969d2SDave Martin /* 2478cd969d2SDave Martin * This assumes that the SVE state has already been saved to 24868a4c52eSJulien Grall * the task struct by calling the function 24968a4c52eSJulien Grall * fpsimd_signal_preserve_current_state(). 2508cd969d2SDave Martin */ 2518cd969d2SDave Martin err |= __copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET, 2528cd969d2SDave Martin current->thread.sve_state, 2538cd969d2SDave Martin SVE_SIG_REGS_SIZE(vq)); 2548cd969d2SDave Martin } 2558cd969d2SDave Martin 2568cd969d2SDave Martin return err ? -EFAULT : 0; 2578cd969d2SDave Martin } 2588cd969d2SDave Martin 2598cd969d2SDave Martin static int restore_sve_fpsimd_context(struct user_ctxs *user) 2608cd969d2SDave Martin { 2618cd969d2SDave Martin int err; 2628cd969d2SDave Martin unsigned int vq; 2630abdeff5SDave Martin struct user_fpsimd_state fpsimd; 2648cd969d2SDave Martin struct sve_context sve; 2658cd969d2SDave Martin 2668cd969d2SDave Martin if (__copy_from_user(&sve, user->sve, sizeof(sve))) 2678cd969d2SDave Martin return -EFAULT; 2688cd969d2SDave Martin 2690423eedcSMark Brown if (sve.vl != task_get_sve_vl(current)) 2708cd969d2SDave Martin return -EINVAL; 2718cd969d2SDave Martin 2728cd969d2SDave Martin if (sve.head.size <= sizeof(*user->sve)) { 2738cd969d2SDave Martin clear_thread_flag(TIF_SVE); 2748cd969d2SDave Martin goto fpsimd_only; 2758cd969d2SDave Martin } 2768cd969d2SDave Martin 2778cd969d2SDave Martin vq = sve_vq_from_vl(sve.vl); 2788cd969d2SDave Martin 2798cd969d2SDave Martin if (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq)) 2808cd969d2SDave Martin return -EINVAL; 2818cd969d2SDave Martin 2828cd969d2SDave Martin /* 2838cd969d2SDave Martin * Careful: we are about __copy_from_user() directly into 2848cd969d2SDave Martin * thread.sve_state with preemption enabled, so protection is 2858cd969d2SDave Martin * needed to prevent a racing context switch from writing stale 2868cd969d2SDave Martin * registers back over the new data. 2878cd969d2SDave Martin */ 2888cd969d2SDave Martin 2898cd969d2SDave Martin fpsimd_flush_task_state(current); 2908cd969d2SDave Martin /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ 2918cd969d2SDave Martin 2928cd969d2SDave Martin sve_alloc(current); 2937559b7d7SMark Brown if (!current->thread.sve_state) { 2947559b7d7SMark Brown clear_thread_flag(TIF_SVE); 2957559b7d7SMark Brown return -ENOMEM; 2967559b7d7SMark Brown } 2977559b7d7SMark Brown 2988cd969d2SDave Martin err = __copy_from_user(current->thread.sve_state, 2998cd969d2SDave Martin (char __user const *)user->sve + 3008cd969d2SDave Martin SVE_SIG_REGS_OFFSET, 3018cd969d2SDave Martin SVE_SIG_REGS_SIZE(vq)); 3028cd969d2SDave Martin if (err) 3038cd969d2SDave Martin return -EFAULT; 3048cd969d2SDave Martin 3058cd969d2SDave Martin set_thread_flag(TIF_SVE); 3068cd969d2SDave Martin 3078cd969d2SDave Martin fpsimd_only: 3088cd969d2SDave Martin /* copy the FP and status/control registers */ 3098cd969d2SDave Martin /* restore_sigframe() already checked that user->fpsimd != NULL. */ 3108cd969d2SDave Martin err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs, 3118cd969d2SDave Martin sizeof(fpsimd.vregs)); 3128cd969d2SDave Martin __get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err); 3138cd969d2SDave Martin __get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err); 3148cd969d2SDave Martin 3158cd969d2SDave Martin /* load the hardware registers from the fpsimd_state structure */ 3168cd969d2SDave Martin if (!err) 3178cd969d2SDave Martin fpsimd_update_current_state(&fpsimd); 3188cd969d2SDave Martin 3198cd969d2SDave Martin return err ? -EFAULT : 0; 3208cd969d2SDave Martin } 3218cd969d2SDave Martin 3228cd969d2SDave Martin #else /* ! CONFIG_ARM64_SVE */ 3238cd969d2SDave Martin 3248cd969d2SDave Martin /* Turn any non-optimised out attempts to use these into a link error: */ 3258cd969d2SDave Martin extern int preserve_sve_context(void __user *ctx); 3268cd969d2SDave Martin extern int restore_sve_fpsimd_context(struct user_ctxs *user); 3278cd969d2SDave Martin 3288cd969d2SDave Martin #endif /* ! CONFIG_ARM64_SVE */ 3298cd969d2SDave Martin 3308cd969d2SDave Martin 33147ccb028SDave Martin static int parse_user_sigframe(struct user_ctxs *user, 33247ccb028SDave Martin struct rt_sigframe __user *sf) 33347ccb028SDave Martin { 33447ccb028SDave Martin struct sigcontext __user *const sc = &sf->uc.uc_mcontext; 335bb4891a6SDave Martin struct _aarch64_ctx __user *head; 336bb4891a6SDave Martin char __user *base = (char __user *)&sc->__reserved; 33747ccb028SDave Martin size_t offset = 0; 338bb4891a6SDave Martin size_t limit = sizeof(sc->__reserved); 33933f08261SDave Martin bool have_extra_context = false; 34033f08261SDave Martin char const __user *const sfp = (char const __user *)sf; 34147ccb028SDave Martin 34247ccb028SDave Martin user->fpsimd = NULL; 3438cd969d2SDave Martin user->sve = NULL; 34447ccb028SDave Martin 345bb4891a6SDave Martin if (!IS_ALIGNED((unsigned long)base, 16)) 34647ccb028SDave Martin goto invalid; 34747ccb028SDave Martin 348bb4891a6SDave Martin while (1) { 349bb4891a6SDave Martin int err = 0; 350bb4891a6SDave Martin u32 magic, size; 35133f08261SDave Martin char const __user *userp; 35233f08261SDave Martin struct extra_context const __user *extra; 35333f08261SDave Martin u64 extra_datap; 35433f08261SDave Martin u32 extra_size; 35533f08261SDave Martin struct _aarch64_ctx const __user *end; 35633f08261SDave Martin u32 end_magic, end_size; 357bb4891a6SDave Martin 358bb4891a6SDave Martin if (limit - offset < sizeof(*head)) 359bb4891a6SDave Martin goto invalid; 360bb4891a6SDave Martin 361bb4891a6SDave Martin if (!IS_ALIGNED(offset, 16)) 362bb4891a6SDave Martin goto invalid; 363bb4891a6SDave Martin 364bb4891a6SDave Martin head = (struct _aarch64_ctx __user *)(base + offset); 36547ccb028SDave Martin __get_user_error(magic, &head->magic, err); 36647ccb028SDave Martin __get_user_error(size, &head->size, err); 36747ccb028SDave Martin if (err) 36847ccb028SDave Martin return err; 36947ccb028SDave Martin 370bb4891a6SDave Martin if (limit - offset < size) 371bb4891a6SDave Martin goto invalid; 372bb4891a6SDave Martin 37347ccb028SDave Martin switch (magic) { 37447ccb028SDave Martin case 0: 37547ccb028SDave Martin if (size) 37647ccb028SDave Martin goto invalid; 37747ccb028SDave Martin 37847ccb028SDave Martin goto done; 37947ccb028SDave Martin 38047ccb028SDave Martin case FPSIMD_MAGIC: 3816d502b6bSSuzuki K Poulose if (!system_supports_fpsimd()) 3826d502b6bSSuzuki K Poulose goto invalid; 38347ccb028SDave Martin if (user->fpsimd) 38447ccb028SDave Martin goto invalid; 38547ccb028SDave Martin 386bb4891a6SDave Martin if (size < sizeof(*user->fpsimd)) 38747ccb028SDave Martin goto invalid; 38847ccb028SDave Martin 38947ccb028SDave Martin user->fpsimd = (struct fpsimd_context __user *)head; 39047ccb028SDave Martin break; 39147ccb028SDave Martin 39247ccb028SDave Martin case ESR_MAGIC: 39347ccb028SDave Martin /* ignore */ 39447ccb028SDave Martin break; 39547ccb028SDave Martin 3968cd969d2SDave Martin case SVE_MAGIC: 3978cd969d2SDave Martin if (!system_supports_sve()) 3988cd969d2SDave Martin goto invalid; 3998cd969d2SDave Martin 4008cd969d2SDave Martin if (user->sve) 4018cd969d2SDave Martin goto invalid; 4028cd969d2SDave Martin 4038cd969d2SDave Martin if (size < sizeof(*user->sve)) 4048cd969d2SDave Martin goto invalid; 4058cd969d2SDave Martin 4068cd969d2SDave Martin user->sve = (struct sve_context __user *)head; 4078cd969d2SDave Martin break; 4088cd969d2SDave Martin 40933f08261SDave Martin case EXTRA_MAGIC: 41033f08261SDave Martin if (have_extra_context) 41133f08261SDave Martin goto invalid; 41233f08261SDave Martin 41333f08261SDave Martin if (size < sizeof(*extra)) 41433f08261SDave Martin goto invalid; 41533f08261SDave Martin 41633f08261SDave Martin userp = (char const __user *)head; 41733f08261SDave Martin 41833f08261SDave Martin extra = (struct extra_context const __user *)userp; 41933f08261SDave Martin userp += size; 42033f08261SDave Martin 42133f08261SDave Martin __get_user_error(extra_datap, &extra->datap, err); 42233f08261SDave Martin __get_user_error(extra_size, &extra->size, err); 42333f08261SDave Martin if (err) 42433f08261SDave Martin return err; 42533f08261SDave Martin 42633f08261SDave Martin /* Check for the dummy terminator in __reserved[]: */ 42733f08261SDave Martin 42833f08261SDave Martin if (limit - offset - size < TERMINATOR_SIZE) 42933f08261SDave Martin goto invalid; 43033f08261SDave Martin 43133f08261SDave Martin end = (struct _aarch64_ctx const __user *)userp; 43233f08261SDave Martin userp += TERMINATOR_SIZE; 43333f08261SDave Martin 43433f08261SDave Martin __get_user_error(end_magic, &end->magic, err); 43533f08261SDave Martin __get_user_error(end_size, &end->size, err); 43633f08261SDave Martin if (err) 43733f08261SDave Martin return err; 43833f08261SDave Martin 43933f08261SDave Martin if (end_magic || end_size) 44033f08261SDave Martin goto invalid; 44133f08261SDave Martin 44233f08261SDave Martin /* Prevent looping/repeated parsing of extra_context */ 44333f08261SDave Martin have_extra_context = true; 44433f08261SDave Martin 44533f08261SDave Martin base = (__force void __user *)extra_datap; 44633f08261SDave Martin if (!IS_ALIGNED((unsigned long)base, 16)) 44733f08261SDave Martin goto invalid; 44833f08261SDave Martin 44933f08261SDave Martin if (!IS_ALIGNED(extra_size, 16)) 45033f08261SDave Martin goto invalid; 45133f08261SDave Martin 45233f08261SDave Martin if (base != userp) 45333f08261SDave Martin goto invalid; 45433f08261SDave Martin 45533f08261SDave Martin /* Reject "unreasonably large" frames: */ 45633f08261SDave Martin if (extra_size > sfp + SIGFRAME_MAXSZ - userp) 45733f08261SDave Martin goto invalid; 45833f08261SDave Martin 45933f08261SDave Martin /* 46033f08261SDave Martin * Ignore trailing terminator in __reserved[] 46133f08261SDave Martin * and start parsing extra data: 46233f08261SDave Martin */ 46333f08261SDave Martin offset = 0; 46433f08261SDave Martin limit = extra_size; 465abf73988SDave Martin 46696d4f267SLinus Torvalds if (!access_ok(base, limit)) 467abf73988SDave Martin goto invalid; 468abf73988SDave Martin 46933f08261SDave Martin continue; 47033f08261SDave Martin 47147ccb028SDave Martin default: 47247ccb028SDave Martin goto invalid; 47347ccb028SDave Martin } 47447ccb028SDave Martin 47547ccb028SDave Martin if (size < sizeof(*head)) 47647ccb028SDave Martin goto invalid; 47747ccb028SDave Martin 478bb4891a6SDave Martin if (limit - offset < size) 47947ccb028SDave Martin goto invalid; 48047ccb028SDave Martin 48147ccb028SDave Martin offset += size; 48247ccb028SDave Martin } 48347ccb028SDave Martin 48447ccb028SDave Martin done: 48547ccb028SDave Martin return 0; 48647ccb028SDave Martin 48747ccb028SDave Martin invalid: 48847ccb028SDave Martin return -EINVAL; 48947ccb028SDave Martin } 49047ccb028SDave Martin 4912c020ed8SCatalin Marinas static int restore_sigframe(struct pt_regs *regs, 4922c020ed8SCatalin Marinas struct rt_sigframe __user *sf) 4932c020ed8SCatalin Marinas { 4942c020ed8SCatalin Marinas sigset_t set; 4952c020ed8SCatalin Marinas int i, err; 49647ccb028SDave Martin struct user_ctxs user; 4972c020ed8SCatalin Marinas 4982c020ed8SCatalin Marinas err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); 4992c020ed8SCatalin Marinas if (err == 0) 5002c020ed8SCatalin Marinas set_current_blocked(&set); 5012c020ed8SCatalin Marinas 5022c020ed8SCatalin Marinas for (i = 0; i < 31; i++) 5032c020ed8SCatalin Marinas __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], 5042c020ed8SCatalin Marinas err); 5052c020ed8SCatalin Marinas __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); 5062c020ed8SCatalin Marinas __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); 5072c020ed8SCatalin Marinas __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); 5082c020ed8SCatalin Marinas 5092c020ed8SCatalin Marinas /* 5102c020ed8SCatalin Marinas * Avoid sys_rt_sigreturn() restarting. 5112c020ed8SCatalin Marinas */ 51217c28958SDave Martin forget_syscall(regs); 5132c020ed8SCatalin Marinas 514dbd4d7caSMark Rutland err |= !valid_user_regs(®s->user_regs, current); 51547ccb028SDave Martin if (err == 0) 51647ccb028SDave Martin err = parse_user_sigframe(&user, sf); 5172c020ed8SCatalin Marinas 5186d502b6bSSuzuki K Poulose if (err == 0 && system_supports_fpsimd()) { 5198cd969d2SDave Martin if (!user.fpsimd) 5208cd969d2SDave Martin return -EINVAL; 5218cd969d2SDave Martin 5228cd969d2SDave Martin if (user.sve) { 5238cd969d2SDave Martin if (!system_supports_sve()) 5248cd969d2SDave Martin return -EINVAL; 5258cd969d2SDave Martin 5268cd969d2SDave Martin err = restore_sve_fpsimd_context(&user); 5278cd969d2SDave Martin } else { 52847ccb028SDave Martin err = restore_fpsimd_context(user.fpsimd); 5298cd969d2SDave Martin } 5308cd969d2SDave Martin } 5312c020ed8SCatalin Marinas 5322c020ed8SCatalin Marinas return err; 5332c020ed8SCatalin Marinas } 5342c020ed8SCatalin Marinas 535bf4ce5ccSMark Rutland SYSCALL_DEFINE0(rt_sigreturn) 5362c020ed8SCatalin Marinas { 5373085e164SMark Rutland struct pt_regs *regs = current_pt_regs(); 5382c020ed8SCatalin Marinas struct rt_sigframe __user *frame; 5392c020ed8SCatalin Marinas 5402c020ed8SCatalin Marinas /* Always make any pending restarted system calls return -EINTR */ 541f56141e3SAndy Lutomirski current->restart_block.fn = do_no_restart_syscall; 5422c020ed8SCatalin Marinas 5432c020ed8SCatalin Marinas /* 5442c020ed8SCatalin Marinas * Since we stacked the signal on a 128-bit boundary, then 'sp' should 5452c020ed8SCatalin Marinas * be word aligned here. 5462c020ed8SCatalin Marinas */ 5472c020ed8SCatalin Marinas if (regs->sp & 15) 5482c020ed8SCatalin Marinas goto badframe; 5492c020ed8SCatalin Marinas 5502c020ed8SCatalin Marinas frame = (struct rt_sigframe __user *)regs->sp; 5512c020ed8SCatalin Marinas 55296d4f267SLinus Torvalds if (!access_ok(frame, sizeof (*frame))) 5532c020ed8SCatalin Marinas goto badframe; 5542c020ed8SCatalin Marinas 5552c020ed8SCatalin Marinas if (restore_sigframe(regs, frame)) 5562c020ed8SCatalin Marinas goto badframe; 5572c020ed8SCatalin Marinas 558207bdae4SAl Viro if (restore_altstack(&frame->uc.uc_stack)) 5592c020ed8SCatalin Marinas goto badframe; 5602c020ed8SCatalin Marinas 5612c020ed8SCatalin Marinas return regs->regs[0]; 5622c020ed8SCatalin Marinas 5632c020ed8SCatalin Marinas badframe: 564f71016a8SWill Deacon arm64_notify_segfault(regs->sp); 5652c020ed8SCatalin Marinas return 0; 5662c020ed8SCatalin Marinas } 5672c020ed8SCatalin Marinas 56894b07c1fSDave Martin /* 56994b07c1fSDave Martin * Determine the layout of optional records in the signal frame 57094b07c1fSDave Martin * 57194b07c1fSDave Martin * add_all: if true, lays out the biggest possible signal frame for 57294b07c1fSDave Martin * this task; otherwise, generates a layout for the current state 57394b07c1fSDave Martin * of the task. 57494b07c1fSDave Martin */ 57594b07c1fSDave Martin static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, 57694b07c1fSDave Martin bool add_all) 577bb4891a6SDave Martin { 578bb4322f7SDave Martin int err; 579bb4322f7SDave Martin 580bb4322f7SDave Martin err = sigframe_alloc(user, &user->fpsimd_offset, 581bb4322f7SDave Martin sizeof(struct fpsimd_context)); 582bb4322f7SDave Martin if (err) 583bb4322f7SDave Martin return err; 584bb4891a6SDave Martin 585bb4891a6SDave Martin /* fault information, if valid */ 58694b07c1fSDave Martin if (add_all || current->thread.fault_code) { 587bb4322f7SDave Martin err = sigframe_alloc(user, &user->esr_offset, 588bb4322f7SDave Martin sizeof(struct esr_context)); 589bb4322f7SDave Martin if (err) 590bb4322f7SDave Martin return err; 591bb4891a6SDave Martin } 592bb4891a6SDave Martin 5938cd969d2SDave Martin if (system_supports_sve()) { 5948cd969d2SDave Martin unsigned int vq = 0; 5958cd969d2SDave Martin 59694b07c1fSDave Martin if (add_all || test_thread_flag(TIF_SVE)) { 597*b5bc00ffSMark Brown int vl = sve_max_vl(); 59894b07c1fSDave Martin 59994b07c1fSDave Martin if (!add_all) 6000423eedcSMark Brown vl = task_get_sve_vl(current); 60194b07c1fSDave Martin 60294b07c1fSDave Martin vq = sve_vq_from_vl(vl); 60394b07c1fSDave Martin } 6048cd969d2SDave Martin 6058cd969d2SDave Martin err = sigframe_alloc(user, &user->sve_offset, 6068cd969d2SDave Martin SVE_SIG_CONTEXT_SIZE(vq)); 6078cd969d2SDave Martin if (err) 6088cd969d2SDave Martin return err; 6098cd969d2SDave Martin } 6108cd969d2SDave Martin 61133f08261SDave Martin return sigframe_alloc_end(user); 612bb4891a6SDave Martin } 613bb4891a6SDave Martin 61420987de3SDave Martin static int setup_sigframe(struct rt_sigframe_user_layout *user, 6152c020ed8SCatalin Marinas struct pt_regs *regs, sigset_t *set) 6162c020ed8SCatalin Marinas { 6172c020ed8SCatalin Marinas int i, err = 0; 61820987de3SDave Martin struct rt_sigframe __user *sf = user->sigframe; 6192c020ed8SCatalin Marinas 620304ef4e8SWill Deacon /* set up the stack frame for unwinding */ 62120987de3SDave Martin __put_user_error(regs->regs[29], &user->next_frame->fp, err); 62220987de3SDave Martin __put_user_error(regs->regs[30], &user->next_frame->lr, err); 623304ef4e8SWill Deacon 6242c020ed8SCatalin Marinas for (i = 0; i < 31; i++) 6252c020ed8SCatalin Marinas __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], 6262c020ed8SCatalin Marinas err); 6272c020ed8SCatalin Marinas __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); 6282c020ed8SCatalin Marinas __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); 6292c020ed8SCatalin Marinas __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); 6302c020ed8SCatalin Marinas 6312c020ed8SCatalin Marinas __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); 6322c020ed8SCatalin Marinas 6332c020ed8SCatalin Marinas err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); 6342c020ed8SCatalin Marinas 6356d502b6bSSuzuki K Poulose if (err == 0 && system_supports_fpsimd()) { 636bb4891a6SDave Martin struct fpsimd_context __user *fpsimd_ctx = 637bb4891a6SDave Martin apply_user_offset(user, user->fpsimd_offset); 6380e0276d1SCatalin Marinas err |= preserve_fpsimd_context(fpsimd_ctx); 6390e0276d1SCatalin Marinas } 6402c020ed8SCatalin Marinas 64115af1942SCatalin Marinas /* fault information, if valid */ 642bb4891a6SDave Martin if (err == 0 && user->esr_offset) { 643bb4891a6SDave Martin struct esr_context __user *esr_ctx = 644bb4891a6SDave Martin apply_user_offset(user, user->esr_offset); 645bb4891a6SDave Martin 64615af1942SCatalin Marinas __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); 64715af1942SCatalin Marinas __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); 64815af1942SCatalin Marinas __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); 64915af1942SCatalin Marinas } 65015af1942SCatalin Marinas 6518cd969d2SDave Martin /* Scalable Vector Extension state, if present */ 6528cd969d2SDave Martin if (system_supports_sve() && err == 0 && user->sve_offset) { 6538cd969d2SDave Martin struct sve_context __user *sve_ctx = 6548cd969d2SDave Martin apply_user_offset(user, user->sve_offset); 6558cd969d2SDave Martin err |= preserve_sve_context(sve_ctx); 6568cd969d2SDave Martin } 6578cd969d2SDave Martin 65833f08261SDave Martin if (err == 0 && user->extra_offset) { 65933f08261SDave Martin char __user *sfp = (char __user *)user->sigframe; 66033f08261SDave Martin char __user *userp = 66133f08261SDave Martin apply_user_offset(user, user->extra_offset); 66233f08261SDave Martin 66333f08261SDave Martin struct extra_context __user *extra; 66433f08261SDave Martin struct _aarch64_ctx __user *end; 66533f08261SDave Martin u64 extra_datap; 66633f08261SDave Martin u32 extra_size; 66733f08261SDave Martin 66833f08261SDave Martin extra = (struct extra_context __user *)userp; 66933f08261SDave Martin userp += EXTRA_CONTEXT_SIZE; 67033f08261SDave Martin 67133f08261SDave Martin end = (struct _aarch64_ctx __user *)userp; 67233f08261SDave Martin userp += TERMINATOR_SIZE; 67333f08261SDave Martin 67433f08261SDave Martin /* 67533f08261SDave Martin * extra_datap is just written to the signal frame. 67633f08261SDave Martin * The value gets cast back to a void __user * 67733f08261SDave Martin * during sigreturn. 67833f08261SDave Martin */ 67933f08261SDave Martin extra_datap = (__force u64)userp; 68033f08261SDave Martin extra_size = sfp + round_up(user->size, 16) - userp; 68133f08261SDave Martin 68233f08261SDave Martin __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); 68333f08261SDave Martin __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); 68433f08261SDave Martin __put_user_error(extra_datap, &extra->datap, err); 68533f08261SDave Martin __put_user_error(extra_size, &extra->size, err); 68633f08261SDave Martin 68733f08261SDave Martin /* Add the terminator */ 68833f08261SDave Martin __put_user_error(0, &end->magic, err); 68933f08261SDave Martin __put_user_error(0, &end->size, err); 69033f08261SDave Martin } 69133f08261SDave Martin 6922c020ed8SCatalin Marinas /* set the "end" magic */ 693bb4891a6SDave Martin if (err == 0) { 694bb4891a6SDave Martin struct _aarch64_ctx __user *end = 695bb4891a6SDave Martin apply_user_offset(user, user->end_offset); 696bb4891a6SDave Martin 6970e0276d1SCatalin Marinas __put_user_error(0, &end->magic, err); 6980e0276d1SCatalin Marinas __put_user_error(0, &end->size, err); 699bb4891a6SDave Martin } 7002c020ed8SCatalin Marinas 7012c020ed8SCatalin Marinas return err; 7022c020ed8SCatalin Marinas } 7032c020ed8SCatalin Marinas 70420987de3SDave Martin static int get_sigframe(struct rt_sigframe_user_layout *user, 70520987de3SDave Martin struct ksignal *ksig, struct pt_regs *regs) 7062c020ed8SCatalin Marinas { 7072c020ed8SCatalin Marinas unsigned long sp, sp_top; 708bb4891a6SDave Martin int err; 709bb4891a6SDave Martin 710bb4891a6SDave Martin init_user_layout(user); 71194b07c1fSDave Martin err = setup_sigframe_layout(user, false); 712bb4891a6SDave Martin if (err) 713bb4891a6SDave Martin return err; 7142c020ed8SCatalin Marinas 71538a7be3cSRichard Weinberger sp = sp_top = sigsp(regs->sp, ksig); 7162c020ed8SCatalin Marinas 71720987de3SDave Martin sp = round_down(sp - sizeof(struct frame_record), 16); 71820987de3SDave Martin user->next_frame = (struct frame_record __user *)sp; 71920987de3SDave Martin 720bb4891a6SDave Martin sp = round_down(sp, 16) - sigframe_size(user); 72120987de3SDave Martin user->sigframe = (struct rt_sigframe __user *)sp; 7222c020ed8SCatalin Marinas 7232c020ed8SCatalin Marinas /* 7242c020ed8SCatalin Marinas * Check that we can actually write to the signal frame. 7252c020ed8SCatalin Marinas */ 72696d4f267SLinus Torvalds if (!access_ok(user->sigframe, sp_top - sp)) 72720987de3SDave Martin return -EFAULT; 7282c020ed8SCatalin Marinas 72920987de3SDave Martin return 0; 7302c020ed8SCatalin Marinas } 7312c020ed8SCatalin Marinas 732304ef4e8SWill Deacon static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, 73320987de3SDave Martin struct rt_sigframe_user_layout *user, int usig) 7342c020ed8SCatalin Marinas { 7352c020ed8SCatalin Marinas __sigrestore_t sigtramp; 7362c020ed8SCatalin Marinas 7372c020ed8SCatalin Marinas regs->regs[0] = usig; 73820987de3SDave Martin regs->sp = (unsigned long)user->sigframe; 73920987de3SDave Martin regs->regs[29] = (unsigned long)&user->next_frame->fp; 7402c020ed8SCatalin Marinas regs->pc = (unsigned long)ka->sa.sa_handler; 7412c020ed8SCatalin Marinas 7428ef8f360SDave Martin /* 7438ef8f360SDave Martin * Signal delivery is a (wacky) indirect function call in 7448ef8f360SDave Martin * userspace, so simulate the same setting of BTYPE as a BLR 7458ef8f360SDave Martin * <register containing the signal handler entry point>. 7468ef8f360SDave Martin * Signal delivery to a location in a PROT_BTI guarded page 7478ef8f360SDave Martin * that is not a function entry point will now trigger a 7488ef8f360SDave Martin * SIGILL in userspace. 7498ef8f360SDave Martin * 7508ef8f360SDave Martin * If the signal handler entry point is not in a PROT_BTI 7518ef8f360SDave Martin * guarded page, this is harmless. 7528ef8f360SDave Martin */ 7538ef8f360SDave Martin if (system_supports_bti()) { 7548ef8f360SDave Martin regs->pstate &= ~PSR_BTYPE_MASK; 7558ef8f360SDave Martin regs->pstate |= PSR_BTYPE_C; 7568ef8f360SDave Martin } 7578ef8f360SDave Martin 758637ec831SVincenzo Frascino /* TCO (Tag Check Override) always cleared for signal handlers */ 759637ec831SVincenzo Frascino regs->pstate &= ~PSR_TCO_BIT; 760637ec831SVincenzo Frascino 7612c020ed8SCatalin Marinas if (ka->sa.sa_flags & SA_RESTORER) 7622c020ed8SCatalin Marinas sigtramp = ka->sa.sa_restorer; 7632c020ed8SCatalin Marinas else 7642c020ed8SCatalin Marinas sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); 7652c020ed8SCatalin Marinas 7662c020ed8SCatalin Marinas regs->regs[30] = (unsigned long)sigtramp; 7672c020ed8SCatalin Marinas } 7682c020ed8SCatalin Marinas 76900554fa4SRichard Weinberger static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, 77000554fa4SRichard Weinberger struct pt_regs *regs) 7712c020ed8SCatalin Marinas { 77220987de3SDave Martin struct rt_sigframe_user_layout user; 7732c020ed8SCatalin Marinas struct rt_sigframe __user *frame; 7742c020ed8SCatalin Marinas int err = 0; 7752c020ed8SCatalin Marinas 7768cd969d2SDave Martin fpsimd_signal_preserve_current_state(); 7778cd969d2SDave Martin 77820987de3SDave Martin if (get_sigframe(&user, ksig, regs)) 7792c020ed8SCatalin Marinas return 1; 7802c020ed8SCatalin Marinas 78120987de3SDave Martin frame = user.sigframe; 78220987de3SDave Martin 7832c020ed8SCatalin Marinas __put_user_error(0, &frame->uc.uc_flags, err); 7842c020ed8SCatalin Marinas __put_user_error(NULL, &frame->uc.uc_link, err); 7852c020ed8SCatalin Marinas 786207bdae4SAl Viro err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 78720987de3SDave Martin err |= setup_sigframe(&user, regs, set); 788304ef4e8SWill Deacon if (err == 0) { 78920987de3SDave Martin setup_return(regs, &ksig->ka, &user, usig); 79000554fa4SRichard Weinberger if (ksig->ka.sa.sa_flags & SA_SIGINFO) { 79100554fa4SRichard Weinberger err |= copy_siginfo_to_user(&frame->info, &ksig->info); 7922c020ed8SCatalin Marinas regs->regs[1] = (unsigned long)&frame->info; 7932c020ed8SCatalin Marinas regs->regs[2] = (unsigned long)&frame->uc; 7942c020ed8SCatalin Marinas } 795304ef4e8SWill Deacon } 7962c020ed8SCatalin Marinas 7972c020ed8SCatalin Marinas return err; 7982c020ed8SCatalin Marinas } 7992c020ed8SCatalin Marinas 8002c020ed8SCatalin Marinas static void setup_restart_syscall(struct pt_regs *regs) 8012c020ed8SCatalin Marinas { 8022c020ed8SCatalin Marinas if (is_compat_task()) 8032c020ed8SCatalin Marinas compat_setup_restart_syscall(regs); 8042c020ed8SCatalin Marinas else 8052c020ed8SCatalin Marinas regs->regs[8] = __NR_restart_syscall; 8062c020ed8SCatalin Marinas } 8072c020ed8SCatalin Marinas 8082c020ed8SCatalin Marinas /* 8092c020ed8SCatalin Marinas * OK, we're invoking a handler 8102c020ed8SCatalin Marinas */ 81100554fa4SRichard Weinberger static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 8122c020ed8SCatalin Marinas { 8132c020ed8SCatalin Marinas sigset_t *oldset = sigmask_to_save(); 81400554fa4SRichard Weinberger int usig = ksig->sig; 8152c020ed8SCatalin Marinas int ret; 8162c020ed8SCatalin Marinas 817409d5db4SWill Deacon rseq_signal_deliver(ksig, regs); 818409d5db4SWill Deacon 8192c020ed8SCatalin Marinas /* 8202c020ed8SCatalin Marinas * Set up the stack frame 8212c020ed8SCatalin Marinas */ 8222c020ed8SCatalin Marinas if (is_compat_task()) { 82300554fa4SRichard Weinberger if (ksig->ka.sa.sa_flags & SA_SIGINFO) 82400554fa4SRichard Weinberger ret = compat_setup_rt_frame(usig, ksig, oldset, regs); 8252c020ed8SCatalin Marinas else 82600554fa4SRichard Weinberger ret = compat_setup_frame(usig, ksig, oldset, regs); 8272c020ed8SCatalin Marinas } else { 82800554fa4SRichard Weinberger ret = setup_rt_frame(usig, ksig, oldset, regs); 8292c020ed8SCatalin Marinas } 8302c020ed8SCatalin Marinas 8312c020ed8SCatalin Marinas /* 8322c020ed8SCatalin Marinas * Check that the resulting registers are actually sane. 8332c020ed8SCatalin Marinas */ 834dbd4d7caSMark Rutland ret |= !valid_user_regs(®s->user_regs, current); 8352c020ed8SCatalin Marinas 836ac2081cdSWill Deacon /* Step into the signal handler if we are stepping */ 837ac2081cdSWill Deacon signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); 8382c020ed8SCatalin Marinas } 8392c020ed8SCatalin Marinas 8402c020ed8SCatalin Marinas /* 8412c020ed8SCatalin Marinas * Note that 'init' is a special process: it doesn't get signals it doesn't 8422c020ed8SCatalin Marinas * want to handle. Thus you cannot kill init even with a SIGKILL even by 8432c020ed8SCatalin Marinas * mistake. 8442c020ed8SCatalin Marinas * 8452c020ed8SCatalin Marinas * Note that we go through the signals twice: once to check the signals that 8462c020ed8SCatalin Marinas * the kernel can handle, and then we build all the user-level signal handling 8472c020ed8SCatalin Marinas * stack-frames in one go after that. 8482c020ed8SCatalin Marinas */ 8492c020ed8SCatalin Marinas static void do_signal(struct pt_regs *regs) 8502c020ed8SCatalin Marinas { 8512c020ed8SCatalin Marinas unsigned long continue_addr = 0, restart_addr = 0; 85200554fa4SRichard Weinberger int retval = 0; 85300554fa4SRichard Weinberger struct ksignal ksig; 8540fe42512SDave Martin bool syscall = in_syscall(regs); 8552c020ed8SCatalin Marinas 8562c020ed8SCatalin Marinas /* 8572c020ed8SCatalin Marinas * If we were from a system call, check for system call restarting... 8582c020ed8SCatalin Marinas */ 8590fe42512SDave Martin if (syscall) { 8602c020ed8SCatalin Marinas continue_addr = regs->pc; 8612c020ed8SCatalin Marinas restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); 8622c020ed8SCatalin Marinas retval = regs->regs[0]; 8632c020ed8SCatalin Marinas 8642c020ed8SCatalin Marinas /* 8652c020ed8SCatalin Marinas * Avoid additional syscall restarting via ret_to_user. 8662c020ed8SCatalin Marinas */ 86717c28958SDave Martin forget_syscall(regs); 8682c020ed8SCatalin Marinas 8692c020ed8SCatalin Marinas /* 8702c020ed8SCatalin Marinas * Prepare for system call restart. We do this here so that a 8712c020ed8SCatalin Marinas * debugger will see the already changed PC. 8722c020ed8SCatalin Marinas */ 8732c020ed8SCatalin Marinas switch (retval) { 8742c020ed8SCatalin Marinas case -ERESTARTNOHAND: 8752c020ed8SCatalin Marinas case -ERESTARTSYS: 8762c020ed8SCatalin Marinas case -ERESTARTNOINTR: 8772c020ed8SCatalin Marinas case -ERESTART_RESTARTBLOCK: 8782c020ed8SCatalin Marinas regs->regs[0] = regs->orig_x0; 8792c020ed8SCatalin Marinas regs->pc = restart_addr; 8802c020ed8SCatalin Marinas break; 8812c020ed8SCatalin Marinas } 8822c020ed8SCatalin Marinas } 8832c020ed8SCatalin Marinas 8842c020ed8SCatalin Marinas /* 8852c020ed8SCatalin Marinas * Get the signal to deliver. When running under ptrace, at this point 8862c020ed8SCatalin Marinas * the debugger may change all of our registers. 8872c020ed8SCatalin Marinas */ 88800554fa4SRichard Weinberger if (get_signal(&ksig)) { 8892c020ed8SCatalin Marinas /* 8902c020ed8SCatalin Marinas * Depending on the signal settings, we may need to revert the 8912c020ed8SCatalin Marinas * decision to restart the system call, but skip this if a 8922c020ed8SCatalin Marinas * debugger has chosen to restart at a different PC. 8932c020ed8SCatalin Marinas */ 8942c020ed8SCatalin Marinas if (regs->pc == restart_addr && 8952c020ed8SCatalin Marinas (retval == -ERESTARTNOHAND || 8962c020ed8SCatalin Marinas retval == -ERESTART_RESTARTBLOCK || 8972c020ed8SCatalin Marinas (retval == -ERESTARTSYS && 89800554fa4SRichard Weinberger !(ksig.ka.sa.sa_flags & SA_RESTART)))) { 899e30e8d46SMark Rutland syscall_set_return_value(current, regs, -EINTR, 0); 9002c020ed8SCatalin Marinas regs->pc = continue_addr; 9012c020ed8SCatalin Marinas } 9022c020ed8SCatalin Marinas 90300554fa4SRichard Weinberger handle_signal(&ksig, regs); 9042c020ed8SCatalin Marinas return; 9052c020ed8SCatalin Marinas } 9062c020ed8SCatalin Marinas 9072c020ed8SCatalin Marinas /* 9082c020ed8SCatalin Marinas * Handle restarting a different system call. As above, if a debugger 9092c020ed8SCatalin Marinas * has chosen to restart at a different PC, ignore the restart. 9102c020ed8SCatalin Marinas */ 9110fe42512SDave Martin if (syscall && regs->pc == restart_addr) { 9122c020ed8SCatalin Marinas if (retval == -ERESTART_RESTARTBLOCK) 9132c020ed8SCatalin Marinas setup_restart_syscall(regs); 9142c020ed8SCatalin Marinas user_rewind_single_step(current); 9152c020ed8SCatalin Marinas } 9162c020ed8SCatalin Marinas 9172c020ed8SCatalin Marinas restore_saved_sigmask(); 9182c020ed8SCatalin Marinas } 9192c020ed8SCatalin Marinas 9204d1c2ee2SMark Rutland void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) 9212c020ed8SCatalin Marinas { 922a2048e34SThomas Garnier do { 923421dd6faSChris Metcalf if (thread_flags & _TIF_NEED_RESCHED) { 9248d66772eSJames Morse /* Unmask Debug and SError for the next task */ 9258d66772eSJames Morse local_daif_restore(DAIF_PROCCTX_NOIRQ); 9268d66772eSJames Morse 927421dd6faSChris Metcalf schedule(); 928421dd6faSChris Metcalf } else { 9298d66772eSJames Morse local_daif_restore(DAIF_PROCCTX); 930421dd6faSChris Metcalf 9319842ceaeSPratyush Anand if (thread_flags & _TIF_UPROBE) 9329842ceaeSPratyush Anand uprobe_notify_resume(regs); 9339842ceaeSPratyush Anand 934637ec831SVincenzo Frascino if (thread_flags & _TIF_MTE_ASYNC_FAULT) { 935637ec831SVincenzo Frascino clear_thread_flag(TIF_MTE_ASYNC_FAULT); 936637ec831SVincenzo Frascino send_sig_fault(SIGSEGV, SEGV_MTEAERR, 937637ec831SVincenzo Frascino (void __user *)NULL, current); 938637ec831SVincenzo Frascino } 939637ec831SVincenzo Frascino 940192caabdSJens Axboe if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 9412c020ed8SCatalin Marinas do_signal(regs); 9422c020ed8SCatalin Marinas 943a68de80fSSean Christopherson if (thread_flags & _TIF_NOTIFY_RESUME) 9442c020ed8SCatalin Marinas tracehook_notify_resume(regs); 945005f78cdSArd Biesheuvel 946005f78cdSArd Biesheuvel if (thread_flags & _TIF_FOREIGN_FPSTATE) 947005f78cdSArd Biesheuvel fpsimd_restore_current_state(); 948421dd6faSChris Metcalf } 949005f78cdSArd Biesheuvel 9508d66772eSJames Morse local_daif_mask(); 951421dd6faSChris Metcalf thread_flags = READ_ONCE(current_thread_info()->flags); 952421dd6faSChris Metcalf } while (thread_flags & _TIF_WORK_MASK); 9532c020ed8SCatalin Marinas } 95494b07c1fSDave Martin 95594b07c1fSDave Martin unsigned long __ro_after_init signal_minsigstksz; 95694b07c1fSDave Martin 95794b07c1fSDave Martin /* 95894b07c1fSDave Martin * Determine the stack space required for guaranteed signal devliery. 95994b07c1fSDave Martin * This function is used to populate AT_MINSIGSTKSZ at process startup. 96094b07c1fSDave Martin * cpufeatures setup is assumed to be complete. 96194b07c1fSDave Martin */ 96294b07c1fSDave Martin void __init minsigstksz_setup(void) 96394b07c1fSDave Martin { 96494b07c1fSDave Martin struct rt_sigframe_user_layout user; 96594b07c1fSDave Martin 96694b07c1fSDave Martin init_user_layout(&user); 96794b07c1fSDave Martin 96894b07c1fSDave Martin /* 96994b07c1fSDave Martin * If this fails, SIGFRAME_MAXSZ needs to be enlarged. It won't 97094b07c1fSDave Martin * be big enough, but it's our best guess: 97194b07c1fSDave Martin */ 97294b07c1fSDave Martin if (WARN_ON(setup_sigframe_layout(&user, true))) 97394b07c1fSDave Martin return; 97494b07c1fSDave Martin 97594b07c1fSDave Martin signal_minsigstksz = sigframe_size(&user) + 97694b07c1fSDave Martin round_up(sizeof(struct frame_record), 16) + 97794b07c1fSDave Martin 16; /* max alignment padding */ 97894b07c1fSDave Martin } 979726e337bSMarco Elver 980726e337bSMarco Elver /* 981726e337bSMarco Elver * Compile-time assertions for siginfo_t offsets. Check NSIG* as well, as 982726e337bSMarco Elver * changes likely come with new fields that should be added below. 983726e337bSMarco Elver */ 984726e337bSMarco Elver static_assert(NSIGILL == 11); 985726e337bSMarco Elver static_assert(NSIGFPE == 15); 986726e337bSMarco Elver static_assert(NSIGSEGV == 9); 987726e337bSMarco Elver static_assert(NSIGBUS == 5); 988726e337bSMarco Elver static_assert(NSIGTRAP == 6); 989726e337bSMarco Elver static_assert(NSIGCHLD == 6); 990726e337bSMarco Elver static_assert(NSIGSYS == 2); 99150ae8130SEric W. Biederman static_assert(sizeof(siginfo_t) == 128); 99250ae8130SEric W. Biederman static_assert(__alignof__(siginfo_t) == 8); 993726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_signo) == 0x00); 994726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_errno) == 0x04); 995726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_code) == 0x08); 996726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_pid) == 0x10); 997726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_uid) == 0x14); 998726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_tid) == 0x10); 999726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_overrun) == 0x14); 1000726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_status) == 0x18); 1001726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_utime) == 0x20); 1002726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_stime) == 0x28); 1003726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_value) == 0x18); 1004726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_int) == 0x18); 1005726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_ptr) == 0x18); 1006726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_addr) == 0x10); 1007726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18); 1008726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_lower) == 0x20); 1009726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_upper) == 0x28); 1010726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_pkey) == 0x20); 1011726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_perf_data) == 0x18); 1012726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_perf_type) == 0x20); 1013726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_band) == 0x10); 1014726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_fd) == 0x18); 1015726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_call_addr) == 0x10); 1016726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_syscall) == 0x18); 1017726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_arch) == 0x1c); 1018