^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Based on arch/arm/kernel/signal.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1995-2009 Russell King
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2012 ARM Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Modified by Will Deacon <will.deacon@arm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/esr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/fpsimd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/signal32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/vdso.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct compat_vfp_sigframe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) compat_ulong_t magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) compat_ulong_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct compat_user_vfp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) compat_u64 fpregs[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) compat_ulong_t fpscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) } ufp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct compat_user_vfp_exc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) compat_ulong_t fpexc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) compat_ulong_t fpinst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) compat_ulong_t fpinst2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) } ufp_exc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) } __attribute__((__aligned__(8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define VFP_MAGIC 0x56465001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FSR_WRITE_SHIFT (11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct compat_aux_sigframe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct compat_vfp_sigframe vfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Something that isn't a valid magic number for any coprocessor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned long end_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } __attribute__((__aligned__(8)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) compat_sigset_t cset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) cset.sig[0] = set->sig[0] & 0xffffffffull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) cset.sig[1] = set->sig[0] >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return copy_to_user(uset, &cset, sizeof(*uset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static inline int get_sigset_t(sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) const compat_sigset_t __user *uset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) compat_sigset_t s32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (copy_from_user(&s32, uset, sizeof(*uset)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * VFP save/restore code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * We have to be careful with endianness, since the fpsimd context-switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * code operates on 128-bit (Q) register values whereas the compat ABI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * uses an array of 64-bit (D) registers. Consequently, we need to swap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * the two halves of each Q register when running on a big-endian CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) union __fpsimd_vreg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __uint128_t raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #ifdef __AARCH64EB__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u64 hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u64 lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u64 lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u64 hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct user_fpsimd_state const *fpsimd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ¤t->thread.uw.fpsimd_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) compat_ulong_t magic = VFP_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) compat_ulong_t size = VFP_STORAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) compat_ulong_t fpscr, fpexc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * Save the hardware registers to the fpsimd_state structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Note that this also saves V16-31, which aren't visible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * in AArch32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) fpsimd_signal_preserve_current_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Place structure header on the stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) __put_user_error(magic, &frame->magic, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) __put_user_error(size, &frame->size, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Now copy the FP registers. Since the registers are packed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * we can copy the prefix we want (V0-V15) as it is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) union __fpsimd_vreg vreg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .raw = fpsimd->vregs[i >> 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) __put_user_error(vreg.lo, &frame->ufp.fpregs[i], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __put_user_error(vreg.hi, &frame->ufp.fpregs[i + 1], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Create an AArch32 fpscr from the fpsr and the fpcr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) fpscr = (fpsimd->fpsr & VFP_FPSCR_STAT_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) (fpsimd->fpcr & VFP_FPSCR_CTRL_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) __put_user_error(fpscr, &frame->ufp.fpscr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * The exception register aren't available so we fake up a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * basic FPEXC and zero everything else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) fpexc = (1 << 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) __put_user_error(fpexc, &frame->ufp_exc.fpexc, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) __put_user_error(0, &frame->ufp_exc.fpinst, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) __put_user_error(0, &frame->ufp_exc.fpinst2, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return err ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int compat_restore_vfp_context(struct compat_vfp_sigframe __user *frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct user_fpsimd_state fpsimd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) compat_ulong_t magic = VFP_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) compat_ulong_t size = VFP_STORAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) compat_ulong_t fpscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) __get_user_error(magic, &frame->magic, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) __get_user_error(size, &frame->size, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Copy the FP registers into the start of the fpsimd_state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) for (i = 0; i < ARRAY_SIZE(frame->ufp.fpregs); i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) union __fpsimd_vreg vreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __get_user_error(vreg.lo, &frame->ufp.fpregs[i], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) __get_user_error(vreg.hi, &frame->ufp.fpregs[i + 1], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fpsimd.vregs[i >> 1] = vreg.raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Extract the fpsr and the fpcr from the fpscr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) __get_user_error(fpscr, &frame->ufp.fpscr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) fpsimd.fpsr = fpscr & VFP_FPSCR_STAT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fpsimd.fpcr = fpscr & VFP_FPSCR_CTRL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * We don't need to touch the exception register, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * reload the hardware state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) fpsimd_update_current_state(&fpsimd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return err ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int compat_restore_sigframe(struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct compat_sigframe __user *sf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sigset_t set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct compat_aux_sigframe __user *aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) unsigned long psr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) err = get_sigset_t(&set, &sf->uc.uc_sigmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) sigdelsetmask(&set, ~_BLOCKABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) set_current_blocked(&set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) __get_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __get_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) __get_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __get_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) __get_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) __get_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) __get_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) __get_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) __get_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) __get_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) __get_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) __get_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) __get_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) __get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) __get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) __get_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) regs->pstate = compat_psr_to_pstate(psr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Avoid compat_sys_sigreturn() restarting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) forget_syscall(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) err |= !valid_user_regs(®s->user_regs, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (err == 0 && system_supports_fpsimd())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) err |= compat_restore_vfp_context(&aux->vfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) COMPAT_SYSCALL_DEFINE0(sigreturn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct compat_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Since we stacked the signal on a 64-bit boundary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * then 'sp' should be word aligned here. If it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * not, then the user is trying to mess with us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (regs->compat_sp & 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) frame = (struct compat_sigframe __user *)regs->compat_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!access_ok(frame, sizeof (*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (compat_restore_sigframe(regs, frame))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return regs->regs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) arm64_notify_segfault(regs->compat_sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct pt_regs *regs = current_pt_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct compat_rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* Always make any pending restarted system calls return -EINTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) current->restart_block.fn = do_no_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Since we stacked the signal on a 64-bit boundary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * then 'sp' should be word aligned here. If it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * not, then the user is trying to mess with us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (regs->compat_sp & 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) frame = (struct compat_rt_sigframe __user *)regs->compat_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (!access_ok(frame, sizeof (*frame)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (compat_restore_sigframe(regs, &frame->sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (compat_restore_altstack(&frame->sig.uc.uc_stack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) goto badframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return regs->regs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) badframe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) arm64_notify_segfault(regs->compat_sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void __user *compat_get_sigframe(struct ksignal *ksig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int framesize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) compat_ulong_t sp = sigsp(regs->compat_sp, ksig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) void __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * ATPCS B01 mandates 8-byte alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) frame = compat_ptr((compat_uptr_t)((sp - framesize) & ~7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Check that we can actually write to the signal frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (!access_ok(frame, framesize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) frame = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) compat_ulong_t __user *rc, void __user *frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int usig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) compat_ulong_t retcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) compat_ulong_t spsr = regs->pstate & ~(PSR_f | PSR_AA32_E_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int thumb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* Check if the handler is written for ARM or Thumb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) thumb = handler & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (thumb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) spsr |= PSR_AA32_T_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) spsr &= ~PSR_AA32_T_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* The IT state must be cleared for both ARM and Thumb-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) spsr &= ~PSR_AA32_IT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* Restore the original endianness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) spsr |= PSR_AA32_ENDSTATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ka->sa.sa_flags & SA_RESTORER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) retcode = ptr_to_compat(ka->sa.sa_restorer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* Set up sigreturn pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) unsigned int idx = thumb << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ka->sa.sa_flags & SA_SIGINFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) idx += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) retcode = (unsigned long)current->mm->context.sigpage +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) (idx << 2) + thumb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) regs->regs[0] = usig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) regs->compat_sp = ptr_to_compat(frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) regs->compat_lr = retcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) regs->pc = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regs->pstate = spsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int compat_setup_sigframe(struct compat_sigframe __user *sf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct pt_regs *regs, sigset_t *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct compat_aux_sigframe __user *aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned long psr = pstate_to_compat_psr(regs->pstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) __put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) __put_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) __put_user_error(regs->regs[2], &sf->uc.uc_mcontext.arm_r2, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) __put_user_error(regs->regs[3], &sf->uc.uc_mcontext.arm_r3, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) __put_user_error(regs->regs[4], &sf->uc.uc_mcontext.arm_r4, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) __put_user_error(regs->regs[5], &sf->uc.uc_mcontext.arm_r5, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) __put_user_error(regs->regs[6], &sf->uc.uc_mcontext.arm_r6, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) __put_user_error(regs->regs[7], &sf->uc.uc_mcontext.arm_r7, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) __put_user_error(regs->regs[8], &sf->uc.uc_mcontext.arm_r8, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) __put_user_error(regs->regs[9], &sf->uc.uc_mcontext.arm_r9, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) __put_user_error(regs->regs[10], &sf->uc.uc_mcontext.arm_r10, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) __put_user_error(regs->regs[11], &sf->uc.uc_mcontext.arm_fp, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) __put_user_error(regs->regs[12], &sf->uc.uc_mcontext.arm_ip, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) __put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) __put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) __put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) __put_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* set the compat FSR WnR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) __put_user_error(!!(current->thread.fault_code & ESR_ELx_WNR) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) FSR_WRITE_SHIFT, &sf->uc.uc_mcontext.error_code, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) err |= put_sigset_t(&sf->uc.uc_sigmask, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (err == 0 && system_supports_fpsimd())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) err |= compat_preserve_vfp_context(&aux->vfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) __put_user_error(0, &aux->end_magic, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * 32-bit signal handling routines called from signal.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int compat_setup_rt_frame(int usig, struct ksignal *ksig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) sigset_t *set, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct compat_rt_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) __put_user_error(0, &frame->sig.uc.uc_flags, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) __put_user_error(0, &frame->sig.uc.uc_link, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) err |= __compat_save_altstack(&frame->sig.uc.uc_stack, regs->compat_sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) err |= compat_setup_sigframe(&frame->sig, regs, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) compat_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct compat_sigframe __user *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) err |= compat_setup_sigframe(frame, regs, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) compat_setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) void compat_setup_restart_syscall(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) regs->regs[7] = __NR_compat_restart_syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }