18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* Copyright (C) 2019 ARM Limited */ 38c2ecf20Sopenharmony_ci#ifndef __TESTCASES_H__ 48c2ecf20Sopenharmony_ci#define __TESTCASES_H__ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <stddef.h> 78c2ecf20Sopenharmony_ci#include <stdio.h> 88c2ecf20Sopenharmony_ci#include <stdbool.h> 98c2ecf20Sopenharmony_ci#include <stdint.h> 108c2ecf20Sopenharmony_ci#include <stdlib.h> 118c2ecf20Sopenharmony_ci#include <ucontext.h> 128c2ecf20Sopenharmony_ci#include <signal.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* Architecture specific sigframe definitions */ 158c2ecf20Sopenharmony_ci#include <asm/sigcontext.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define FPSIMD_CTX (1 << 0) 188c2ecf20Sopenharmony_ci#define SVE_CTX (1 << 1) 198c2ecf20Sopenharmony_ci#define EXTRA_CTX (1 << 2) 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define KSFT_BAD_MAGIC 0xdeadbeef 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define HDR_SZ \ 248c2ecf20Sopenharmony_ci sizeof(struct _aarch64_ctx) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define GET_SF_RESV_HEAD(sf) \ 278c2ecf20Sopenharmony_ci (struct _aarch64_ctx *)(&(sf).uc.uc_mcontext.__reserved) 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define GET_SF_RESV_SIZE(sf) \ 308c2ecf20Sopenharmony_ci sizeof((sf).uc.uc_mcontext.__reserved) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define GET_UCP_RESV_SIZE(ucp) \ 338c2ecf20Sopenharmony_ci sizeof((ucp)->uc_mcontext.__reserved) 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define ASSERT_BAD_CONTEXT(uc) do { \ 368c2ecf20Sopenharmony_ci char *err = NULL; \ 378c2ecf20Sopenharmony_ci if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) { \ 388c2ecf20Sopenharmony_ci if (err) \ 398c2ecf20Sopenharmony_ci fprintf(stderr, \ 408c2ecf20Sopenharmony_ci "Using badly built context - ERR: %s\n",\ 418c2ecf20Sopenharmony_ci err); \ 428c2ecf20Sopenharmony_ci } else { \ 438c2ecf20Sopenharmony_ci abort(); \ 448c2ecf20Sopenharmony_ci } \ 458c2ecf20Sopenharmony_ci} while (0) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define ASSERT_GOOD_CONTEXT(uc) do { \ 488c2ecf20Sopenharmony_ci char *err = NULL; \ 498c2ecf20Sopenharmony_ci if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) { \ 508c2ecf20Sopenharmony_ci if (err) \ 518c2ecf20Sopenharmony_ci fprintf(stderr, \ 528c2ecf20Sopenharmony_ci "Detected BAD context - ERR: %s\n", err);\ 538c2ecf20Sopenharmony_ci abort(); \ 548c2ecf20Sopenharmony_ci } else { \ 558c2ecf20Sopenharmony_ci fprintf(stderr, "uc context validated.\n"); \ 568c2ecf20Sopenharmony_ci } \ 578c2ecf20Sopenharmony_ci} while (0) 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/* 608c2ecf20Sopenharmony_ci * A simple record-walker for __reserved area: it walks through assuming 618c2ecf20Sopenharmony_ci * only to find a proper struct __aarch64_ctx header descriptor. 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * Instead it makes no assumptions on the content and ordering of the 648c2ecf20Sopenharmony_ci * records, any needed bounds checking must be enforced by the caller 658c2ecf20Sopenharmony_ci * if wanted: this way can be used by caller on any maliciously built bad 668c2ecf20Sopenharmony_ci * contexts. 678c2ecf20Sopenharmony_ci * 688c2ecf20Sopenharmony_ci * head->size accounts both for payload and header _aarch64_ctx size ! 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ci#define GET_RESV_NEXT_HEAD(h) \ 718c2ecf20Sopenharmony_ci (struct _aarch64_ctx *)((char *)(h) + (h)->size) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistruct fake_sigframe { 748c2ecf20Sopenharmony_ci siginfo_t info; 758c2ecf20Sopenharmony_ci ucontext_t uc; 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cibool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cibool validate_extra_context(struct extra_context *extra, char **err); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistruct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic, 848c2ecf20Sopenharmony_ci size_t resv_sz, size_t *offset); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic inline struct _aarch64_ctx *get_terminator(struct _aarch64_ctx *head, 878c2ecf20Sopenharmony_ci size_t resv_sz, 888c2ecf20Sopenharmony_ci size_t *offset) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci return get_header(head, 0, resv_sz, offset); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic inline void write_terminator_record(struct _aarch64_ctx *tail) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci if (tail) { 968c2ecf20Sopenharmony_ci tail->magic = 0; 978c2ecf20Sopenharmony_ci tail->size = 0; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistruct _aarch64_ctx *get_starting_head(struct _aarch64_ctx *shead, 1028c2ecf20Sopenharmony_ci size_t need_sz, size_t resv_sz, 1038c2ecf20Sopenharmony_ci size_t *offset); 1048c2ecf20Sopenharmony_ci#endif 105