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> 322c020ed8SCatalin Marinas #include <asm/signal32.h> 33f71016a8SWill Deacon #include <asm/traps.h> 342c020ed8SCatalin Marinas #include <asm/vdso.h> 352c020ed8SCatalin Marinas 362c020ed8SCatalin Marinas /* 372c020ed8SCatalin Marinas * Do a signal return; undo the signal stack. These are aligned to 128-bit. 382c020ed8SCatalin Marinas */ 392c020ed8SCatalin Marinas struct rt_sigframe { 402c020ed8SCatalin Marinas struct siginfo info; 412c020ed8SCatalin Marinas struct ucontext uc; 4220987de3SDave Martin }; 4320987de3SDave Martin 4420987de3SDave Martin struct frame_record { 45304ef4e8SWill Deacon u64 fp; 46304ef4e8SWill Deacon u64 lr; 472c020ed8SCatalin Marinas }; 482c020ed8SCatalin Marinas 4920987de3SDave Martin struct rt_sigframe_user_layout { 5020987de3SDave Martin struct rt_sigframe __user *sigframe; 5120987de3SDave Martin struct frame_record __user *next_frame; 52bb4891a6SDave Martin 53bb4891a6SDave Martin unsigned long size; /* size of allocated sigframe data */ 54bb4891a6SDave Martin unsigned long limit; /* largest allowed size */ 55bb4891a6SDave Martin 56bb4891a6SDave Martin unsigned long fpsimd_offset; 57bb4891a6SDave Martin unsigned long esr_offset; 588cd969d2SDave Martin unsigned long sve_offset; 5933f08261SDave Martin unsigned long extra_offset; 60bb4891a6SDave Martin unsigned long end_offset; 6120987de3SDave Martin }; 6220987de3SDave Martin 6333f08261SDave Martin #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) 6433f08261SDave Martin #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) 6533f08261SDave Martin #define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) 6633f08261SDave Martin 67bb4891a6SDave Martin static void init_user_layout(struct rt_sigframe_user_layout *user) 68bb4891a6SDave Martin { 6933f08261SDave Martin const size_t reserved_size = 7033f08261SDave Martin sizeof(user->sigframe->uc.uc_mcontext.__reserved); 7133f08261SDave Martin 72bb4891a6SDave Martin memset(user, 0, sizeof(*user)); 73bb4891a6SDave Martin user->size = offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved); 74bb4891a6SDave Martin 7533f08261SDave Martin user->limit = user->size + reserved_size; 7633f08261SDave Martin 7733f08261SDave Martin user->limit -= TERMINATOR_SIZE; 7833f08261SDave Martin user->limit -= EXTRA_CONTEXT_SIZE; 7933f08261SDave Martin /* Reserve space for extension and terminator ^ */ 80bb4891a6SDave Martin } 81bb4891a6SDave Martin 82bb4891a6SDave Martin static size_t sigframe_size(struct rt_sigframe_user_layout const *user) 83bb4891a6SDave Martin { 84bb4891a6SDave Martin return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); 85bb4891a6SDave Martin } 86bb4891a6SDave Martin 87bb4322f7SDave Martin /* 8833f08261SDave Martin * Sanity limit on the approximate maximum size of signal frame we'll 8933f08261SDave Martin * try to generate. Stack alignment padding and the frame record are 9033f08261SDave Martin * not taken into account. This limit is not a guarantee and is 9133f08261SDave Martin * NOT ABI. 9233f08261SDave Martin */ 9333f08261SDave Martin #define SIGFRAME_MAXSZ SZ_64K 9433f08261SDave Martin 9533f08261SDave Martin static int __sigframe_alloc(struct rt_sigframe_user_layout *user, 9633f08261SDave Martin unsigned long *offset, size_t size, bool extend) 9733f08261SDave Martin { 9833f08261SDave Martin size_t padded_size = round_up(size, 16); 9933f08261SDave Martin 10033f08261SDave Martin if (padded_size > user->limit - user->size && 10133f08261SDave Martin !user->extra_offset && 10233f08261SDave Martin extend) { 10333f08261SDave Martin int ret; 10433f08261SDave Martin 10533f08261SDave Martin user->limit += EXTRA_CONTEXT_SIZE; 10633f08261SDave Martin ret = __sigframe_alloc(user, &user->extra_offset, 10733f08261SDave Martin sizeof(struct extra_context), false); 10833f08261SDave Martin if (ret) { 10933f08261SDave Martin user->limit -= EXTRA_CONTEXT_SIZE; 11033f08261SDave Martin return ret; 11133f08261SDave Martin } 11233f08261SDave Martin 11333f08261SDave Martin /* Reserve space for the __reserved[] terminator */ 11433f08261SDave Martin user->size += TERMINATOR_SIZE; 11533f08261SDave Martin 11633f08261SDave Martin /* 11733f08261SDave Martin * Allow expansion up to SIGFRAME_MAXSZ, ensuring space for 11833f08261SDave Martin * the terminator: 11933f08261SDave Martin */ 12033f08261SDave Martin user->limit = SIGFRAME_MAXSZ - TERMINATOR_SIZE; 12133f08261SDave Martin } 12233f08261SDave Martin 12333f08261SDave Martin /* Still not enough space? Bad luck! */ 12433f08261SDave Martin if (padded_size > user->limit - user->size) 12533f08261SDave Martin return -ENOMEM; 12633f08261SDave Martin 12733f08261SDave Martin *offset = user->size; 12833f08261SDave Martin user->size += padded_size; 12933f08261SDave Martin 13033f08261SDave Martin return 0; 13133f08261SDave Martin } 13233f08261SDave Martin 13333f08261SDave Martin /* 134bb4322f7SDave Martin * Allocate space for an optional record of <size> bytes in the user 135bb4322f7SDave Martin * signal frame. The offset from the signal frame base address to the 136bb4322f7SDave Martin * allocated block is assigned to *offset. 137bb4322f7SDave Martin */ 138bb4322f7SDave Martin static int sigframe_alloc(struct rt_sigframe_user_layout *user, 139bb4322f7SDave Martin unsigned long *offset, size_t size) 140bb4322f7SDave Martin { 14133f08261SDave Martin return __sigframe_alloc(user, offset, size, true); 14233f08261SDave Martin } 143bb4322f7SDave Martin 14433f08261SDave Martin /* Allocate the null terminator record and prevent further allocations */ 14533f08261SDave Martin static int sigframe_alloc_end(struct rt_sigframe_user_layout *user) 14633f08261SDave Martin { 14733f08261SDave Martin int ret; 148bb4322f7SDave Martin 14933f08261SDave Martin /* Un-reserve the space reserved for the terminator: */ 15033f08261SDave Martin user->limit += TERMINATOR_SIZE; 15133f08261SDave Martin 15233f08261SDave Martin ret = sigframe_alloc(user, &user->end_offset, 15333f08261SDave Martin sizeof(struct _aarch64_ctx)); 15433f08261SDave Martin if (ret) 15533f08261SDave Martin return ret; 15633f08261SDave Martin 15733f08261SDave Martin /* Prevent further allocation: */ 15833f08261SDave Martin user->limit = user->size; 159bb4322f7SDave Martin return 0; 160bb4322f7SDave Martin } 161bb4322f7SDave Martin 162bb4891a6SDave Martin static void __user *apply_user_offset( 163bb4891a6SDave Martin struct rt_sigframe_user_layout const *user, unsigned long offset) 164bb4891a6SDave Martin { 165bb4891a6SDave Martin char __user *base = (char __user *)user->sigframe; 166bb4891a6SDave Martin 167bb4891a6SDave Martin return base + offset; 168bb4891a6SDave Martin } 169bb4891a6SDave Martin 1702c020ed8SCatalin Marinas static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) 1712c020ed8SCatalin Marinas { 17265896545SDave Martin struct user_fpsimd_state const *fpsimd = 17365896545SDave Martin ¤t->thread.uw.fpsimd_state; 1742c020ed8SCatalin Marinas int err; 1752c020ed8SCatalin Marinas 1762c020ed8SCatalin Marinas /* copy the FP and status/control registers */ 1772c020ed8SCatalin Marinas err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs)); 1782c020ed8SCatalin Marinas __put_user_error(fpsimd->fpsr, &ctx->fpsr, err); 1792c020ed8SCatalin Marinas __put_user_error(fpsimd->fpcr, &ctx->fpcr, err); 1802c020ed8SCatalin Marinas 1812c020ed8SCatalin Marinas /* copy the magic/size information */ 1822c020ed8SCatalin Marinas __put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err); 1832c020ed8SCatalin Marinas __put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err); 1842c020ed8SCatalin Marinas 1852c020ed8SCatalin Marinas return err ? -EFAULT : 0; 1862c020ed8SCatalin Marinas } 1872c020ed8SCatalin Marinas 1882c020ed8SCatalin Marinas static int restore_fpsimd_context(struct fpsimd_context __user *ctx) 1892c020ed8SCatalin Marinas { 1900abdeff5SDave Martin struct user_fpsimd_state fpsimd; 1912c020ed8SCatalin Marinas __u32 magic, size; 1922c020ed8SCatalin Marinas int err = 0; 1932c020ed8SCatalin Marinas 1942c020ed8SCatalin Marinas /* check the magic/size information */ 1952c020ed8SCatalin Marinas __get_user_error(magic, &ctx->head.magic, err); 1962c020ed8SCatalin Marinas __get_user_error(size, &ctx->head.size, err); 1972c020ed8SCatalin Marinas if (err) 1982c020ed8SCatalin Marinas return -EFAULT; 1992c020ed8SCatalin Marinas if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context)) 2002c020ed8SCatalin Marinas return -EINVAL; 2012c020ed8SCatalin Marinas 2022c020ed8SCatalin Marinas /* copy the FP and status/control registers */ 2032c020ed8SCatalin Marinas err = __copy_from_user(fpsimd.vregs, ctx->vregs, 2042c020ed8SCatalin Marinas sizeof(fpsimd.vregs)); 2052c020ed8SCatalin Marinas __get_user_error(fpsimd.fpsr, &ctx->fpsr, err); 2062c020ed8SCatalin Marinas __get_user_error(fpsimd.fpcr, &ctx->fpcr, err); 2072c020ed8SCatalin Marinas 2088cd969d2SDave Martin clear_thread_flag(TIF_SVE); 2098cd969d2SDave Martin 2102c020ed8SCatalin Marinas /* load the hardware registers from the fpsimd_state structure */ 211c51f9269SArd Biesheuvel if (!err) 212c51f9269SArd Biesheuvel fpsimd_update_current_state(&fpsimd); 2132c020ed8SCatalin Marinas 2142c020ed8SCatalin Marinas return err ? -EFAULT : 0; 2152c020ed8SCatalin Marinas } 2162c020ed8SCatalin Marinas 2178cd969d2SDave Martin 21847ccb028SDave Martin struct user_ctxs { 21947ccb028SDave Martin struct fpsimd_context __user *fpsimd; 2208cd969d2SDave Martin struct sve_context __user *sve; 22147ccb028SDave Martin }; 22247ccb028SDave Martin 2238cd969d2SDave Martin #ifdef CONFIG_ARM64_SVE 2248cd969d2SDave Martin 2258cd969d2SDave Martin static int preserve_sve_context(struct sve_context __user *ctx) 2268cd969d2SDave Martin { 2278cd969d2SDave Martin int err = 0; 2288cd969d2SDave Martin u16 reserved[ARRAY_SIZE(ctx->__reserved)]; 2298cd969d2SDave Martin unsigned int vl = current->thread.sve_vl; 2308cd969d2SDave Martin unsigned int vq = 0; 2318cd969d2SDave Martin 2328cd969d2SDave Martin if (test_thread_flag(TIF_SVE)) 2338cd969d2SDave Martin vq = sve_vq_from_vl(vl); 2348cd969d2SDave Martin 2358cd969d2SDave Martin memset(reserved, 0, sizeof(reserved)); 2368cd969d2SDave Martin 2378cd969d2SDave Martin __put_user_error(SVE_MAGIC, &ctx->head.magic, err); 2388cd969d2SDave Martin __put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16), 2398cd969d2SDave Martin &ctx->head.size, err); 2408cd969d2SDave Martin __put_user_error(vl, &ctx->vl, err); 2418cd969d2SDave Martin BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved)); 2428cd969d2SDave Martin err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved)); 2438cd969d2SDave Martin 2448cd969d2SDave Martin if (vq) { 2458cd969d2SDave Martin /* 2468cd969d2SDave Martin * This assumes that the SVE state has already been saved to 2478cd969d2SDave Martin * the task struct by calling preserve_fpsimd_context(). 2488cd969d2SDave Martin */ 2498cd969d2SDave Martin err |= __copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET, 2508cd969d2SDave Martin current->thread.sve_state, 2518cd969d2SDave Martin SVE_SIG_REGS_SIZE(vq)); 2528cd969d2SDave Martin } 2538cd969d2SDave Martin 2548cd969d2SDave Martin return err ? -EFAULT : 0; 2558cd969d2SDave Martin } 2568cd969d2SDave Martin 2578cd969d2SDave Martin static int restore_sve_fpsimd_context(struct user_ctxs *user) 2588cd969d2SDave Martin { 2598cd969d2SDave Martin int err; 2608cd969d2SDave Martin unsigned int vq; 2610abdeff5SDave Martin struct user_fpsimd_state fpsimd; 2628cd969d2SDave Martin struct sve_context sve; 2638cd969d2SDave Martin 2648cd969d2SDave Martin if (__copy_from_user(&sve, user->sve, sizeof(sve))) 2658cd969d2SDave Martin return -EFAULT; 2668cd969d2SDave Martin 2678cd969d2SDave Martin if (sve.vl != current->thread.sve_vl) 2688cd969d2SDave Martin return -EINVAL; 2698cd969d2SDave Martin 2708cd969d2SDave Martin if (sve.head.size <= sizeof(*user->sve)) { 2718cd969d2SDave Martin clear_thread_flag(TIF_SVE); 2728cd969d2SDave Martin goto fpsimd_only; 2738cd969d2SDave Martin } 2748cd969d2SDave Martin 2758cd969d2SDave Martin vq = sve_vq_from_vl(sve.vl); 2768cd969d2SDave Martin 2778cd969d2SDave Martin if (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq)) 2788cd969d2SDave Martin return -EINVAL; 2798cd969d2SDave Martin 2808cd969d2SDave Martin /* 2818cd969d2SDave Martin * Careful: we are about __copy_from_user() directly into 2828cd969d2SDave Martin * thread.sve_state with preemption enabled, so protection is 2838cd969d2SDave Martin * needed to prevent a racing context switch from writing stale 2848cd969d2SDave Martin * registers back over the new data. 2858cd969d2SDave Martin */ 2868cd969d2SDave Martin 2878cd969d2SDave Martin fpsimd_flush_task_state(current); 2888cd969d2SDave Martin /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ 2898cd969d2SDave Martin 2908cd969d2SDave Martin sve_alloc(current); 2918cd969d2SDave Martin err = __copy_from_user(current->thread.sve_state, 2928cd969d2SDave Martin (char __user const *)user->sve + 2938cd969d2SDave Martin SVE_SIG_REGS_OFFSET, 2948cd969d2SDave Martin SVE_SIG_REGS_SIZE(vq)); 2958cd969d2SDave Martin if (err) 2968cd969d2SDave Martin return -EFAULT; 2978cd969d2SDave Martin 2988cd969d2SDave Martin set_thread_flag(TIF_SVE); 2998cd969d2SDave Martin 3008cd969d2SDave Martin fpsimd_only: 3018cd969d2SDave Martin /* copy the FP and status/control registers */ 3028cd969d2SDave Martin /* restore_sigframe() already checked that user->fpsimd != NULL. */ 3038cd969d2SDave Martin err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs, 3048cd969d2SDave Martin sizeof(fpsimd.vregs)); 3058cd969d2SDave Martin __get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err); 3068cd969d2SDave Martin __get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err); 3078cd969d2SDave Martin 3088cd969d2SDave Martin /* load the hardware registers from the fpsimd_state structure */ 3098cd969d2SDave Martin if (!err) 3108cd969d2SDave Martin fpsimd_update_current_state(&fpsimd); 3118cd969d2SDave Martin 3128cd969d2SDave Martin return err ? -EFAULT : 0; 3138cd969d2SDave Martin } 3148cd969d2SDave Martin 3158cd969d2SDave Martin #else /* ! CONFIG_ARM64_SVE */ 3168cd969d2SDave Martin 3178cd969d2SDave Martin /* Turn any non-optimised out attempts to use these into a link error: */ 3188cd969d2SDave Martin extern int preserve_sve_context(void __user *ctx); 3198cd969d2SDave Martin extern int restore_sve_fpsimd_context(struct user_ctxs *user); 3208cd969d2SDave Martin 3218cd969d2SDave Martin #endif /* ! CONFIG_ARM64_SVE */ 3228cd969d2SDave Martin 3238cd969d2SDave Martin 32447ccb028SDave Martin static int parse_user_sigframe(struct user_ctxs *user, 32547ccb028SDave Martin struct rt_sigframe __user *sf) 32647ccb028SDave Martin { 32747ccb028SDave Martin struct sigcontext __user *const sc = &sf->uc.uc_mcontext; 328bb4891a6SDave Martin struct _aarch64_ctx __user *head; 329bb4891a6SDave Martin char __user *base = (char __user *)&sc->__reserved; 33047ccb028SDave Martin size_t offset = 0; 331bb4891a6SDave Martin size_t limit = sizeof(sc->__reserved); 33233f08261SDave Martin bool have_extra_context = false; 33333f08261SDave Martin char const __user *const sfp = (char const __user *)sf; 33447ccb028SDave Martin 33547ccb028SDave Martin user->fpsimd = NULL; 3368cd969d2SDave Martin user->sve = NULL; 33747ccb028SDave Martin 338bb4891a6SDave Martin if (!IS_ALIGNED((unsigned long)base, 16)) 33947ccb028SDave Martin goto invalid; 34047ccb028SDave Martin 341bb4891a6SDave Martin while (1) { 342bb4891a6SDave Martin int err = 0; 343bb4891a6SDave Martin u32 magic, size; 34433f08261SDave Martin char const __user *userp; 34533f08261SDave Martin struct extra_context const __user *extra; 34633f08261SDave Martin u64 extra_datap; 34733f08261SDave Martin u32 extra_size; 34833f08261SDave Martin struct _aarch64_ctx const __user *end; 34933f08261SDave Martin u32 end_magic, end_size; 350bb4891a6SDave Martin 351bb4891a6SDave Martin if (limit - offset < sizeof(*head)) 352bb4891a6SDave Martin goto invalid; 353bb4891a6SDave Martin 354bb4891a6SDave Martin if (!IS_ALIGNED(offset, 16)) 355bb4891a6SDave Martin goto invalid; 356bb4891a6SDave Martin 357bb4891a6SDave Martin head = (struct _aarch64_ctx __user *)(base + offset); 35847ccb028SDave Martin __get_user_error(magic, &head->magic, err); 35947ccb028SDave Martin __get_user_error(size, &head->size, err); 36047ccb028SDave Martin if (err) 36147ccb028SDave Martin return err; 36247ccb028SDave Martin 363bb4891a6SDave Martin if (limit - offset < size) 364bb4891a6SDave Martin goto invalid; 365bb4891a6SDave Martin 36647ccb028SDave Martin switch (magic) { 36747ccb028SDave Martin case 0: 36847ccb028SDave Martin if (size) 36947ccb028SDave Martin goto invalid; 37047ccb028SDave Martin 37147ccb028SDave Martin goto done; 37247ccb028SDave Martin 37347ccb028SDave Martin case FPSIMD_MAGIC: 3746d502b6bSSuzuki K Poulose if (!system_supports_fpsimd()) 3756d502b6bSSuzuki K Poulose goto invalid; 37647ccb028SDave Martin if (user->fpsimd) 37747ccb028SDave Martin goto invalid; 37847ccb028SDave Martin 379bb4891a6SDave Martin if (size < sizeof(*user->fpsimd)) 38047ccb028SDave Martin goto invalid; 38147ccb028SDave Martin 38247ccb028SDave Martin user->fpsimd = (struct fpsimd_context __user *)head; 38347ccb028SDave Martin break; 38447ccb028SDave Martin 38547ccb028SDave Martin case ESR_MAGIC: 38647ccb028SDave Martin /* ignore */ 38747ccb028SDave Martin break; 38847ccb028SDave Martin 3898cd969d2SDave Martin case SVE_MAGIC: 3908cd969d2SDave Martin if (!system_supports_sve()) 3918cd969d2SDave Martin goto invalid; 3928cd969d2SDave Martin 3938cd969d2SDave Martin if (user->sve) 3948cd969d2SDave Martin goto invalid; 3958cd969d2SDave Martin 3968cd969d2SDave Martin if (size < sizeof(*user->sve)) 3978cd969d2SDave Martin goto invalid; 3988cd969d2SDave Martin 3998cd969d2SDave Martin user->sve = (struct sve_context __user *)head; 4008cd969d2SDave Martin break; 4018cd969d2SDave Martin 40233f08261SDave Martin case EXTRA_MAGIC: 40333f08261SDave Martin if (have_extra_context) 40433f08261SDave Martin goto invalid; 40533f08261SDave Martin 40633f08261SDave Martin if (size < sizeof(*extra)) 40733f08261SDave Martin goto invalid; 40833f08261SDave Martin 40933f08261SDave Martin userp = (char const __user *)head; 41033f08261SDave Martin 41133f08261SDave Martin extra = (struct extra_context const __user *)userp; 41233f08261SDave Martin userp += size; 41333f08261SDave Martin 41433f08261SDave Martin __get_user_error(extra_datap, &extra->datap, err); 41533f08261SDave Martin __get_user_error(extra_size, &extra->size, err); 41633f08261SDave Martin if (err) 41733f08261SDave Martin return err; 41833f08261SDave Martin 41933f08261SDave Martin /* Check for the dummy terminator in __reserved[]: */ 42033f08261SDave Martin 42133f08261SDave Martin if (limit - offset - size < TERMINATOR_SIZE) 42233f08261SDave Martin goto invalid; 42333f08261SDave Martin 42433f08261SDave Martin end = (struct _aarch64_ctx const __user *)userp; 42533f08261SDave Martin userp += TERMINATOR_SIZE; 42633f08261SDave Martin 42733f08261SDave Martin __get_user_error(end_magic, &end->magic, err); 42833f08261SDave Martin __get_user_error(end_size, &end->size, err); 42933f08261SDave Martin if (err) 43033f08261SDave Martin return err; 43133f08261SDave Martin 43233f08261SDave Martin if (end_magic || end_size) 43333f08261SDave Martin goto invalid; 43433f08261SDave Martin 43533f08261SDave Martin /* Prevent looping/repeated parsing of extra_context */ 43633f08261SDave Martin have_extra_context = true; 43733f08261SDave Martin 43833f08261SDave Martin base = (__force void __user *)extra_datap; 43933f08261SDave Martin if (!IS_ALIGNED((unsigned long)base, 16)) 44033f08261SDave Martin goto invalid; 44133f08261SDave Martin 44233f08261SDave Martin if (!IS_ALIGNED(extra_size, 16)) 44333f08261SDave Martin goto invalid; 44433f08261SDave Martin 44533f08261SDave Martin if (base != userp) 44633f08261SDave Martin goto invalid; 44733f08261SDave Martin 44833f08261SDave Martin /* Reject "unreasonably large" frames: */ 44933f08261SDave Martin if (extra_size > sfp + SIGFRAME_MAXSZ - userp) 45033f08261SDave Martin goto invalid; 45133f08261SDave Martin 45233f08261SDave Martin /* 45333f08261SDave Martin * Ignore trailing terminator in __reserved[] 45433f08261SDave Martin * and start parsing extra data: 45533f08261SDave Martin */ 45633f08261SDave Martin offset = 0; 45733f08261SDave Martin limit = extra_size; 458abf73988SDave Martin 45996d4f267SLinus Torvalds if (!access_ok(base, limit)) 460abf73988SDave Martin goto invalid; 461abf73988SDave Martin 46233f08261SDave Martin continue; 46333f08261SDave Martin 46447ccb028SDave Martin default: 46547ccb028SDave Martin goto invalid; 46647ccb028SDave Martin } 46747ccb028SDave Martin 46847ccb028SDave Martin if (size < sizeof(*head)) 46947ccb028SDave Martin goto invalid; 47047ccb028SDave Martin 471bb4891a6SDave Martin if (limit - offset < size) 47247ccb028SDave Martin goto invalid; 47347ccb028SDave Martin 47447ccb028SDave Martin offset += size; 47547ccb028SDave Martin } 47647ccb028SDave Martin 47747ccb028SDave Martin done: 47847ccb028SDave Martin return 0; 47947ccb028SDave Martin 48047ccb028SDave Martin invalid: 48147ccb028SDave Martin return -EINVAL; 48247ccb028SDave Martin } 48347ccb028SDave Martin 4842c020ed8SCatalin Marinas static int restore_sigframe(struct pt_regs *regs, 4852c020ed8SCatalin Marinas struct rt_sigframe __user *sf) 4862c020ed8SCatalin Marinas { 4872c020ed8SCatalin Marinas sigset_t set; 4882c020ed8SCatalin Marinas int i, err; 48947ccb028SDave Martin struct user_ctxs user; 4902c020ed8SCatalin Marinas 4912c020ed8SCatalin Marinas err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); 4922c020ed8SCatalin Marinas if (err == 0) 4932c020ed8SCatalin Marinas set_current_blocked(&set); 4942c020ed8SCatalin Marinas 4952c020ed8SCatalin Marinas for (i = 0; i < 31; i++) 4962c020ed8SCatalin Marinas __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], 4972c020ed8SCatalin Marinas err); 4982c020ed8SCatalin Marinas __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); 4992c020ed8SCatalin Marinas __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); 5002c020ed8SCatalin Marinas __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); 5012c020ed8SCatalin Marinas 5022c020ed8SCatalin Marinas /* 5032c020ed8SCatalin Marinas * Avoid sys_rt_sigreturn() restarting. 5042c020ed8SCatalin Marinas */ 50517c28958SDave Martin forget_syscall(regs); 5062c020ed8SCatalin Marinas 507dbd4d7caSMark Rutland err |= !valid_user_regs(®s->user_regs, current); 50847ccb028SDave Martin if (err == 0) 50947ccb028SDave Martin err = parse_user_sigframe(&user, sf); 5102c020ed8SCatalin Marinas 5116d502b6bSSuzuki K Poulose if (err == 0 && system_supports_fpsimd()) { 5128cd969d2SDave Martin if (!user.fpsimd) 5138cd969d2SDave Martin return -EINVAL; 5148cd969d2SDave Martin 5158cd969d2SDave Martin if (user.sve) { 5168cd969d2SDave Martin if (!system_supports_sve()) 5178cd969d2SDave Martin return -EINVAL; 5188cd969d2SDave Martin 5198cd969d2SDave Martin err = restore_sve_fpsimd_context(&user); 5208cd969d2SDave Martin } else { 52147ccb028SDave Martin err = restore_fpsimd_context(user.fpsimd); 5228cd969d2SDave Martin } 5238cd969d2SDave Martin } 5242c020ed8SCatalin Marinas 5252c020ed8SCatalin Marinas return err; 5262c020ed8SCatalin Marinas } 5272c020ed8SCatalin Marinas 528bf4ce5ccSMark Rutland SYSCALL_DEFINE0(rt_sigreturn) 5292c020ed8SCatalin Marinas { 5303085e164SMark Rutland struct pt_regs *regs = current_pt_regs(); 5312c020ed8SCatalin Marinas struct rt_sigframe __user *frame; 5322c020ed8SCatalin Marinas 5332c020ed8SCatalin Marinas /* Always make any pending restarted system calls return -EINTR */ 534f56141e3SAndy Lutomirski current->restart_block.fn = do_no_restart_syscall; 5352c020ed8SCatalin Marinas 5362c020ed8SCatalin Marinas /* 5372c020ed8SCatalin Marinas * Since we stacked the signal on a 128-bit boundary, then 'sp' should 5382c020ed8SCatalin Marinas * be word aligned here. 5392c020ed8SCatalin Marinas */ 5402c020ed8SCatalin Marinas if (regs->sp & 15) 5412c020ed8SCatalin Marinas goto badframe; 5422c020ed8SCatalin Marinas 5432c020ed8SCatalin Marinas frame = (struct rt_sigframe __user *)regs->sp; 5442c020ed8SCatalin Marinas 54596d4f267SLinus Torvalds if (!access_ok(frame, sizeof (*frame))) 5462c020ed8SCatalin Marinas goto badframe; 5472c020ed8SCatalin Marinas 5482c020ed8SCatalin Marinas if (restore_sigframe(regs, frame)) 5492c020ed8SCatalin Marinas goto badframe; 5502c020ed8SCatalin Marinas 551207bdae4SAl Viro if (restore_altstack(&frame->uc.uc_stack)) 5522c020ed8SCatalin Marinas goto badframe; 5532c020ed8SCatalin Marinas 5542c020ed8SCatalin Marinas return regs->regs[0]; 5552c020ed8SCatalin Marinas 5562c020ed8SCatalin Marinas badframe: 557f71016a8SWill Deacon arm64_notify_segfault(regs->sp); 5582c020ed8SCatalin Marinas return 0; 5592c020ed8SCatalin Marinas } 5602c020ed8SCatalin Marinas 56194b07c1fSDave Martin /* 56294b07c1fSDave Martin * Determine the layout of optional records in the signal frame 56394b07c1fSDave Martin * 56494b07c1fSDave Martin * add_all: if true, lays out the biggest possible signal frame for 56594b07c1fSDave Martin * this task; otherwise, generates a layout for the current state 56694b07c1fSDave Martin * of the task. 56794b07c1fSDave Martin */ 56894b07c1fSDave Martin static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, 56994b07c1fSDave Martin bool add_all) 570bb4891a6SDave Martin { 571bb4322f7SDave Martin int err; 572bb4322f7SDave Martin 573bb4322f7SDave Martin err = sigframe_alloc(user, &user->fpsimd_offset, 574bb4322f7SDave Martin sizeof(struct fpsimd_context)); 575bb4322f7SDave Martin if (err) 576bb4322f7SDave Martin return err; 577bb4891a6SDave Martin 578bb4891a6SDave Martin /* fault information, if valid */ 57994b07c1fSDave Martin if (add_all || current->thread.fault_code) { 580bb4322f7SDave Martin err = sigframe_alloc(user, &user->esr_offset, 581bb4322f7SDave Martin sizeof(struct esr_context)); 582bb4322f7SDave Martin if (err) 583bb4322f7SDave Martin return err; 584bb4891a6SDave Martin } 585bb4891a6SDave Martin 5868cd969d2SDave Martin if (system_supports_sve()) { 5878cd969d2SDave Martin unsigned int vq = 0; 5888cd969d2SDave Martin 58994b07c1fSDave Martin if (add_all || test_thread_flag(TIF_SVE)) { 59094b07c1fSDave Martin int vl = sve_max_vl; 59194b07c1fSDave Martin 59294b07c1fSDave Martin if (!add_all) 59394b07c1fSDave Martin vl = current->thread.sve_vl; 59494b07c1fSDave Martin 59594b07c1fSDave Martin vq = sve_vq_from_vl(vl); 59694b07c1fSDave Martin } 5978cd969d2SDave Martin 5988cd969d2SDave Martin err = sigframe_alloc(user, &user->sve_offset, 5998cd969d2SDave Martin SVE_SIG_CONTEXT_SIZE(vq)); 6008cd969d2SDave Martin if (err) 6018cd969d2SDave Martin return err; 6028cd969d2SDave Martin } 6038cd969d2SDave Martin 60433f08261SDave Martin return sigframe_alloc_end(user); 605bb4891a6SDave Martin } 606bb4891a6SDave Martin 60720987de3SDave Martin static int setup_sigframe(struct rt_sigframe_user_layout *user, 6082c020ed8SCatalin Marinas struct pt_regs *regs, sigset_t *set) 6092c020ed8SCatalin Marinas { 6102c020ed8SCatalin Marinas int i, err = 0; 61120987de3SDave Martin struct rt_sigframe __user *sf = user->sigframe; 6122c020ed8SCatalin Marinas 613304ef4e8SWill Deacon /* set up the stack frame for unwinding */ 61420987de3SDave Martin __put_user_error(regs->regs[29], &user->next_frame->fp, err); 61520987de3SDave Martin __put_user_error(regs->regs[30], &user->next_frame->lr, err); 616304ef4e8SWill Deacon 6172c020ed8SCatalin Marinas for (i = 0; i < 31; i++) 6182c020ed8SCatalin Marinas __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], 6192c020ed8SCatalin Marinas err); 6202c020ed8SCatalin Marinas __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); 6212c020ed8SCatalin Marinas __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); 6222c020ed8SCatalin Marinas __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); 6232c020ed8SCatalin Marinas 6242c020ed8SCatalin Marinas __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); 6252c020ed8SCatalin Marinas 6262c020ed8SCatalin Marinas err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); 6272c020ed8SCatalin Marinas 6286d502b6bSSuzuki K Poulose if (err == 0 && system_supports_fpsimd()) { 629bb4891a6SDave Martin struct fpsimd_context __user *fpsimd_ctx = 630bb4891a6SDave Martin apply_user_offset(user, user->fpsimd_offset); 6310e0276d1SCatalin Marinas err |= preserve_fpsimd_context(fpsimd_ctx); 6320e0276d1SCatalin Marinas } 6332c020ed8SCatalin Marinas 63415af1942SCatalin Marinas /* fault information, if valid */ 635bb4891a6SDave Martin if (err == 0 && user->esr_offset) { 636bb4891a6SDave Martin struct esr_context __user *esr_ctx = 637bb4891a6SDave Martin apply_user_offset(user, user->esr_offset); 638bb4891a6SDave Martin 63915af1942SCatalin Marinas __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); 64015af1942SCatalin Marinas __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); 64115af1942SCatalin Marinas __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); 64215af1942SCatalin Marinas } 64315af1942SCatalin Marinas 6448cd969d2SDave Martin /* Scalable Vector Extension state, if present */ 6458cd969d2SDave Martin if (system_supports_sve() && err == 0 && user->sve_offset) { 6468cd969d2SDave Martin struct sve_context __user *sve_ctx = 6478cd969d2SDave Martin apply_user_offset(user, user->sve_offset); 6488cd969d2SDave Martin err |= preserve_sve_context(sve_ctx); 6498cd969d2SDave Martin } 6508cd969d2SDave Martin 65133f08261SDave Martin if (err == 0 && user->extra_offset) { 65233f08261SDave Martin char __user *sfp = (char __user *)user->sigframe; 65333f08261SDave Martin char __user *userp = 65433f08261SDave Martin apply_user_offset(user, user->extra_offset); 65533f08261SDave Martin 65633f08261SDave Martin struct extra_context __user *extra; 65733f08261SDave Martin struct _aarch64_ctx __user *end; 65833f08261SDave Martin u64 extra_datap; 65933f08261SDave Martin u32 extra_size; 66033f08261SDave Martin 66133f08261SDave Martin extra = (struct extra_context __user *)userp; 66233f08261SDave Martin userp += EXTRA_CONTEXT_SIZE; 66333f08261SDave Martin 66433f08261SDave Martin end = (struct _aarch64_ctx __user *)userp; 66533f08261SDave Martin userp += TERMINATOR_SIZE; 66633f08261SDave Martin 66733f08261SDave Martin /* 66833f08261SDave Martin * extra_datap is just written to the signal frame. 66933f08261SDave Martin * The value gets cast back to a void __user * 67033f08261SDave Martin * during sigreturn. 67133f08261SDave Martin */ 67233f08261SDave Martin extra_datap = (__force u64)userp; 67333f08261SDave Martin extra_size = sfp + round_up(user->size, 16) - userp; 67433f08261SDave Martin 67533f08261SDave Martin __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); 67633f08261SDave Martin __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); 67733f08261SDave Martin __put_user_error(extra_datap, &extra->datap, err); 67833f08261SDave Martin __put_user_error(extra_size, &extra->size, err); 67933f08261SDave Martin 68033f08261SDave Martin /* Add the terminator */ 68133f08261SDave Martin __put_user_error(0, &end->magic, err); 68233f08261SDave Martin __put_user_error(0, &end->size, err); 68333f08261SDave Martin } 68433f08261SDave Martin 6852c020ed8SCatalin Marinas /* set the "end" magic */ 686bb4891a6SDave Martin if (err == 0) { 687bb4891a6SDave Martin struct _aarch64_ctx __user *end = 688bb4891a6SDave Martin apply_user_offset(user, user->end_offset); 689bb4891a6SDave Martin 6900e0276d1SCatalin Marinas __put_user_error(0, &end->magic, err); 6910e0276d1SCatalin Marinas __put_user_error(0, &end->size, err); 692bb4891a6SDave Martin } 6932c020ed8SCatalin Marinas 6942c020ed8SCatalin Marinas return err; 6952c020ed8SCatalin Marinas } 6962c020ed8SCatalin Marinas 69720987de3SDave Martin static int get_sigframe(struct rt_sigframe_user_layout *user, 69820987de3SDave Martin struct ksignal *ksig, struct pt_regs *regs) 6992c020ed8SCatalin Marinas { 7002c020ed8SCatalin Marinas unsigned long sp, sp_top; 701bb4891a6SDave Martin int err; 702bb4891a6SDave Martin 703bb4891a6SDave Martin init_user_layout(user); 70494b07c1fSDave Martin err = setup_sigframe_layout(user, false); 705bb4891a6SDave Martin if (err) 706bb4891a6SDave Martin return err; 7072c020ed8SCatalin Marinas 70838a7be3cSRichard Weinberger sp = sp_top = sigsp(regs->sp, ksig); 7092c020ed8SCatalin Marinas 71020987de3SDave Martin sp = round_down(sp - sizeof(struct frame_record), 16); 71120987de3SDave Martin user->next_frame = (struct frame_record __user *)sp; 71220987de3SDave Martin 713bb4891a6SDave Martin sp = round_down(sp, 16) - sigframe_size(user); 71420987de3SDave Martin user->sigframe = (struct rt_sigframe __user *)sp; 7152c020ed8SCatalin Marinas 7162c020ed8SCatalin Marinas /* 7172c020ed8SCatalin Marinas * Check that we can actually write to the signal frame. 7182c020ed8SCatalin Marinas */ 71996d4f267SLinus Torvalds if (!access_ok(user->sigframe, sp_top - sp)) 72020987de3SDave Martin return -EFAULT; 7212c020ed8SCatalin Marinas 72220987de3SDave Martin return 0; 7232c020ed8SCatalin Marinas } 7242c020ed8SCatalin Marinas 725304ef4e8SWill Deacon static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, 72620987de3SDave Martin struct rt_sigframe_user_layout *user, int usig) 7272c020ed8SCatalin Marinas { 7282c020ed8SCatalin Marinas __sigrestore_t sigtramp; 7292c020ed8SCatalin Marinas 7302c020ed8SCatalin Marinas regs->regs[0] = usig; 73120987de3SDave Martin regs->sp = (unsigned long)user->sigframe; 73220987de3SDave Martin regs->regs[29] = (unsigned long)&user->next_frame->fp; 7332c020ed8SCatalin Marinas regs->pc = (unsigned long)ka->sa.sa_handler; 7342c020ed8SCatalin Marinas 7358ef8f360SDave Martin /* 7368ef8f360SDave Martin * Signal delivery is a (wacky) indirect function call in 7378ef8f360SDave Martin * userspace, so simulate the same setting of BTYPE as a BLR 7388ef8f360SDave Martin * <register containing the signal handler entry point>. 7398ef8f360SDave Martin * Signal delivery to a location in a PROT_BTI guarded page 7408ef8f360SDave Martin * that is not a function entry point will now trigger a 7418ef8f360SDave Martin * SIGILL in userspace. 7428ef8f360SDave Martin * 7438ef8f360SDave Martin * If the signal handler entry point is not in a PROT_BTI 7448ef8f360SDave Martin * guarded page, this is harmless. 7458ef8f360SDave Martin */ 7468ef8f360SDave Martin if (system_supports_bti()) { 7478ef8f360SDave Martin regs->pstate &= ~PSR_BTYPE_MASK; 7488ef8f360SDave Martin regs->pstate |= PSR_BTYPE_C; 7498ef8f360SDave Martin } 7508ef8f360SDave Martin 7512c020ed8SCatalin Marinas if (ka->sa.sa_flags & SA_RESTORER) 7522c020ed8SCatalin Marinas sigtramp = ka->sa.sa_restorer; 7532c020ed8SCatalin Marinas else 7542c020ed8SCatalin Marinas sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); 7552c020ed8SCatalin Marinas 7562c020ed8SCatalin Marinas regs->regs[30] = (unsigned long)sigtramp; 7572c020ed8SCatalin Marinas } 7582c020ed8SCatalin Marinas 75900554fa4SRichard Weinberger static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, 76000554fa4SRichard Weinberger struct pt_regs *regs) 7612c020ed8SCatalin Marinas { 76220987de3SDave Martin struct rt_sigframe_user_layout user; 7632c020ed8SCatalin Marinas struct rt_sigframe __user *frame; 7642c020ed8SCatalin Marinas int err = 0; 7652c020ed8SCatalin Marinas 7668cd969d2SDave Martin fpsimd_signal_preserve_current_state(); 7678cd969d2SDave Martin 76820987de3SDave Martin if (get_sigframe(&user, ksig, regs)) 7692c020ed8SCatalin Marinas return 1; 7702c020ed8SCatalin Marinas 77120987de3SDave Martin frame = user.sigframe; 77220987de3SDave Martin 7732c020ed8SCatalin Marinas __put_user_error(0, &frame->uc.uc_flags, err); 7742c020ed8SCatalin Marinas __put_user_error(NULL, &frame->uc.uc_link, err); 7752c020ed8SCatalin Marinas 776207bdae4SAl Viro err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 77720987de3SDave Martin err |= setup_sigframe(&user, regs, set); 778304ef4e8SWill Deacon if (err == 0) { 77920987de3SDave Martin setup_return(regs, &ksig->ka, &user, usig); 78000554fa4SRichard Weinberger if (ksig->ka.sa.sa_flags & SA_SIGINFO) { 78100554fa4SRichard Weinberger err |= copy_siginfo_to_user(&frame->info, &ksig->info); 7822c020ed8SCatalin Marinas regs->regs[1] = (unsigned long)&frame->info; 7832c020ed8SCatalin Marinas regs->regs[2] = (unsigned long)&frame->uc; 7842c020ed8SCatalin Marinas } 785304ef4e8SWill Deacon } 7862c020ed8SCatalin Marinas 7872c020ed8SCatalin Marinas return err; 7882c020ed8SCatalin Marinas } 7892c020ed8SCatalin Marinas 7902c020ed8SCatalin Marinas static void setup_restart_syscall(struct pt_regs *regs) 7912c020ed8SCatalin Marinas { 7922c020ed8SCatalin Marinas if (is_compat_task()) 7932c020ed8SCatalin Marinas compat_setup_restart_syscall(regs); 7942c020ed8SCatalin Marinas else 7952c020ed8SCatalin Marinas regs->regs[8] = __NR_restart_syscall; 7962c020ed8SCatalin Marinas } 7972c020ed8SCatalin Marinas 7982c020ed8SCatalin Marinas /* 7992c020ed8SCatalin Marinas * OK, we're invoking a handler 8002c020ed8SCatalin Marinas */ 80100554fa4SRichard Weinberger static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 8022c020ed8SCatalin Marinas { 8032c020ed8SCatalin Marinas struct task_struct *tsk = current; 8042c020ed8SCatalin Marinas sigset_t *oldset = sigmask_to_save(); 80500554fa4SRichard Weinberger int usig = ksig->sig; 8062c020ed8SCatalin Marinas int ret; 8072c020ed8SCatalin Marinas 808409d5db4SWill Deacon rseq_signal_deliver(ksig, regs); 809409d5db4SWill Deacon 8102c020ed8SCatalin Marinas /* 8112c020ed8SCatalin Marinas * Set up the stack frame 8122c020ed8SCatalin Marinas */ 8132c020ed8SCatalin Marinas if (is_compat_task()) { 81400554fa4SRichard Weinberger if (ksig->ka.sa.sa_flags & SA_SIGINFO) 81500554fa4SRichard Weinberger ret = compat_setup_rt_frame(usig, ksig, oldset, regs); 8162c020ed8SCatalin Marinas else 81700554fa4SRichard Weinberger ret = compat_setup_frame(usig, ksig, oldset, regs); 8182c020ed8SCatalin Marinas } else { 81900554fa4SRichard Weinberger ret = setup_rt_frame(usig, ksig, oldset, regs); 8202c020ed8SCatalin Marinas } 8212c020ed8SCatalin Marinas 8222c020ed8SCatalin Marinas /* 8232c020ed8SCatalin Marinas * Check that the resulting registers are actually sane. 8242c020ed8SCatalin Marinas */ 825dbd4d7caSMark Rutland ret |= !valid_user_regs(®s->user_regs, current); 8262c020ed8SCatalin Marinas 8272c020ed8SCatalin Marinas /* 8282c020ed8SCatalin Marinas * Fast forward the stepping logic so we step into the signal 8292c020ed8SCatalin Marinas * handler. 8302c020ed8SCatalin Marinas */ 83100554fa4SRichard Weinberger if (!ret) 8322c020ed8SCatalin Marinas user_fastforward_single_step(tsk); 8332c020ed8SCatalin Marinas 83400554fa4SRichard Weinberger signal_setup_done(ret, ksig, 0); 8352c020ed8SCatalin Marinas } 8362c020ed8SCatalin Marinas 8372c020ed8SCatalin Marinas /* 8382c020ed8SCatalin Marinas * Note that 'init' is a special process: it doesn't get signals it doesn't 8392c020ed8SCatalin Marinas * want to handle. Thus you cannot kill init even with a SIGKILL even by 8402c020ed8SCatalin Marinas * mistake. 8412c020ed8SCatalin Marinas * 8422c020ed8SCatalin Marinas * Note that we go through the signals twice: once to check the signals that 8432c020ed8SCatalin Marinas * the kernel can handle, and then we build all the user-level signal handling 8442c020ed8SCatalin Marinas * stack-frames in one go after that. 8452c020ed8SCatalin Marinas */ 8462c020ed8SCatalin Marinas static void do_signal(struct pt_regs *regs) 8472c020ed8SCatalin Marinas { 8482c020ed8SCatalin Marinas unsigned long continue_addr = 0, restart_addr = 0; 84900554fa4SRichard Weinberger int retval = 0; 85000554fa4SRichard Weinberger struct ksignal ksig; 8510fe42512SDave Martin bool syscall = in_syscall(regs); 8522c020ed8SCatalin Marinas 8532c020ed8SCatalin Marinas /* 8542c020ed8SCatalin Marinas * If we were from a system call, check for system call restarting... 8552c020ed8SCatalin Marinas */ 8560fe42512SDave Martin if (syscall) { 8572c020ed8SCatalin Marinas continue_addr = regs->pc; 8582c020ed8SCatalin Marinas restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); 8592c020ed8SCatalin Marinas retval = regs->regs[0]; 8602c020ed8SCatalin Marinas 8612c020ed8SCatalin Marinas /* 8622c020ed8SCatalin Marinas * Avoid additional syscall restarting via ret_to_user. 8632c020ed8SCatalin Marinas */ 86417c28958SDave Martin forget_syscall(regs); 8652c020ed8SCatalin Marinas 8662c020ed8SCatalin Marinas /* 8672c020ed8SCatalin Marinas * Prepare for system call restart. We do this here so that a 8682c020ed8SCatalin Marinas * debugger will see the already changed PC. 8692c020ed8SCatalin Marinas */ 8702c020ed8SCatalin Marinas switch (retval) { 8712c020ed8SCatalin Marinas case -ERESTARTNOHAND: 8722c020ed8SCatalin Marinas case -ERESTARTSYS: 8732c020ed8SCatalin Marinas case -ERESTARTNOINTR: 8742c020ed8SCatalin Marinas case -ERESTART_RESTARTBLOCK: 8752c020ed8SCatalin Marinas regs->regs[0] = regs->orig_x0; 8762c020ed8SCatalin Marinas regs->pc = restart_addr; 8772c020ed8SCatalin Marinas break; 8782c020ed8SCatalin Marinas } 8792c020ed8SCatalin Marinas } 8802c020ed8SCatalin Marinas 8812c020ed8SCatalin Marinas /* 8822c020ed8SCatalin Marinas * Get the signal to deliver. When running under ptrace, at this point 8832c020ed8SCatalin Marinas * the debugger may change all of our registers. 8842c020ed8SCatalin Marinas */ 88500554fa4SRichard Weinberger if (get_signal(&ksig)) { 8862c020ed8SCatalin Marinas /* 8872c020ed8SCatalin Marinas * Depending on the signal settings, we may need to revert the 8882c020ed8SCatalin Marinas * decision to restart the system call, but skip this if a 8892c020ed8SCatalin Marinas * debugger has chosen to restart at a different PC. 8902c020ed8SCatalin Marinas */ 8912c020ed8SCatalin Marinas if (regs->pc == restart_addr && 8922c020ed8SCatalin Marinas (retval == -ERESTARTNOHAND || 8932c020ed8SCatalin Marinas retval == -ERESTART_RESTARTBLOCK || 8942c020ed8SCatalin Marinas (retval == -ERESTARTSYS && 89500554fa4SRichard Weinberger !(ksig.ka.sa.sa_flags & SA_RESTART)))) { 8962c020ed8SCatalin Marinas regs->regs[0] = -EINTR; 8972c020ed8SCatalin Marinas regs->pc = continue_addr; 8982c020ed8SCatalin Marinas } 8992c020ed8SCatalin Marinas 90000554fa4SRichard Weinberger handle_signal(&ksig, regs); 9012c020ed8SCatalin Marinas return; 9022c020ed8SCatalin Marinas } 9032c020ed8SCatalin Marinas 9042c020ed8SCatalin Marinas /* 9052c020ed8SCatalin Marinas * Handle restarting a different system call. As above, if a debugger 9062c020ed8SCatalin Marinas * has chosen to restart at a different PC, ignore the restart. 9072c020ed8SCatalin Marinas */ 9080fe42512SDave Martin if (syscall && regs->pc == restart_addr) { 9092c020ed8SCatalin Marinas if (retval == -ERESTART_RESTARTBLOCK) 9102c020ed8SCatalin Marinas setup_restart_syscall(regs); 9112c020ed8SCatalin Marinas user_rewind_single_step(current); 9122c020ed8SCatalin Marinas } 9132c020ed8SCatalin Marinas 9142c020ed8SCatalin Marinas restore_saved_sigmask(); 9152c020ed8SCatalin Marinas } 9162c020ed8SCatalin Marinas 9172c020ed8SCatalin Marinas asmlinkage void do_notify_resume(struct pt_regs *regs, 9183eb6f1f9SMark Rutland unsigned long thread_flags) 9192c020ed8SCatalin Marinas { 920421dd6faSChris Metcalf /* 921421dd6faSChris Metcalf * The assembly code enters us with IRQs off, but it hasn't 922421dd6faSChris Metcalf * informed the tracing code of that for efficiency reasons. 923421dd6faSChris Metcalf * Update the trace code with the current status. 924421dd6faSChris Metcalf */ 925421dd6faSChris Metcalf trace_hardirqs_off(); 926cf7de27aSThomas Garnier 927a2048e34SThomas Garnier do { 928cf7de27aSThomas Garnier /* Check valid user FS if needed */ 929cf7de27aSThomas Garnier addr_limit_user_check(); 930cf7de27aSThomas Garnier 931421dd6faSChris Metcalf if (thread_flags & _TIF_NEED_RESCHED) { 9328d66772eSJames Morse /* Unmask Debug and SError for the next task */ 9338d66772eSJames Morse local_daif_restore(DAIF_PROCCTX_NOIRQ); 9348d66772eSJames Morse 935421dd6faSChris Metcalf schedule(); 936421dd6faSChris Metcalf } else { 9378d66772eSJames Morse local_daif_restore(DAIF_PROCCTX); 938421dd6faSChris Metcalf 9399842ceaeSPratyush Anand if (thread_flags & _TIF_UPROBE) 9409842ceaeSPratyush Anand uprobe_notify_resume(regs); 9419842ceaeSPratyush Anand 9422c020ed8SCatalin Marinas if (thread_flags & _TIF_SIGPENDING) 9432c020ed8SCatalin Marinas do_signal(regs); 9442c020ed8SCatalin Marinas 9452c020ed8SCatalin Marinas if (thread_flags & _TIF_NOTIFY_RESUME) { 9462c020ed8SCatalin Marinas clear_thread_flag(TIF_NOTIFY_RESUME); 9472c020ed8SCatalin Marinas tracehook_notify_resume(regs); 948409d5db4SWill Deacon rseq_handle_notify_resume(NULL, regs); 9492c020ed8SCatalin Marinas } 950005f78cdSArd Biesheuvel 951005f78cdSArd Biesheuvel if (thread_flags & _TIF_FOREIGN_FPSTATE) 952005f78cdSArd Biesheuvel fpsimd_restore_current_state(); 953421dd6faSChris Metcalf } 954005f78cdSArd Biesheuvel 9558d66772eSJames Morse local_daif_mask(); 956421dd6faSChris Metcalf thread_flags = READ_ONCE(current_thread_info()->flags); 957421dd6faSChris Metcalf } while (thread_flags & _TIF_WORK_MASK); 9582c020ed8SCatalin Marinas } 95994b07c1fSDave Martin 96094b07c1fSDave Martin unsigned long __ro_after_init signal_minsigstksz; 96194b07c1fSDave Martin 96294b07c1fSDave Martin /* 96394b07c1fSDave Martin * Determine the stack space required for guaranteed signal devliery. 96494b07c1fSDave Martin * This function is used to populate AT_MINSIGSTKSZ at process startup. 96594b07c1fSDave Martin * cpufeatures setup is assumed to be complete. 96694b07c1fSDave Martin */ 96794b07c1fSDave Martin void __init minsigstksz_setup(void) 96894b07c1fSDave Martin { 96994b07c1fSDave Martin struct rt_sigframe_user_layout user; 97094b07c1fSDave Martin 97194b07c1fSDave Martin init_user_layout(&user); 97294b07c1fSDave Martin 97394b07c1fSDave Martin /* 97494b07c1fSDave Martin * If this fails, SIGFRAME_MAXSZ needs to be enlarged. It won't 97594b07c1fSDave Martin * be big enough, but it's our best guess: 97694b07c1fSDave Martin */ 97794b07c1fSDave Martin if (WARN_ON(setup_sigframe_layout(&user, true))) 97894b07c1fSDave Martin return; 97994b07c1fSDave Martin 98094b07c1fSDave Martin signal_minsigstksz = sigframe_size(&user) + 98194b07c1fSDave Martin round_up(sizeof(struct frame_record), 16) + 98294b07c1fSDave Martin 16; /* max alignment padding */ 98394b07c1fSDave Martin } 984