1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2012 ARM Ltd. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify 6*4882a593Smuzhiyun * it under the terms of the GNU General Public License version 2 as 7*4882a593Smuzhiyun * published by the Free Software Foundation. 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 10*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 11*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*4882a593Smuzhiyun * GNU General Public License for more details. 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License 15*4882a593Smuzhiyun * along with this program. If not, see <http://www.gnu.org/licenses/>. 16*4882a593Smuzhiyun */ 17*4882a593Smuzhiyun #ifndef _UAPI__ASM_SIGCONTEXT_H 18*4882a593Smuzhiyun #define _UAPI__ASM_SIGCONTEXT_H 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun #include <linux/types.h> 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun /* 25*4882a593Smuzhiyun * Signal context structure - contains all info to do with the state 26*4882a593Smuzhiyun * before the signal handler was invoked. 27*4882a593Smuzhiyun */ 28*4882a593Smuzhiyun struct sigcontext { 29*4882a593Smuzhiyun __u64 fault_address; 30*4882a593Smuzhiyun /* AArch64 registers */ 31*4882a593Smuzhiyun __u64 regs[31]; 32*4882a593Smuzhiyun __u64 sp; 33*4882a593Smuzhiyun __u64 pc; 34*4882a593Smuzhiyun __u64 pstate; 35*4882a593Smuzhiyun /* 4K reserved for FP/SIMD state and future expansion */ 36*4882a593Smuzhiyun __u8 __reserved[4096] __attribute__((__aligned__(16))); 37*4882a593Smuzhiyun }; 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /* 40*4882a593Smuzhiyun * Allocation of __reserved[]: 41*4882a593Smuzhiyun * (Note: records do not necessarily occur in the order shown here.) 42*4882a593Smuzhiyun * 43*4882a593Smuzhiyun * size description 44*4882a593Smuzhiyun * 45*4882a593Smuzhiyun * 0x210 fpsimd_context 46*4882a593Smuzhiyun * 0x10 esr_context 47*4882a593Smuzhiyun * 0x8a0 sve_context (vl <= 64) (optional) 48*4882a593Smuzhiyun * 0x20 extra_context (optional) 49*4882a593Smuzhiyun * 0x10 terminator (null _aarch64_ctx) 50*4882a593Smuzhiyun * 51*4882a593Smuzhiyun * 0x510 (reserved for future allocation) 52*4882a593Smuzhiyun * 53*4882a593Smuzhiyun * New records that can exceed this space need to be opt-in for userspace, so 54*4882a593Smuzhiyun * that an expanded signal frame is not generated unexpectedly. The mechanism 55*4882a593Smuzhiyun * for opting in will depend on the extension that generates each new record. 56*4882a593Smuzhiyun * The above table documents the maximum set and sizes of records than can be 57*4882a593Smuzhiyun * generated when userspace does not opt in for any such extension. 58*4882a593Smuzhiyun */ 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun /* 61*4882a593Smuzhiyun * Header to be used at the beginning of structures extending the user 62*4882a593Smuzhiyun * context. Such structures must be placed after the rt_sigframe on the stack 63*4882a593Smuzhiyun * and be 16-byte aligned. The last structure must be a dummy one with the 64*4882a593Smuzhiyun * magic and size set to 0. 65*4882a593Smuzhiyun */ 66*4882a593Smuzhiyun struct _aarch64_ctx { 67*4882a593Smuzhiyun __u32 magic; 68*4882a593Smuzhiyun __u32 size; 69*4882a593Smuzhiyun }; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun #define FPSIMD_MAGIC 0x46508001 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun struct fpsimd_context { 74*4882a593Smuzhiyun struct _aarch64_ctx head; 75*4882a593Smuzhiyun __u32 fpsr; 76*4882a593Smuzhiyun __u32 fpcr; 77*4882a593Smuzhiyun __uint128_t vregs[32]; 78*4882a593Smuzhiyun }; 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /* 81*4882a593Smuzhiyun * Note: similarly to all other integer fields, each V-register is stored in an 82*4882a593Smuzhiyun * endianness-dependent format, with the byte at offset i from the start of the 83*4882a593Smuzhiyun * in-memory representation of the register value containing 84*4882a593Smuzhiyun * 85*4882a593Smuzhiyun * bits [(7 + 8 * i) : (8 * i)] of the register on little-endian hosts; or 86*4882a593Smuzhiyun * bits [(127 - 8 * i) : (120 - 8 * i)] on big-endian hosts. 87*4882a593Smuzhiyun */ 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /* ESR_EL1 context */ 90*4882a593Smuzhiyun #define ESR_MAGIC 0x45535201 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun struct esr_context { 93*4882a593Smuzhiyun struct _aarch64_ctx head; 94*4882a593Smuzhiyun __u64 esr; 95*4882a593Smuzhiyun }; 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /* 98*4882a593Smuzhiyun * extra_context: describes extra space in the signal frame for 99*4882a593Smuzhiyun * additional structures that don't fit in sigcontext.__reserved[]. 100*4882a593Smuzhiyun * 101*4882a593Smuzhiyun * Note: 102*4882a593Smuzhiyun * 103*4882a593Smuzhiyun * 1) fpsimd_context, esr_context and extra_context must be placed in 104*4882a593Smuzhiyun * sigcontext.__reserved[] if present. They cannot be placed in the 105*4882a593Smuzhiyun * extra space. Any other record can be placed either in the extra 106*4882a593Smuzhiyun * space or in sigcontext.__reserved[], unless otherwise specified in 107*4882a593Smuzhiyun * this file. 108*4882a593Smuzhiyun * 109*4882a593Smuzhiyun * 2) There must not be more than one extra_context. 110*4882a593Smuzhiyun * 111*4882a593Smuzhiyun * 3) If extra_context is present, it must be followed immediately in 112*4882a593Smuzhiyun * sigcontext.__reserved[] by the terminating null _aarch64_ctx. 113*4882a593Smuzhiyun * 114*4882a593Smuzhiyun * 4) The extra space to which datap points must start at the first 115*4882a593Smuzhiyun * 16-byte aligned address immediately after the terminating null 116*4882a593Smuzhiyun * _aarch64_ctx that follows the extra_context structure in 117*4882a593Smuzhiyun * __reserved[]. The extra space may overrun the end of __reserved[], 118*4882a593Smuzhiyun * as indicated by a sufficiently large value for the size field. 119*4882a593Smuzhiyun * 120*4882a593Smuzhiyun * 5) The extra space must itself be terminated with a null 121*4882a593Smuzhiyun * _aarch64_ctx. 122*4882a593Smuzhiyun */ 123*4882a593Smuzhiyun #define EXTRA_MAGIC 0x45585401 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun struct extra_context { 126*4882a593Smuzhiyun struct _aarch64_ctx head; 127*4882a593Smuzhiyun __u64 datap; /* 16-byte aligned pointer to extra space cast to __u64 */ 128*4882a593Smuzhiyun __u32 size; /* size in bytes of the extra space */ 129*4882a593Smuzhiyun __u32 __reserved[3]; 130*4882a593Smuzhiyun }; 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun #define SVE_MAGIC 0x53564501 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun struct sve_context { 135*4882a593Smuzhiyun struct _aarch64_ctx head; 136*4882a593Smuzhiyun __u16 vl; 137*4882a593Smuzhiyun __u16 __reserved[3]; 138*4882a593Smuzhiyun }; 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */ 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun #include <asm/sve_context.h> 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun /* 145*4882a593Smuzhiyun * The SVE architecture leaves space for future expansion of the 146*4882a593Smuzhiyun * vector length beyond its initial architectural limit of 2048 bits 147*4882a593Smuzhiyun * (16 quadwords). 148*4882a593Smuzhiyun * 149*4882a593Smuzhiyun * See linux/Documentation/arm64/sve.rst for a description of the VL/VQ 150*4882a593Smuzhiyun * terminology. 151*4882a593Smuzhiyun */ 152*4882a593Smuzhiyun #define SVE_VQ_BYTES __SVE_VQ_BYTES /* bytes per quadword */ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #define SVE_VQ_MIN __SVE_VQ_MIN 155*4882a593Smuzhiyun #define SVE_VQ_MAX __SVE_VQ_MAX 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun #define SVE_VL_MIN __SVE_VL_MIN 158*4882a593Smuzhiyun #define SVE_VL_MAX __SVE_VL_MAX 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun #define SVE_NUM_ZREGS __SVE_NUM_ZREGS 161*4882a593Smuzhiyun #define SVE_NUM_PREGS __SVE_NUM_PREGS 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun #define sve_vl_valid(vl) __sve_vl_valid(vl) 164*4882a593Smuzhiyun #define sve_vq_from_vl(vl) __sve_vq_from_vl(vl) 165*4882a593Smuzhiyun #define sve_vl_from_vq(vq) __sve_vl_from_vq(vq) 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun /* 168*4882a593Smuzhiyun * If the SVE registers are currently live for the thread at signal delivery, 169*4882a593Smuzhiyun * sve_context.head.size >= 170*4882a593Smuzhiyun * SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)) 171*4882a593Smuzhiyun * and the register data may be accessed using the SVE_SIG_*() macros. 172*4882a593Smuzhiyun * 173*4882a593Smuzhiyun * If sve_context.head.size < 174*4882a593Smuzhiyun * SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)), 175*4882a593Smuzhiyun * the SVE registers were not live for the thread and no register data 176*4882a593Smuzhiyun * is included: in this case, the SVE_SIG_*() macros should not be 177*4882a593Smuzhiyun * used except for this check. 178*4882a593Smuzhiyun * 179*4882a593Smuzhiyun * The same convention applies when returning from a signal: a caller 180*4882a593Smuzhiyun * will need to remove or resize the sve_context block if it wants to 181*4882a593Smuzhiyun * make the SVE registers live when they were previously non-live or 182*4882a593Smuzhiyun * vice-versa. This may require the caller to allocate fresh 183*4882a593Smuzhiyun * memory and/or move other context blocks in the signal frame. 184*4882a593Smuzhiyun * 185*4882a593Smuzhiyun * Changing the vector length during signal return is not permitted: 186*4882a593Smuzhiyun * sve_context.vl must equal the thread's current vector length when 187*4882a593Smuzhiyun * doing a sigreturn. 188*4882a593Smuzhiyun * 189*4882a593Smuzhiyun * 190*4882a593Smuzhiyun * Note: for all these macros, the "vq" argument denotes the SVE 191*4882a593Smuzhiyun * vector length in quadwords (i.e., units of 128 bits). 192*4882a593Smuzhiyun * 193*4882a593Smuzhiyun * The correct way to obtain vq is to use sve_vq_from_vl(vl). The 194*4882a593Smuzhiyun * result is valid if and only if sve_vl_valid(vl) is true. This is 195*4882a593Smuzhiyun * guaranteed for a struct sve_context written by the kernel. 196*4882a593Smuzhiyun * 197*4882a593Smuzhiyun * 198*4882a593Smuzhiyun * Additional macros describe the contents and layout of the payload. 199*4882a593Smuzhiyun * For each, SVE_SIG_x_OFFSET(args) is the start offset relative to 200*4882a593Smuzhiyun * the start of struct sve_context, and SVE_SIG_x_SIZE(args) is the 201*4882a593Smuzhiyun * size in bytes: 202*4882a593Smuzhiyun * 203*4882a593Smuzhiyun * x type description 204*4882a593Smuzhiyun * - ---- ----------- 205*4882a593Smuzhiyun * REGS the entire SVE context 206*4882a593Smuzhiyun * 207*4882a593Smuzhiyun * ZREGS __uint128_t[SVE_NUM_ZREGS][vq] all Z-registers 208*4882a593Smuzhiyun * ZREG __uint128_t[vq] individual Z-register Zn 209*4882a593Smuzhiyun * 210*4882a593Smuzhiyun * PREGS uint16_t[SVE_NUM_PREGS][vq] all P-registers 211*4882a593Smuzhiyun * PREG uint16_t[vq] individual P-register Pn 212*4882a593Smuzhiyun * 213*4882a593Smuzhiyun * FFR uint16_t[vq] first-fault status register 214*4882a593Smuzhiyun * 215*4882a593Smuzhiyun * Additional data might be appended in the future. 216*4882a593Smuzhiyun * 217*4882a593Smuzhiyun * Unlike vregs[] in fpsimd_context, each SVE scalable register (Z-, P- or FFR) 218*4882a593Smuzhiyun * is encoded in memory in an endianness-invariant format, with the byte at 219*4882a593Smuzhiyun * offset i from the start of the in-memory representation containing bits 220*4882a593Smuzhiyun * [(7 + 8 * i) : (8 * i)] of the register value. 221*4882a593Smuzhiyun */ 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun #define SVE_SIG_ZREG_SIZE(vq) __SVE_ZREG_SIZE(vq) 224*4882a593Smuzhiyun #define SVE_SIG_PREG_SIZE(vq) __SVE_PREG_SIZE(vq) 225*4882a593Smuzhiyun #define SVE_SIG_FFR_SIZE(vq) __SVE_FFR_SIZE(vq) 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun #define SVE_SIG_REGS_OFFSET \ 228*4882a593Smuzhiyun ((sizeof(struct sve_context) + (__SVE_VQ_BYTES - 1)) \ 229*4882a593Smuzhiyun / __SVE_VQ_BYTES * __SVE_VQ_BYTES) 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun #define SVE_SIG_ZREGS_OFFSET \ 232*4882a593Smuzhiyun (SVE_SIG_REGS_OFFSET + __SVE_ZREGS_OFFSET) 233*4882a593Smuzhiyun #define SVE_SIG_ZREG_OFFSET(vq, n) \ 234*4882a593Smuzhiyun (SVE_SIG_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n)) 235*4882a593Smuzhiyun #define SVE_SIG_ZREGS_SIZE(vq) __SVE_ZREGS_SIZE(vq) 236*4882a593Smuzhiyun 237*4882a593Smuzhiyun #define SVE_SIG_PREGS_OFFSET(vq) \ 238*4882a593Smuzhiyun (SVE_SIG_REGS_OFFSET + __SVE_PREGS_OFFSET(vq)) 239*4882a593Smuzhiyun #define SVE_SIG_PREG_OFFSET(vq, n) \ 240*4882a593Smuzhiyun (SVE_SIG_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n)) 241*4882a593Smuzhiyun #define SVE_SIG_PREGS_SIZE(vq) __SVE_PREGS_SIZE(vq) 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun #define SVE_SIG_FFR_OFFSET(vq) \ 244*4882a593Smuzhiyun (SVE_SIG_REGS_OFFSET + __SVE_FFR_OFFSET(vq)) 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun #define SVE_SIG_REGS_SIZE(vq) \ 247*4882a593Smuzhiyun (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq)) 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun #define SVE_SIG_CONTEXT_SIZE(vq) \ 250*4882a593Smuzhiyun (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq)) 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun #endif /* _UAPI__ASM_SIGCONTEXT_H */ 253