Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
0002 /*
0003  * Copyright (C) 2012 ARM Ltd.
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License version 2 as
0007  * published by the Free Software Foundation.
0008  *
0009  * This program is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  * GNU General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU General Public License
0015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 #ifndef _UAPI__ASM_SIGCONTEXT_H
0018 #define _UAPI__ASM_SIGCONTEXT_H
0019 
0020 #ifndef __ASSEMBLY__
0021 
0022 #include <linux/types.h>
0023 
0024 /*
0025  * Signal context structure - contains all info to do with the state
0026  * before the signal handler was invoked.
0027  */
0028 struct sigcontext {
0029     __u64 fault_address;
0030     /* AArch64 registers */
0031     __u64 regs[31];
0032     __u64 sp;
0033     __u64 pc;
0034     __u64 pstate;
0035     /* 4K reserved for FP/SIMD state and future expansion */
0036     __u8 __reserved[4096] __attribute__((__aligned__(16)));
0037 };
0038 
0039 /*
0040  * Allocation of __reserved[]:
0041  * (Note: records do not necessarily occur in the order shown here.)
0042  *
0043  *  size        description
0044  *
0045  *  0x210       fpsimd_context
0046  *   0x10       esr_context
0047  *  0x8a0       sve_context (vl <= 64) (optional)
0048  *   0x20       extra_context (optional)
0049  *   0x10       terminator (null _aarch64_ctx)
0050  *
0051  *  0x510       (reserved for future allocation)
0052  *
0053  * New records that can exceed this space need to be opt-in for userspace, so
0054  * that an expanded signal frame is not generated unexpectedly.  The mechanism
0055  * for opting in will depend on the extension that generates each new record.
0056  * The above table documents the maximum set and sizes of records than can be
0057  * generated when userspace does not opt in for any such extension.
0058  */
0059 
0060 /*
0061  * Header to be used at the beginning of structures extending the user
0062  * context. Such structures must be placed after the rt_sigframe on the stack
0063  * and be 16-byte aligned. The last structure must be a dummy one with the
0064  * magic and size set to 0.
0065  */
0066 struct _aarch64_ctx {
0067     __u32 magic;
0068     __u32 size;
0069 };
0070 
0071 #define FPSIMD_MAGIC    0x46508001
0072 
0073 struct fpsimd_context {
0074     struct _aarch64_ctx head;
0075     __u32 fpsr;
0076     __u32 fpcr;
0077     __uint128_t vregs[32];
0078 };
0079 
0080 /*
0081  * Note: similarly to all other integer fields, each V-register is stored in an
0082  * endianness-dependent format, with the byte at offset i from the start of the
0083  * in-memory representation of the register value containing
0084  *
0085  *    bits [(7 + 8 * i) : (8 * i)] of the register on little-endian hosts; or
0086  *    bits [(127 - 8 * i) : (120 - 8 * i)] on big-endian hosts.
0087  */
0088 
0089 /* ESR_EL1 context */
0090 #define ESR_MAGIC   0x45535201
0091 
0092 struct esr_context {
0093     struct _aarch64_ctx head;
0094     __u64 esr;
0095 };
0096 
0097 /*
0098  * extra_context: describes extra space in the signal frame for
0099  * additional structures that don't fit in sigcontext.__reserved[].
0100  *
0101  * Note:
0102  *
0103  * 1) fpsimd_context, esr_context and extra_context must be placed in
0104  * sigcontext.__reserved[] if present.  They cannot be placed in the
0105  * extra space.  Any other record can be placed either in the extra
0106  * space or in sigcontext.__reserved[], unless otherwise specified in
0107  * this file.
0108  *
0109  * 2) There must not be more than one extra_context.
0110  *
0111  * 3) If extra_context is present, it must be followed immediately in
0112  * sigcontext.__reserved[] by the terminating null _aarch64_ctx.
0113  *
0114  * 4) The extra space to which datap points must start at the first
0115  * 16-byte aligned address immediately after the terminating null
0116  * _aarch64_ctx that follows the extra_context structure in
0117  * __reserved[].  The extra space may overrun the end of __reserved[],
0118  * as indicated by a sufficiently large value for the size field.
0119  *
0120  * 5) The extra space must itself be terminated with a null
0121  * _aarch64_ctx.
0122  */
0123 #define EXTRA_MAGIC 0x45585401
0124 
0125 struct extra_context {
0126     struct _aarch64_ctx head;
0127     __u64 datap; /* 16-byte aligned pointer to extra space cast to __u64 */
0128     __u32 size; /* size in bytes of the extra space */
0129     __u32 __reserved[3];
0130 };
0131 
0132 #define SVE_MAGIC   0x53564501
0133 
0134 struct sve_context {
0135     struct _aarch64_ctx head;
0136     __u16 vl;
0137     __u16 flags;
0138     __u16 __reserved[2];
0139 };
0140 
0141 #define SVE_SIG_FLAG_SM 0x1 /* Context describes streaming mode */
0142 
0143 #define ZA_MAGIC    0x54366345
0144 
0145 struct za_context {
0146     struct _aarch64_ctx head;
0147     __u16 vl;
0148     __u16 __reserved[3];
0149 };
0150 
0151 #endif /* !__ASSEMBLY__ */
0152 
0153 #include <asm/sve_context.h>
0154 
0155 /*
0156  * The SVE architecture leaves space for future expansion of the
0157  * vector length beyond its initial architectural limit of 2048 bits
0158  * (16 quadwords).
0159  *
0160  * See linux/Documentation/arm64/sve.rst for a description of the VL/VQ
0161  * terminology.
0162  */
0163 #define SVE_VQ_BYTES        __SVE_VQ_BYTES  /* bytes per quadword */
0164 
0165 #define SVE_VQ_MIN      __SVE_VQ_MIN
0166 #define SVE_VQ_MAX      __SVE_VQ_MAX
0167 
0168 #define SVE_VL_MIN      __SVE_VL_MIN
0169 #define SVE_VL_MAX      __SVE_VL_MAX
0170 
0171 #define SVE_NUM_ZREGS       __SVE_NUM_ZREGS
0172 #define SVE_NUM_PREGS       __SVE_NUM_PREGS
0173 
0174 #define sve_vl_valid(vl)    __sve_vl_valid(vl)
0175 #define sve_vq_from_vl(vl)  __sve_vq_from_vl(vl)
0176 #define sve_vl_from_vq(vq)  __sve_vl_from_vq(vq)
0177 
0178 /*
0179  * If the SVE registers are currently live for the thread at signal delivery,
0180  * sve_context.head.size >=
0181  *  SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl))
0182  * and the register data may be accessed using the SVE_SIG_*() macros.
0183  *
0184  * If sve_context.head.size <
0185  *  SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)),
0186  * the SVE registers were not live for the thread and no register data
0187  * is included: in this case, the SVE_SIG_*() macros should not be
0188  * used except for this check.
0189  *
0190  * The same convention applies when returning from a signal: a caller
0191  * will need to remove or resize the sve_context block if it wants to
0192  * make the SVE registers live when they were previously non-live or
0193  * vice-versa.  This may require the caller to allocate fresh
0194  * memory and/or move other context blocks in the signal frame.
0195  *
0196  * Changing the vector length during signal return is not permitted:
0197  * sve_context.vl must equal the thread's current vector length when
0198  * doing a sigreturn.
0199  *
0200  * On systems with support for SME the SVE register state may reflect either
0201  * streaming or non-streaming mode.  In streaming mode the streaming mode
0202  * vector length will be used and the flag SVE_SIG_FLAG_SM will be set in
0203  * the flags field. It is permitted to enter or leave streaming mode in
0204  * a signal return, applications should take care to ensure that any difference
0205  * in vector length between the two modes is handled, including any resizing
0206  * and movement of context blocks.
0207  *
0208  * Note: for all these macros, the "vq" argument denotes the vector length
0209  * in quadwords (i.e., units of 128 bits).
0210  *
0211  * The correct way to obtain vq is to use sve_vq_from_vl(vl).  The
0212  * result is valid if and only if sve_vl_valid(vl) is true.  This is
0213  * guaranteed for a struct sve_context written by the kernel.
0214  *
0215  *
0216  * Additional macros describe the contents and layout of the payload.
0217  * For each, SVE_SIG_x_OFFSET(args) is the start offset relative to
0218  * the start of struct sve_context, and SVE_SIG_x_SIZE(args) is the
0219  * size in bytes:
0220  *
0221  *  x   type                description
0222  *  -   ----                -----------
0223  *  REGS                    the entire SVE context
0224  *
0225  *  ZREGS   __uint128_t[SVE_NUM_ZREGS][vq]  all Z-registers
0226  *  ZREG    __uint128_t[vq]         individual Z-register Zn
0227  *
0228  *  PREGS   uint16_t[SVE_NUM_PREGS][vq] all P-registers
0229  *  PREG    uint16_t[vq]            individual P-register Pn
0230  *
0231  *  FFR uint16_t[vq]            first-fault status register
0232  *
0233  * Additional data might be appended in the future.
0234  *
0235  * Unlike vregs[] in fpsimd_context, each SVE scalable register (Z-, P- or FFR)
0236  * is encoded in memory in an endianness-invariant format, with the byte at
0237  * offset i from the start of the in-memory representation containing bits
0238  * [(7 + 8 * i) : (8 * i)] of the register value.
0239  */
0240 
0241 #define SVE_SIG_ZREG_SIZE(vq)   __SVE_ZREG_SIZE(vq)
0242 #define SVE_SIG_PREG_SIZE(vq)   __SVE_PREG_SIZE(vq)
0243 #define SVE_SIG_FFR_SIZE(vq)    __SVE_FFR_SIZE(vq)
0244 
0245 #define SVE_SIG_REGS_OFFSET                 \
0246     ((sizeof(struct sve_context) + (__SVE_VQ_BYTES - 1))    \
0247         / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
0248 
0249 #define SVE_SIG_ZREGS_OFFSET \
0250         (SVE_SIG_REGS_OFFSET + __SVE_ZREGS_OFFSET)
0251 #define SVE_SIG_ZREG_OFFSET(vq, n) \
0252         (SVE_SIG_REGS_OFFSET + __SVE_ZREG_OFFSET(vq, n))
0253 #define SVE_SIG_ZREGS_SIZE(vq) __SVE_ZREGS_SIZE(vq)
0254 
0255 #define SVE_SIG_PREGS_OFFSET(vq) \
0256         (SVE_SIG_REGS_OFFSET + __SVE_PREGS_OFFSET(vq))
0257 #define SVE_SIG_PREG_OFFSET(vq, n) \
0258         (SVE_SIG_REGS_OFFSET + __SVE_PREG_OFFSET(vq, n))
0259 #define SVE_SIG_PREGS_SIZE(vq) __SVE_PREGS_SIZE(vq)
0260 
0261 #define SVE_SIG_FFR_OFFSET(vq) \
0262         (SVE_SIG_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
0263 
0264 #define SVE_SIG_REGS_SIZE(vq) \
0265         (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
0266 
0267 #define SVE_SIG_CONTEXT_SIZE(vq) \
0268         (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
0269 
0270 /*
0271  * If the ZA register is enabled for the thread at signal delivery then,
0272  * za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
0273  * and the register data may be accessed using the ZA_SIG_*() macros.
0274  *
0275  * If za_context.head.size < ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
0276  * then ZA was not enabled and no register data was included in which case
0277  * ZA register was not enabled for the thread and no register data
0278  * the ZA_SIG_*() macros should not be used except for this check.
0279  *
0280  * The same convention applies when returning from a signal: a caller
0281  * will need to remove or resize the za_context block if it wants to
0282  * enable the ZA register when it was previously non-live or vice-versa.
0283  * This may require the caller to allocate fresh memory and/or move other
0284  * context blocks in the signal frame.
0285  *
0286  * Changing the vector length during signal return is not permitted:
0287  * za_context.vl must equal the thread's current SME vector length when
0288  * doing a sigreturn.
0289  */
0290 
0291 #define ZA_SIG_REGS_OFFSET                  \
0292     ((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1)) \
0293         / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
0294 
0295 #define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
0296 
0297 #define ZA_SIG_ZAV_OFFSET(vq, n) (ZA_SIG_REGS_OFFSET + \
0298                   (SVE_SIG_ZREG_SIZE(vq) * n))
0299 
0300 #define ZA_SIG_CONTEXT_SIZE(vq) \
0301         (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
0302 
0303 #endif /* _UAPI__ASM_SIGCONTEXT_H */