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/freezer.h> 1547ccb028SDave Martin #include <linux/stddef.h> 162c020ed8SCatalin Marinas #include <linux/uaccess.h> 1733f08261SDave Martin #include <linux/sizes.h> 18bb4891a6SDave Martin #include <linux/string.h> 1903248addSEric W. Biederman #include <linux/resume_user_mode.h> 202c020ed8SCatalin Marinas #include <linux/ratelimit.h> 21cf7de27aSThomas Garnier #include <linux/syscalls.h> 222c020ed8SCatalin Marinas 238d66772eSJames Morse #include <asm/daifflags.h> 242c020ed8SCatalin Marinas #include <asm/debug-monitors.h> 252c020ed8SCatalin Marinas #include <asm/elf.h> 262c020ed8SCatalin Marinas #include <asm/cacheflush.h> 272c020ed8SCatalin Marinas #include <asm/ucontext.h> 282c020ed8SCatalin Marinas #include <asm/unistd.h> 292c020ed8SCatalin Marinas #include <asm/fpsimd.h> 3017c28958SDave Martin #include <asm/ptrace.h> 31e30e8d46SMark Rutland #include <asm/syscall.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)]; 2290423eedcSMark Brown unsigned int vl = task_get_sve_vl(current); 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 24768a4c52eSJulien Grall * the task struct by calling the function 24868a4c52eSJulien Grall * fpsimd_signal_preserve_current_state(). 2498cd969d2SDave Martin */ 2508cd969d2SDave Martin err |= __copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET, 2518cd969d2SDave Martin current->thread.sve_state, 2528cd969d2SDave Martin SVE_SIG_REGS_SIZE(vq)); 2538cd969d2SDave Martin } 2548cd969d2SDave Martin 2558cd969d2SDave Martin return err ? -EFAULT : 0; 2568cd969d2SDave Martin } 2578cd969d2SDave Martin 2588cd969d2SDave Martin static int restore_sve_fpsimd_context(struct user_ctxs *user) 2598cd969d2SDave Martin { 2608cd969d2SDave Martin int err; 2618cd969d2SDave Martin unsigned int vq; 2620abdeff5SDave Martin struct user_fpsimd_state fpsimd; 2638cd969d2SDave Martin struct sve_context sve; 2648cd969d2SDave Martin 2658cd969d2SDave Martin if (__copy_from_user(&sve, user->sve, sizeof(sve))) 2668cd969d2SDave Martin return -EFAULT; 2678cd969d2SDave Martin 2680423eedcSMark Brown if (sve.vl != task_get_sve_vl(current)) 2698cd969d2SDave Martin return -EINVAL; 2708cd969d2SDave Martin 2718cd969d2SDave Martin if (sve.head.size <= sizeof(*user->sve)) { 2728cd969d2SDave Martin clear_thread_flag(TIF_SVE); 2738cd969d2SDave Martin goto fpsimd_only; 2748cd969d2SDave Martin } 2758cd969d2SDave Martin 2768cd969d2SDave Martin vq = sve_vq_from_vl(sve.vl); 2778cd969d2SDave Martin 2788cd969d2SDave Martin if (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq)) 2798cd969d2SDave Martin return -EINVAL; 2808cd969d2SDave Martin 2818cd969d2SDave Martin /* 2828cd969d2SDave Martin * Careful: we are about __copy_from_user() directly into 2838cd969d2SDave Martin * thread.sve_state with preemption enabled, so protection is 2848cd969d2SDave Martin * needed to prevent a racing context switch from writing stale 2858cd969d2SDave Martin * registers back over the new data. 2868cd969d2SDave Martin */ 2878cd969d2SDave Martin 2888cd969d2SDave Martin fpsimd_flush_task_state(current); 2898cd969d2SDave Martin /* From now, fpsimd_thread_switch() won't touch thread.sve_state */ 2908cd969d2SDave Martin 2918cd969d2SDave Martin sve_alloc(current); 2927559b7d7SMark Brown if (!current->thread.sve_state) { 2937559b7d7SMark Brown clear_thread_flag(TIF_SVE); 2947559b7d7SMark Brown return -ENOMEM; 2957559b7d7SMark Brown } 2967559b7d7SMark Brown 2978cd969d2SDave Martin err = __copy_from_user(current->thread.sve_state, 2988cd969d2SDave Martin (char __user const *)user->sve + 2998cd969d2SDave Martin SVE_SIG_REGS_OFFSET, 3008cd969d2SDave Martin SVE_SIG_REGS_SIZE(vq)); 3018cd969d2SDave Martin if (err) 3028cd969d2SDave Martin return -EFAULT; 3038cd969d2SDave Martin 3048cd969d2SDave Martin set_thread_flag(TIF_SVE); 3058cd969d2SDave Martin 3068cd969d2SDave Martin fpsimd_only: 3078cd969d2SDave Martin /* copy the FP and status/control registers */ 3088cd969d2SDave Martin /* restore_sigframe() already checked that user->fpsimd != NULL. */ 3098cd969d2SDave Martin err = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs, 3108cd969d2SDave Martin sizeof(fpsimd.vregs)); 3118cd969d2SDave Martin __get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err); 3128cd969d2SDave Martin __get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err); 3138cd969d2SDave Martin 3148cd969d2SDave Martin /* load the hardware registers from the fpsimd_state structure */ 3158cd969d2SDave Martin if (!err) 3168cd969d2SDave Martin fpsimd_update_current_state(&fpsimd); 3178cd969d2SDave Martin 3188cd969d2SDave Martin return err ? -EFAULT : 0; 3198cd969d2SDave Martin } 3208cd969d2SDave Martin 3218cd969d2SDave Martin #else /* ! CONFIG_ARM64_SVE */ 3228cd969d2SDave Martin 3238cd969d2SDave Martin /* Turn any non-optimised out attempts to use these into a link error: */ 3248cd969d2SDave Martin extern int preserve_sve_context(void __user *ctx); 3258cd969d2SDave Martin extern int restore_sve_fpsimd_context(struct user_ctxs *user); 3268cd969d2SDave Martin 3278cd969d2SDave Martin #endif /* ! CONFIG_ARM64_SVE */ 3288cd969d2SDave Martin 3298cd969d2SDave Martin 33047ccb028SDave Martin static int parse_user_sigframe(struct user_ctxs *user, 33147ccb028SDave Martin struct rt_sigframe __user *sf) 33247ccb028SDave Martin { 33347ccb028SDave Martin struct sigcontext __user *const sc = &sf->uc.uc_mcontext; 334bb4891a6SDave Martin struct _aarch64_ctx __user *head; 335bb4891a6SDave Martin char __user *base = (char __user *)&sc->__reserved; 33647ccb028SDave Martin size_t offset = 0; 337bb4891a6SDave Martin size_t limit = sizeof(sc->__reserved); 33833f08261SDave Martin bool have_extra_context = false; 33933f08261SDave Martin char const __user *const sfp = (char const __user *)sf; 34047ccb028SDave Martin 34147ccb028SDave Martin user->fpsimd = NULL; 3428cd969d2SDave Martin user->sve = NULL; 34347ccb028SDave Martin 344bb4891a6SDave Martin if (!IS_ALIGNED((unsigned long)base, 16)) 34547ccb028SDave Martin goto invalid; 34647ccb028SDave Martin 347bb4891a6SDave Martin while (1) { 348bb4891a6SDave Martin int err = 0; 349bb4891a6SDave Martin u32 magic, size; 35033f08261SDave Martin char const __user *userp; 35133f08261SDave Martin struct extra_context const __user *extra; 35233f08261SDave Martin u64 extra_datap; 35333f08261SDave Martin u32 extra_size; 35433f08261SDave Martin struct _aarch64_ctx const __user *end; 35533f08261SDave Martin u32 end_magic, end_size; 356bb4891a6SDave Martin 357bb4891a6SDave Martin if (limit - offset < sizeof(*head)) 358bb4891a6SDave Martin goto invalid; 359bb4891a6SDave Martin 360bb4891a6SDave Martin if (!IS_ALIGNED(offset, 16)) 361bb4891a6SDave Martin goto invalid; 362bb4891a6SDave Martin 363bb4891a6SDave Martin head = (struct _aarch64_ctx __user *)(base + offset); 36447ccb028SDave Martin __get_user_error(magic, &head->magic, err); 36547ccb028SDave Martin __get_user_error(size, &head->size, err); 36647ccb028SDave Martin if (err) 36747ccb028SDave Martin return err; 36847ccb028SDave Martin 369bb4891a6SDave Martin if (limit - offset < size) 370bb4891a6SDave Martin goto invalid; 371bb4891a6SDave Martin 37247ccb028SDave Martin switch (magic) { 37347ccb028SDave Martin case 0: 37447ccb028SDave Martin if (size) 37547ccb028SDave Martin goto invalid; 37647ccb028SDave Martin 37747ccb028SDave Martin goto done; 37847ccb028SDave Martin 37947ccb028SDave Martin case FPSIMD_MAGIC: 3806d502b6bSSuzuki K Poulose if (!system_supports_fpsimd()) 3816d502b6bSSuzuki K Poulose goto invalid; 38247ccb028SDave Martin if (user->fpsimd) 38347ccb028SDave Martin goto invalid; 38447ccb028SDave Martin 385bb4891a6SDave Martin if (size < sizeof(*user->fpsimd)) 38647ccb028SDave Martin goto invalid; 38747ccb028SDave Martin 38847ccb028SDave Martin user->fpsimd = (struct fpsimd_context __user *)head; 38947ccb028SDave Martin break; 39047ccb028SDave Martin 39147ccb028SDave Martin case ESR_MAGIC: 39247ccb028SDave Martin /* ignore */ 39347ccb028SDave Martin break; 39447ccb028SDave Martin 3958cd969d2SDave Martin case SVE_MAGIC: 3968cd969d2SDave Martin if (!system_supports_sve()) 3978cd969d2SDave Martin goto invalid; 3988cd969d2SDave Martin 3998cd969d2SDave Martin if (user->sve) 4008cd969d2SDave Martin goto invalid; 4018cd969d2SDave Martin 4028cd969d2SDave Martin if (size < sizeof(*user->sve)) 4038cd969d2SDave Martin goto invalid; 4048cd969d2SDave Martin 4058cd969d2SDave Martin user->sve = (struct sve_context __user *)head; 4068cd969d2SDave Martin break; 4078cd969d2SDave Martin 40833f08261SDave Martin case EXTRA_MAGIC: 40933f08261SDave Martin if (have_extra_context) 41033f08261SDave Martin goto invalid; 41133f08261SDave Martin 41233f08261SDave Martin if (size < sizeof(*extra)) 41333f08261SDave Martin goto invalid; 41433f08261SDave Martin 41533f08261SDave Martin userp = (char const __user *)head; 41633f08261SDave Martin 41733f08261SDave Martin extra = (struct extra_context const __user *)userp; 41833f08261SDave Martin userp += size; 41933f08261SDave Martin 42033f08261SDave Martin __get_user_error(extra_datap, &extra->datap, err); 42133f08261SDave Martin __get_user_error(extra_size, &extra->size, err); 42233f08261SDave Martin if (err) 42333f08261SDave Martin return err; 42433f08261SDave Martin 42533f08261SDave Martin /* Check for the dummy terminator in __reserved[]: */ 42633f08261SDave Martin 42733f08261SDave Martin if (limit - offset - size < TERMINATOR_SIZE) 42833f08261SDave Martin goto invalid; 42933f08261SDave Martin 43033f08261SDave Martin end = (struct _aarch64_ctx const __user *)userp; 43133f08261SDave Martin userp += TERMINATOR_SIZE; 43233f08261SDave Martin 43333f08261SDave Martin __get_user_error(end_magic, &end->magic, err); 43433f08261SDave Martin __get_user_error(end_size, &end->size, err); 43533f08261SDave Martin if (err) 43633f08261SDave Martin return err; 43733f08261SDave Martin 43833f08261SDave Martin if (end_magic || end_size) 43933f08261SDave Martin goto invalid; 44033f08261SDave Martin 44133f08261SDave Martin /* Prevent looping/repeated parsing of extra_context */ 44233f08261SDave Martin have_extra_context = true; 44333f08261SDave Martin 44433f08261SDave Martin base = (__force void __user *)extra_datap; 44533f08261SDave Martin if (!IS_ALIGNED((unsigned long)base, 16)) 44633f08261SDave Martin goto invalid; 44733f08261SDave Martin 44833f08261SDave Martin if (!IS_ALIGNED(extra_size, 16)) 44933f08261SDave Martin goto invalid; 45033f08261SDave Martin 45133f08261SDave Martin if (base != userp) 45233f08261SDave Martin goto invalid; 45333f08261SDave Martin 45433f08261SDave Martin /* Reject "unreasonably large" frames: */ 45533f08261SDave Martin if (extra_size > sfp + SIGFRAME_MAXSZ - userp) 45633f08261SDave Martin goto invalid; 45733f08261SDave Martin 45833f08261SDave Martin /* 45933f08261SDave Martin * Ignore trailing terminator in __reserved[] 46033f08261SDave Martin * and start parsing extra data: 46133f08261SDave Martin */ 46233f08261SDave Martin offset = 0; 46333f08261SDave Martin limit = extra_size; 464abf73988SDave Martin 46596d4f267SLinus Torvalds if (!access_ok(base, limit)) 466abf73988SDave Martin goto invalid; 467abf73988SDave Martin 46833f08261SDave Martin continue; 46933f08261SDave Martin 47047ccb028SDave Martin default: 47147ccb028SDave Martin goto invalid; 47247ccb028SDave Martin } 47347ccb028SDave Martin 47447ccb028SDave Martin if (size < sizeof(*head)) 47547ccb028SDave Martin goto invalid; 47647ccb028SDave Martin 477bb4891a6SDave Martin if (limit - offset < size) 47847ccb028SDave Martin goto invalid; 47947ccb028SDave Martin 48047ccb028SDave Martin offset += size; 48147ccb028SDave Martin } 48247ccb028SDave Martin 48347ccb028SDave Martin done: 48447ccb028SDave Martin return 0; 48547ccb028SDave Martin 48647ccb028SDave Martin invalid: 48747ccb028SDave Martin return -EINVAL; 48847ccb028SDave Martin } 48947ccb028SDave Martin 4902c020ed8SCatalin Marinas static int restore_sigframe(struct pt_regs *regs, 4912c020ed8SCatalin Marinas struct rt_sigframe __user *sf) 4922c020ed8SCatalin Marinas { 4932c020ed8SCatalin Marinas sigset_t set; 4942c020ed8SCatalin Marinas int i, err; 49547ccb028SDave Martin struct user_ctxs user; 4962c020ed8SCatalin Marinas 4972c020ed8SCatalin Marinas err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); 4982c020ed8SCatalin Marinas if (err == 0) 4992c020ed8SCatalin Marinas set_current_blocked(&set); 5002c020ed8SCatalin Marinas 5012c020ed8SCatalin Marinas for (i = 0; i < 31; i++) 5022c020ed8SCatalin Marinas __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], 5032c020ed8SCatalin Marinas err); 5042c020ed8SCatalin Marinas __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); 5052c020ed8SCatalin Marinas __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); 5062c020ed8SCatalin Marinas __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); 5072c020ed8SCatalin Marinas 5082c020ed8SCatalin Marinas /* 5092c020ed8SCatalin Marinas * Avoid sys_rt_sigreturn() restarting. 5102c020ed8SCatalin Marinas */ 51117c28958SDave Martin forget_syscall(regs); 5122c020ed8SCatalin Marinas 513dbd4d7caSMark Rutland err |= !valid_user_regs(®s->user_regs, current); 51447ccb028SDave Martin if (err == 0) 51547ccb028SDave Martin err = parse_user_sigframe(&user, sf); 5162c020ed8SCatalin Marinas 5176d502b6bSSuzuki K Poulose if (err == 0 && system_supports_fpsimd()) { 5188cd969d2SDave Martin if (!user.fpsimd) 5198cd969d2SDave Martin return -EINVAL; 5208cd969d2SDave Martin 5218cd969d2SDave Martin if (user.sve) { 5228cd969d2SDave Martin if (!system_supports_sve()) 5238cd969d2SDave Martin return -EINVAL; 5248cd969d2SDave Martin 5258cd969d2SDave Martin err = restore_sve_fpsimd_context(&user); 5268cd969d2SDave Martin } else { 52747ccb028SDave Martin err = restore_fpsimd_context(user.fpsimd); 5288cd969d2SDave Martin } 5298cd969d2SDave Martin } 5302c020ed8SCatalin Marinas 5312c020ed8SCatalin Marinas return err; 5322c020ed8SCatalin Marinas } 5332c020ed8SCatalin Marinas 534bf4ce5ccSMark Rutland SYSCALL_DEFINE0(rt_sigreturn) 5352c020ed8SCatalin Marinas { 5363085e164SMark Rutland struct pt_regs *regs = current_pt_regs(); 5372c020ed8SCatalin Marinas struct rt_sigframe __user *frame; 5382c020ed8SCatalin Marinas 5392c020ed8SCatalin Marinas /* Always make any pending restarted system calls return -EINTR */ 540f56141e3SAndy Lutomirski current->restart_block.fn = do_no_restart_syscall; 5412c020ed8SCatalin Marinas 5422c020ed8SCatalin Marinas /* 5432c020ed8SCatalin Marinas * Since we stacked the signal on a 128-bit boundary, then 'sp' should 5442c020ed8SCatalin Marinas * be word aligned here. 5452c020ed8SCatalin Marinas */ 5462c020ed8SCatalin Marinas if (regs->sp & 15) 5472c020ed8SCatalin Marinas goto badframe; 5482c020ed8SCatalin Marinas 5492c020ed8SCatalin Marinas frame = (struct rt_sigframe __user *)regs->sp; 5502c020ed8SCatalin Marinas 55196d4f267SLinus Torvalds if (!access_ok(frame, sizeof (*frame))) 5522c020ed8SCatalin Marinas goto badframe; 5532c020ed8SCatalin Marinas 5542c020ed8SCatalin Marinas if (restore_sigframe(regs, frame)) 5552c020ed8SCatalin Marinas goto badframe; 5562c020ed8SCatalin Marinas 557207bdae4SAl Viro if (restore_altstack(&frame->uc.uc_stack)) 5582c020ed8SCatalin Marinas goto badframe; 5592c020ed8SCatalin Marinas 5602c020ed8SCatalin Marinas return regs->regs[0]; 5612c020ed8SCatalin Marinas 5622c020ed8SCatalin Marinas badframe: 563f71016a8SWill Deacon arm64_notify_segfault(regs->sp); 5642c020ed8SCatalin Marinas return 0; 5652c020ed8SCatalin Marinas } 5662c020ed8SCatalin Marinas 56794b07c1fSDave Martin /* 56894b07c1fSDave Martin * Determine the layout of optional records in the signal frame 56994b07c1fSDave Martin * 57094b07c1fSDave Martin * add_all: if true, lays out the biggest possible signal frame for 57194b07c1fSDave Martin * this task; otherwise, generates a layout for the current state 57294b07c1fSDave Martin * of the task. 57394b07c1fSDave Martin */ 57494b07c1fSDave Martin static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, 57594b07c1fSDave Martin bool add_all) 576bb4891a6SDave Martin { 577bb4322f7SDave Martin int err; 578bb4322f7SDave Martin 5790a32c88dSDavid Engraf if (system_supports_fpsimd()) { 580bb4322f7SDave Martin err = sigframe_alloc(user, &user->fpsimd_offset, 581bb4322f7SDave Martin sizeof(struct fpsimd_context)); 582bb4322f7SDave Martin if (err) 583bb4322f7SDave Martin return err; 5840a32c88dSDavid Engraf } 585bb4891a6SDave Martin 586bb4891a6SDave Martin /* fault information, if valid */ 58794b07c1fSDave Martin if (add_all || current->thread.fault_code) { 588bb4322f7SDave Martin err = sigframe_alloc(user, &user->esr_offset, 589bb4322f7SDave Martin sizeof(struct esr_context)); 590bb4322f7SDave Martin if (err) 591bb4322f7SDave Martin return err; 592bb4891a6SDave Martin } 593bb4891a6SDave Martin 5948cd969d2SDave Martin if (system_supports_sve()) { 5958cd969d2SDave Martin unsigned int vq = 0; 5968cd969d2SDave Martin 59794b07c1fSDave Martin if (add_all || test_thread_flag(TIF_SVE)) { 598b5bc00ffSMark Brown int vl = sve_max_vl(); 59994b07c1fSDave Martin 60094b07c1fSDave Martin if (!add_all) 6010423eedcSMark Brown vl = task_get_sve_vl(current); 60294b07c1fSDave Martin 60394b07c1fSDave Martin vq = sve_vq_from_vl(vl); 60494b07c1fSDave Martin } 6058cd969d2SDave Martin 6068cd969d2SDave Martin err = sigframe_alloc(user, &user->sve_offset, 6078cd969d2SDave Martin SVE_SIG_CONTEXT_SIZE(vq)); 6088cd969d2SDave Martin if (err) 6098cd969d2SDave Martin return err; 6108cd969d2SDave Martin } 6118cd969d2SDave Martin 61233f08261SDave Martin return sigframe_alloc_end(user); 613bb4891a6SDave Martin } 614bb4891a6SDave Martin 61520987de3SDave Martin static int setup_sigframe(struct rt_sigframe_user_layout *user, 6162c020ed8SCatalin Marinas struct pt_regs *regs, sigset_t *set) 6172c020ed8SCatalin Marinas { 6182c020ed8SCatalin Marinas int i, err = 0; 61920987de3SDave Martin struct rt_sigframe __user *sf = user->sigframe; 6202c020ed8SCatalin Marinas 621304ef4e8SWill Deacon /* set up the stack frame for unwinding */ 62220987de3SDave Martin __put_user_error(regs->regs[29], &user->next_frame->fp, err); 62320987de3SDave Martin __put_user_error(regs->regs[30], &user->next_frame->lr, err); 624304ef4e8SWill Deacon 6252c020ed8SCatalin Marinas for (i = 0; i < 31; i++) 6262c020ed8SCatalin Marinas __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], 6272c020ed8SCatalin Marinas err); 6282c020ed8SCatalin Marinas __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); 6292c020ed8SCatalin Marinas __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); 6302c020ed8SCatalin Marinas __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); 6312c020ed8SCatalin Marinas 6322c020ed8SCatalin Marinas __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); 6332c020ed8SCatalin Marinas 6342c020ed8SCatalin Marinas err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); 6352c020ed8SCatalin Marinas 6366d502b6bSSuzuki K Poulose if (err == 0 && system_supports_fpsimd()) { 637bb4891a6SDave Martin struct fpsimd_context __user *fpsimd_ctx = 638bb4891a6SDave Martin apply_user_offset(user, user->fpsimd_offset); 6390e0276d1SCatalin Marinas err |= preserve_fpsimd_context(fpsimd_ctx); 6400e0276d1SCatalin Marinas } 6412c020ed8SCatalin Marinas 64215af1942SCatalin Marinas /* fault information, if valid */ 643bb4891a6SDave Martin if (err == 0 && user->esr_offset) { 644bb4891a6SDave Martin struct esr_context __user *esr_ctx = 645bb4891a6SDave Martin apply_user_offset(user, user->esr_offset); 646bb4891a6SDave Martin 64715af1942SCatalin Marinas __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); 64815af1942SCatalin Marinas __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); 64915af1942SCatalin Marinas __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); 65015af1942SCatalin Marinas } 65115af1942SCatalin Marinas 6528cd969d2SDave Martin /* Scalable Vector Extension state, if present */ 6538cd969d2SDave Martin if (system_supports_sve() && err == 0 && user->sve_offset) { 6548cd969d2SDave Martin struct sve_context __user *sve_ctx = 6558cd969d2SDave Martin apply_user_offset(user, user->sve_offset); 6568cd969d2SDave Martin err |= preserve_sve_context(sve_ctx); 6578cd969d2SDave Martin } 6588cd969d2SDave Martin 65933f08261SDave Martin if (err == 0 && user->extra_offset) { 66033f08261SDave Martin char __user *sfp = (char __user *)user->sigframe; 66133f08261SDave Martin char __user *userp = 66233f08261SDave Martin apply_user_offset(user, user->extra_offset); 66333f08261SDave Martin 66433f08261SDave Martin struct extra_context __user *extra; 66533f08261SDave Martin struct _aarch64_ctx __user *end; 66633f08261SDave Martin u64 extra_datap; 66733f08261SDave Martin u32 extra_size; 66833f08261SDave Martin 66933f08261SDave Martin extra = (struct extra_context __user *)userp; 67033f08261SDave Martin userp += EXTRA_CONTEXT_SIZE; 67133f08261SDave Martin 67233f08261SDave Martin end = (struct _aarch64_ctx __user *)userp; 67333f08261SDave Martin userp += TERMINATOR_SIZE; 67433f08261SDave Martin 67533f08261SDave Martin /* 67633f08261SDave Martin * extra_datap is just written to the signal frame. 67733f08261SDave Martin * The value gets cast back to a void __user * 67833f08261SDave Martin * during sigreturn. 67933f08261SDave Martin */ 68033f08261SDave Martin extra_datap = (__force u64)userp; 68133f08261SDave Martin extra_size = sfp + round_up(user->size, 16) - userp; 68233f08261SDave Martin 68333f08261SDave Martin __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); 68433f08261SDave Martin __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); 68533f08261SDave Martin __put_user_error(extra_datap, &extra->datap, err); 68633f08261SDave Martin __put_user_error(extra_size, &extra->size, err); 68733f08261SDave Martin 68833f08261SDave Martin /* Add the terminator */ 68933f08261SDave Martin __put_user_error(0, &end->magic, err); 69033f08261SDave Martin __put_user_error(0, &end->size, err); 69133f08261SDave Martin } 69233f08261SDave Martin 6932c020ed8SCatalin Marinas /* set the "end" magic */ 694bb4891a6SDave Martin if (err == 0) { 695bb4891a6SDave Martin struct _aarch64_ctx __user *end = 696bb4891a6SDave Martin apply_user_offset(user, user->end_offset); 697bb4891a6SDave Martin 6980e0276d1SCatalin Marinas __put_user_error(0, &end->magic, err); 6990e0276d1SCatalin Marinas __put_user_error(0, &end->size, err); 700bb4891a6SDave Martin } 7012c020ed8SCatalin Marinas 7022c020ed8SCatalin Marinas return err; 7032c020ed8SCatalin Marinas } 7042c020ed8SCatalin Marinas 70520987de3SDave Martin static int get_sigframe(struct rt_sigframe_user_layout *user, 70620987de3SDave Martin struct ksignal *ksig, struct pt_regs *regs) 7072c020ed8SCatalin Marinas { 7082c020ed8SCatalin Marinas unsigned long sp, sp_top; 709bb4891a6SDave Martin int err; 710bb4891a6SDave Martin 711bb4891a6SDave Martin init_user_layout(user); 71294b07c1fSDave Martin err = setup_sigframe_layout(user, false); 713bb4891a6SDave Martin if (err) 714bb4891a6SDave Martin return err; 7152c020ed8SCatalin Marinas 71638a7be3cSRichard Weinberger sp = sp_top = sigsp(regs->sp, ksig); 7172c020ed8SCatalin Marinas 71820987de3SDave Martin sp = round_down(sp - sizeof(struct frame_record), 16); 71920987de3SDave Martin user->next_frame = (struct frame_record __user *)sp; 72020987de3SDave Martin 721bb4891a6SDave Martin sp = round_down(sp, 16) - sigframe_size(user); 72220987de3SDave Martin user->sigframe = (struct rt_sigframe __user *)sp; 7232c020ed8SCatalin Marinas 7242c020ed8SCatalin Marinas /* 7252c020ed8SCatalin Marinas * Check that we can actually write to the signal frame. 7262c020ed8SCatalin Marinas */ 72796d4f267SLinus Torvalds if (!access_ok(user->sigframe, sp_top - sp)) 72820987de3SDave Martin return -EFAULT; 7292c020ed8SCatalin Marinas 73020987de3SDave Martin return 0; 7312c020ed8SCatalin Marinas } 7322c020ed8SCatalin Marinas 733304ef4e8SWill Deacon static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, 73420987de3SDave Martin struct rt_sigframe_user_layout *user, int usig) 7352c020ed8SCatalin Marinas { 7362c020ed8SCatalin Marinas __sigrestore_t sigtramp; 7372c020ed8SCatalin Marinas 7382c020ed8SCatalin Marinas regs->regs[0] = usig; 73920987de3SDave Martin regs->sp = (unsigned long)user->sigframe; 74020987de3SDave Martin regs->regs[29] = (unsigned long)&user->next_frame->fp; 7412c020ed8SCatalin Marinas regs->pc = (unsigned long)ka->sa.sa_handler; 7422c020ed8SCatalin Marinas 7438ef8f360SDave Martin /* 7448ef8f360SDave Martin * Signal delivery is a (wacky) indirect function call in 7458ef8f360SDave Martin * userspace, so simulate the same setting of BTYPE as a BLR 7468ef8f360SDave Martin * <register containing the signal handler entry point>. 7478ef8f360SDave Martin * Signal delivery to a location in a PROT_BTI guarded page 7488ef8f360SDave Martin * that is not a function entry point will now trigger a 7498ef8f360SDave Martin * SIGILL in userspace. 7508ef8f360SDave Martin * 7518ef8f360SDave Martin * If the signal handler entry point is not in a PROT_BTI 7528ef8f360SDave Martin * guarded page, this is harmless. 7538ef8f360SDave Martin */ 7548ef8f360SDave Martin if (system_supports_bti()) { 7558ef8f360SDave Martin regs->pstate &= ~PSR_BTYPE_MASK; 7568ef8f360SDave Martin regs->pstate |= PSR_BTYPE_C; 7578ef8f360SDave Martin } 7588ef8f360SDave Martin 759637ec831SVincenzo Frascino /* TCO (Tag Check Override) always cleared for signal handlers */ 760637ec831SVincenzo Frascino regs->pstate &= ~PSR_TCO_BIT; 761637ec831SVincenzo Frascino 7622c020ed8SCatalin Marinas if (ka->sa.sa_flags & SA_RESTORER) 7632c020ed8SCatalin Marinas sigtramp = ka->sa.sa_restorer; 7642c020ed8SCatalin Marinas else 7652c020ed8SCatalin Marinas sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); 7662c020ed8SCatalin Marinas 7672c020ed8SCatalin Marinas regs->regs[30] = (unsigned long)sigtramp; 7682c020ed8SCatalin Marinas } 7692c020ed8SCatalin Marinas 77000554fa4SRichard Weinberger static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, 77100554fa4SRichard Weinberger struct pt_regs *regs) 7722c020ed8SCatalin Marinas { 77320987de3SDave Martin struct rt_sigframe_user_layout user; 7742c020ed8SCatalin Marinas struct rt_sigframe __user *frame; 7752c020ed8SCatalin Marinas int err = 0; 7762c020ed8SCatalin Marinas 7778cd969d2SDave Martin fpsimd_signal_preserve_current_state(); 7788cd969d2SDave Martin 77920987de3SDave Martin if (get_sigframe(&user, ksig, regs)) 7802c020ed8SCatalin Marinas return 1; 7812c020ed8SCatalin Marinas 78220987de3SDave Martin frame = user.sigframe; 78320987de3SDave Martin 7842c020ed8SCatalin Marinas __put_user_error(0, &frame->uc.uc_flags, err); 7852c020ed8SCatalin Marinas __put_user_error(NULL, &frame->uc.uc_link, err); 7862c020ed8SCatalin Marinas 787207bdae4SAl Viro err |= __save_altstack(&frame->uc.uc_stack, regs->sp); 78820987de3SDave Martin err |= setup_sigframe(&user, regs, set); 789304ef4e8SWill Deacon if (err == 0) { 79020987de3SDave Martin setup_return(regs, &ksig->ka, &user, usig); 79100554fa4SRichard Weinberger if (ksig->ka.sa.sa_flags & SA_SIGINFO) { 79200554fa4SRichard Weinberger err |= copy_siginfo_to_user(&frame->info, &ksig->info); 7932c020ed8SCatalin Marinas regs->regs[1] = (unsigned long)&frame->info; 7942c020ed8SCatalin Marinas regs->regs[2] = (unsigned long)&frame->uc; 7952c020ed8SCatalin Marinas } 796304ef4e8SWill Deacon } 7972c020ed8SCatalin Marinas 7982c020ed8SCatalin Marinas return err; 7992c020ed8SCatalin Marinas } 8002c020ed8SCatalin Marinas 8012c020ed8SCatalin Marinas static void setup_restart_syscall(struct pt_regs *regs) 8022c020ed8SCatalin Marinas { 8032c020ed8SCatalin Marinas if (is_compat_task()) 8042c020ed8SCatalin Marinas compat_setup_restart_syscall(regs); 8052c020ed8SCatalin Marinas else 8062c020ed8SCatalin Marinas regs->regs[8] = __NR_restart_syscall; 8072c020ed8SCatalin Marinas } 8082c020ed8SCatalin Marinas 8092c020ed8SCatalin Marinas /* 8102c020ed8SCatalin Marinas * OK, we're invoking a handler 8112c020ed8SCatalin Marinas */ 81200554fa4SRichard Weinberger static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 8132c020ed8SCatalin Marinas { 8142c020ed8SCatalin Marinas sigset_t *oldset = sigmask_to_save(); 81500554fa4SRichard Weinberger int usig = ksig->sig; 8162c020ed8SCatalin Marinas int ret; 8172c020ed8SCatalin Marinas 818409d5db4SWill Deacon rseq_signal_deliver(ksig, regs); 819409d5db4SWill Deacon 8202c020ed8SCatalin Marinas /* 8212c020ed8SCatalin Marinas * Set up the stack frame 8222c020ed8SCatalin Marinas */ 8232c020ed8SCatalin Marinas if (is_compat_task()) { 82400554fa4SRichard Weinberger if (ksig->ka.sa.sa_flags & SA_SIGINFO) 82500554fa4SRichard Weinberger ret = compat_setup_rt_frame(usig, ksig, oldset, regs); 8262c020ed8SCatalin Marinas else 82700554fa4SRichard Weinberger ret = compat_setup_frame(usig, ksig, oldset, regs); 8282c020ed8SCatalin Marinas } else { 82900554fa4SRichard Weinberger ret = setup_rt_frame(usig, ksig, oldset, regs); 8302c020ed8SCatalin Marinas } 8312c020ed8SCatalin Marinas 8322c020ed8SCatalin Marinas /* 8332c020ed8SCatalin Marinas * Check that the resulting registers are actually sane. 8342c020ed8SCatalin Marinas */ 835dbd4d7caSMark Rutland ret |= !valid_user_regs(®s->user_regs, current); 8362c020ed8SCatalin Marinas 837ac2081cdSWill Deacon /* Step into the signal handler if we are stepping */ 838ac2081cdSWill Deacon signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); 8392c020ed8SCatalin Marinas } 8402c020ed8SCatalin Marinas 8412c020ed8SCatalin Marinas /* 8422c020ed8SCatalin Marinas * Note that 'init' is a special process: it doesn't get signals it doesn't 8432c020ed8SCatalin Marinas * want to handle. Thus you cannot kill init even with a SIGKILL even by 8442c020ed8SCatalin Marinas * mistake. 8452c020ed8SCatalin Marinas * 8462c020ed8SCatalin Marinas * Note that we go through the signals twice: once to check the signals that 8472c020ed8SCatalin Marinas * the kernel can handle, and then we build all the user-level signal handling 8482c020ed8SCatalin Marinas * stack-frames in one go after that. 8492c020ed8SCatalin Marinas */ 8502c020ed8SCatalin Marinas static void do_signal(struct pt_regs *regs) 8512c020ed8SCatalin Marinas { 8522c020ed8SCatalin Marinas unsigned long continue_addr = 0, restart_addr = 0; 85300554fa4SRichard Weinberger int retval = 0; 85400554fa4SRichard Weinberger struct ksignal ksig; 8550fe42512SDave Martin bool syscall = in_syscall(regs); 8562c020ed8SCatalin Marinas 8572c020ed8SCatalin Marinas /* 8582c020ed8SCatalin Marinas * If we were from a system call, check for system call restarting... 8592c020ed8SCatalin Marinas */ 8600fe42512SDave Martin if (syscall) { 8612c020ed8SCatalin Marinas continue_addr = regs->pc; 8622c020ed8SCatalin Marinas restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); 8632c020ed8SCatalin Marinas retval = regs->regs[0]; 8642c020ed8SCatalin Marinas 8652c020ed8SCatalin Marinas /* 8662c020ed8SCatalin Marinas * Avoid additional syscall restarting via ret_to_user. 8672c020ed8SCatalin Marinas */ 86817c28958SDave Martin forget_syscall(regs); 8692c020ed8SCatalin Marinas 8702c020ed8SCatalin Marinas /* 8712c020ed8SCatalin Marinas * Prepare for system call restart. We do this here so that a 8722c020ed8SCatalin Marinas * debugger will see the already changed PC. 8732c020ed8SCatalin Marinas */ 8742c020ed8SCatalin Marinas switch (retval) { 8752c020ed8SCatalin Marinas case -ERESTARTNOHAND: 8762c020ed8SCatalin Marinas case -ERESTARTSYS: 8772c020ed8SCatalin Marinas case -ERESTARTNOINTR: 8782c020ed8SCatalin Marinas case -ERESTART_RESTARTBLOCK: 8792c020ed8SCatalin Marinas regs->regs[0] = regs->orig_x0; 8802c020ed8SCatalin Marinas regs->pc = restart_addr; 8812c020ed8SCatalin Marinas break; 8822c020ed8SCatalin Marinas } 8832c020ed8SCatalin Marinas } 8842c020ed8SCatalin Marinas 8852c020ed8SCatalin Marinas /* 8862c020ed8SCatalin Marinas * Get the signal to deliver. When running under ptrace, at this point 8872c020ed8SCatalin Marinas * the debugger may change all of our registers. 8882c020ed8SCatalin Marinas */ 88900554fa4SRichard Weinberger if (get_signal(&ksig)) { 8902c020ed8SCatalin Marinas /* 8912c020ed8SCatalin Marinas * Depending on the signal settings, we may need to revert the 8922c020ed8SCatalin Marinas * decision to restart the system call, but skip this if a 8932c020ed8SCatalin Marinas * debugger has chosen to restart at a different PC. 8942c020ed8SCatalin Marinas */ 8952c020ed8SCatalin Marinas if (regs->pc == restart_addr && 8962c020ed8SCatalin Marinas (retval == -ERESTARTNOHAND || 8972c020ed8SCatalin Marinas retval == -ERESTART_RESTARTBLOCK || 8982c020ed8SCatalin Marinas (retval == -ERESTARTSYS && 89900554fa4SRichard Weinberger !(ksig.ka.sa.sa_flags & SA_RESTART)))) { 900e30e8d46SMark Rutland syscall_set_return_value(current, regs, -EINTR, 0); 9012c020ed8SCatalin Marinas regs->pc = continue_addr; 9022c020ed8SCatalin Marinas } 9032c020ed8SCatalin Marinas 90400554fa4SRichard Weinberger handle_signal(&ksig, regs); 9052c020ed8SCatalin Marinas return; 9062c020ed8SCatalin Marinas } 9072c020ed8SCatalin Marinas 9082c020ed8SCatalin Marinas /* 9092c020ed8SCatalin Marinas * Handle restarting a different system call. As above, if a debugger 9102c020ed8SCatalin Marinas * has chosen to restart at a different PC, ignore the restart. 9112c020ed8SCatalin Marinas */ 9120fe42512SDave Martin if (syscall && regs->pc == restart_addr) { 9132c020ed8SCatalin Marinas if (retval == -ERESTART_RESTARTBLOCK) 9142c020ed8SCatalin Marinas setup_restart_syscall(regs); 9152c020ed8SCatalin Marinas user_rewind_single_step(current); 9162c020ed8SCatalin Marinas } 9172c020ed8SCatalin Marinas 9182c020ed8SCatalin Marinas restore_saved_sigmask(); 9192c020ed8SCatalin Marinas } 9202c020ed8SCatalin Marinas 9214d1c2ee2SMark Rutland void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) 9222c020ed8SCatalin Marinas { 923a2048e34SThomas Garnier do { 924421dd6faSChris Metcalf if (thread_flags & _TIF_NEED_RESCHED) { 9258d66772eSJames Morse /* Unmask Debug and SError for the next task */ 9268d66772eSJames Morse local_daif_restore(DAIF_PROCCTX_NOIRQ); 9278d66772eSJames Morse 928421dd6faSChris Metcalf schedule(); 929421dd6faSChris Metcalf } else { 9308d66772eSJames Morse local_daif_restore(DAIF_PROCCTX); 931421dd6faSChris Metcalf 9329842ceaeSPratyush Anand if (thread_flags & _TIF_UPROBE) 9339842ceaeSPratyush Anand uprobe_notify_resume(regs); 9349842ceaeSPratyush Anand 935637ec831SVincenzo Frascino if (thread_flags & _TIF_MTE_ASYNC_FAULT) { 936637ec831SVincenzo Frascino clear_thread_flag(TIF_MTE_ASYNC_FAULT); 937637ec831SVincenzo Frascino send_sig_fault(SIGSEGV, SEGV_MTEAERR, 938637ec831SVincenzo Frascino (void __user *)NULL, current); 939637ec831SVincenzo Frascino } 940637ec831SVincenzo Frascino 941192caabdSJens Axboe if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) 9422c020ed8SCatalin Marinas do_signal(regs); 9432c020ed8SCatalin Marinas 944a68de80fSSean Christopherson if (thread_flags & _TIF_NOTIFY_RESUME) 94503248addSEric W. Biederman resume_user_mode_work(regs); 946005f78cdSArd Biesheuvel 947005f78cdSArd Biesheuvel if (thread_flags & _TIF_FOREIGN_FPSTATE) 948005f78cdSArd Biesheuvel fpsimd_restore_current_state(); 949421dd6faSChris Metcalf } 950005f78cdSArd Biesheuvel 9518d66772eSJames Morse local_daif_mask(); 952342b3808SMark Rutland thread_flags = read_thread_flags(); 953421dd6faSChris Metcalf } while (thread_flags & _TIF_WORK_MASK); 9542c020ed8SCatalin Marinas } 95594b07c1fSDave Martin 95694b07c1fSDave Martin unsigned long __ro_after_init signal_minsigstksz; 95794b07c1fSDave Martin 95894b07c1fSDave Martin /* 95994b07c1fSDave Martin * Determine the stack space required for guaranteed signal devliery. 96094b07c1fSDave Martin * This function is used to populate AT_MINSIGSTKSZ at process startup. 96194b07c1fSDave Martin * cpufeatures setup is assumed to be complete. 96294b07c1fSDave Martin */ 96394b07c1fSDave Martin void __init minsigstksz_setup(void) 96494b07c1fSDave Martin { 96594b07c1fSDave Martin struct rt_sigframe_user_layout user; 96694b07c1fSDave Martin 96794b07c1fSDave Martin init_user_layout(&user); 96894b07c1fSDave Martin 96994b07c1fSDave Martin /* 97094b07c1fSDave Martin * If this fails, SIGFRAME_MAXSZ needs to be enlarged. It won't 97194b07c1fSDave Martin * be big enough, but it's our best guess: 97294b07c1fSDave Martin */ 97394b07c1fSDave Martin if (WARN_ON(setup_sigframe_layout(&user, true))) 97494b07c1fSDave Martin return; 97594b07c1fSDave Martin 97694b07c1fSDave Martin signal_minsigstksz = sigframe_size(&user) + 97794b07c1fSDave Martin round_up(sizeof(struct frame_record), 16) + 97894b07c1fSDave Martin 16; /* max alignment padding */ 97994b07c1fSDave Martin } 980726e337bSMarco Elver 981726e337bSMarco Elver /* 982726e337bSMarco Elver * Compile-time assertions for siginfo_t offsets. Check NSIG* as well, as 983726e337bSMarco Elver * changes likely come with new fields that should be added below. 984726e337bSMarco Elver */ 985726e337bSMarco Elver static_assert(NSIGILL == 11); 986726e337bSMarco Elver static_assert(NSIGFPE == 15); 987726e337bSMarco Elver static_assert(NSIGSEGV == 9); 988726e337bSMarco Elver static_assert(NSIGBUS == 5); 989726e337bSMarco Elver static_assert(NSIGTRAP == 6); 990726e337bSMarco Elver static_assert(NSIGCHLD == 6); 991726e337bSMarco Elver static_assert(NSIGSYS == 2); 99250ae8130SEric W. Biederman static_assert(sizeof(siginfo_t) == 128); 99350ae8130SEric W. Biederman static_assert(__alignof__(siginfo_t) == 8); 994726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_signo) == 0x00); 995726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_errno) == 0x04); 996726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_code) == 0x08); 997726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_pid) == 0x10); 998726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_uid) == 0x14); 999726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_tid) == 0x10); 1000726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_overrun) == 0x14); 1001726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_status) == 0x18); 1002726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_utime) == 0x20); 1003726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_stime) == 0x28); 1004726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_value) == 0x18); 1005726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_int) == 0x18); 1006726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_ptr) == 0x18); 1007726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_addr) == 0x10); 1008726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18); 1009726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_lower) == 0x20); 1010726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_upper) == 0x28); 1011726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_pkey) == 0x20); 1012726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_perf_data) == 0x18); 1013726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_perf_type) == 0x20); 1014*78ed93d7SMarco Elver static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24); 1015726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_band) == 0x10); 1016726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_fd) == 0x18); 1017726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_call_addr) == 0x10); 1018726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_syscall) == 0x18); 1019726e337bSMarco Elver static_assert(offsetof(siginfo_t, si_arch) == 0x1c); 1020