0001
0002
0003 #include "testcases.h"
0004
0005 struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
0006 size_t resv_sz, size_t *offset)
0007 {
0008 size_t offs = 0;
0009 struct _aarch64_ctx *found = NULL;
0010
0011 if (!head || resv_sz < HDR_SZ)
0012 return found;
0013
0014 while (offs <= resv_sz - HDR_SZ &&
0015 head->magic != magic && head->magic) {
0016 offs += head->size;
0017 head = GET_RESV_NEXT_HEAD(head);
0018 }
0019 if (head->magic == magic) {
0020 found = head;
0021 if (offset)
0022 *offset = offs;
0023 }
0024
0025 return found;
0026 }
0027
0028 bool validate_extra_context(struct extra_context *extra, char **err)
0029 {
0030 struct _aarch64_ctx *term;
0031
0032 if (!extra || !err)
0033 return false;
0034
0035 fprintf(stderr, "Validating EXTRA...\n");
0036 term = GET_RESV_NEXT_HEAD(extra);
0037 if (!term || term->magic || term->size) {
0038 *err = "Missing terminator after EXTRA context";
0039 return false;
0040 }
0041 if (extra->datap & 0x0fUL)
0042 *err = "Extra DATAP misaligned";
0043 else if (extra->size & 0x0fUL)
0044 *err = "Extra SIZE misaligned";
0045 else if (extra->datap != (uint64_t)term + sizeof(*term))
0046 *err = "Extra DATAP misplaced (not contiguous)";
0047 if (*err)
0048 return false;
0049
0050 return true;
0051 }
0052
0053 bool validate_sve_context(struct sve_context *sve, char **err)
0054 {
0055
0056 size_t regs_size
0057 = ((SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve->vl)) + 15) / 16) * 16;
0058
0059 if (!sve || !err)
0060 return false;
0061
0062
0063 if ((sve->head.size != sizeof(struct sve_context)) &&
0064 (sve->head.size != regs_size)) {
0065 *err = "bad size for SVE context";
0066 return false;
0067 }
0068
0069 if (!sve_vl_valid(sve->vl)) {
0070 *err = "SVE VL invalid";
0071
0072 return false;
0073 }
0074
0075 return true;
0076 }
0077
0078 bool validate_za_context(struct za_context *za, char **err)
0079 {
0080
0081 size_t regs_size
0082 = ((ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za->vl)) + 15) / 16) * 16;
0083
0084 if (!za || !err)
0085 return false;
0086
0087
0088 if ((za->head.size != sizeof(struct za_context)) &&
0089 (za->head.size != regs_size)) {
0090 *err = "bad size for ZA context";
0091 return false;
0092 }
0093
0094 if (!sve_vl_valid(za->vl)) {
0095 *err = "SME VL in ZA context invalid";
0096
0097 return false;
0098 }
0099
0100 return true;
0101 }
0102
0103 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
0104 {
0105 bool terminated = false;
0106 size_t offs = 0;
0107 int flags = 0;
0108 struct extra_context *extra = NULL;
0109 struct sve_context *sve = NULL;
0110 struct za_context *za = NULL;
0111 struct _aarch64_ctx *head =
0112 (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
0113
0114 if (!err)
0115 return false;
0116
0117 while (head && !terminated && offs < resv_sz) {
0118 if ((uint64_t)head & 0x0fUL) {
0119 *err = "Misaligned HEAD";
0120 return false;
0121 }
0122
0123 switch (head->magic) {
0124 case 0:
0125 if (head->size)
0126 *err = "Bad size for terminator";
0127 else
0128 terminated = true;
0129 break;
0130 case FPSIMD_MAGIC:
0131 if (flags & FPSIMD_CTX)
0132 *err = "Multiple FPSIMD_MAGIC";
0133 else if (head->size !=
0134 sizeof(struct fpsimd_context))
0135 *err = "Bad size for fpsimd_context";
0136 flags |= FPSIMD_CTX;
0137 break;
0138 case ESR_MAGIC:
0139 if (head->size != sizeof(struct esr_context))
0140 *err = "Bad size for esr_context";
0141 break;
0142 case SVE_MAGIC:
0143 if (flags & SVE_CTX)
0144 *err = "Multiple SVE_MAGIC";
0145
0146 sve = (struct sve_context *)head;
0147 flags |= SVE_CTX;
0148 break;
0149 case ZA_MAGIC:
0150 if (flags & ZA_CTX)
0151 *err = "Multiple ZA_MAGIC";
0152
0153 za = (struct za_context *)head;
0154 flags |= ZA_CTX;
0155 break;
0156 case EXTRA_MAGIC:
0157 if (flags & EXTRA_CTX)
0158 *err = "Multiple EXTRA_MAGIC";
0159 else if (head->size !=
0160 sizeof(struct extra_context))
0161 *err = "Bad size for extra_context";
0162 flags |= EXTRA_CTX;
0163 extra = (struct extra_context *)head;
0164 break;
0165 case KSFT_BAD_MAGIC:
0166
0167
0168
0169
0170
0171
0172 *err = "BAD MAGIC !";
0173 break;
0174 default:
0175
0176
0177
0178
0179
0180 fprintf(stdout,
0181 "SKIP Unknown MAGIC: 0x%X - Is KSFT arm64/signal up to date ?\n",
0182 head->magic);
0183 break;
0184 }
0185
0186 if (*err)
0187 return false;
0188
0189 offs += head->size;
0190 if (resv_sz < offs + sizeof(*head)) {
0191 *err = "HEAD Overrun";
0192 return false;
0193 }
0194
0195 if (flags & EXTRA_CTX)
0196 if (!validate_extra_context(extra, err))
0197 return false;
0198 if (flags & SVE_CTX)
0199 if (!validate_sve_context(sve, err))
0200 return false;
0201 if (flags & ZA_CTX)
0202 if (!validate_za_context(za, err))
0203 return false;
0204
0205 head = GET_RESV_NEXT_HEAD(head);
0206 }
0207
0208 if (terminated && !(flags & FPSIMD_CTX)) {
0209 *err = "Missing FPSIMD";
0210 return false;
0211 }
0212
0213 return true;
0214 }
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 struct _aarch64_ctx *get_starting_head(struct _aarch64_ctx *shead,
0235 size_t need_sz, size_t resv_sz,
0236 size_t *offset)
0237 {
0238 size_t offs = 0;
0239 struct _aarch64_ctx *head;
0240
0241 head = get_terminator(shead, resv_sz, &offs);
0242
0243 if (!head)
0244 return head;
0245 if (resv_sz - offs < need_sz) {
0246 fprintf(stderr, "Low on space:%zd. Discarding extra_context.\n",
0247 resv_sz - offs);
0248 head = get_header(shead, EXTRA_MAGIC, resv_sz, &offs);
0249 if (!head || resv_sz - offs < need_sz) {
0250 fprintf(stderr,
0251 "Failed to reclaim space on sigframe.\n");
0252 return NULL;
0253 }
0254 }
0255
0256 fprintf(stderr, "Available space:%zd\n", resv_sz - offs);
0257 if (offset)
0258 *offset = offs;
0259 return head;
0260 }