118f8729aSMark Brown // SPDX-License-Identifier: GPL-2.0
218f8729aSMark Brown /*
318f8729aSMark Brown * Copyright (C) 2021 ARM Limited
418f8729aSMark Brown *
518f8729aSMark Brown * Verify that using an instruction not supported in streaming mode
618f8729aSMark Brown * traps when in streaming mode.
718f8729aSMark Brown */
818f8729aSMark Brown
918f8729aSMark Brown #include <signal.h>
1018f8729aSMark Brown #include <ucontext.h>
1118f8729aSMark Brown #include <sys/prctl.h>
1218f8729aSMark Brown
1318f8729aSMark Brown #include "test_signals_utils.h"
1418f8729aSMark Brown #include "testcases.h"
1518f8729aSMark Brown
1618f8729aSMark Brown static union {
1718f8729aSMark Brown ucontext_t uc;
1818f8729aSMark Brown char buf[1024 * 128];
1918f8729aSMark Brown } context;
2018f8729aSMark Brown
enable_za(void)2118f8729aSMark Brown static void enable_za(void)
2218f8729aSMark Brown {
2318f8729aSMark Brown /* smstart za; real data is TODO */
2418f8729aSMark Brown asm volatile(".inst 0xd503457f" : : : );
2518f8729aSMark Brown }
2618f8729aSMark Brown
zt_regs_run(struct tdescr * td,siginfo_t * si,ucontext_t * uc)2718f8729aSMark Brown int zt_regs_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
2818f8729aSMark Brown {
2918f8729aSMark Brown size_t offset;
3018f8729aSMark Brown struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
3118f8729aSMark Brown struct zt_context *zt;
3218f8729aSMark Brown char *zeros;
3318f8729aSMark Brown
3418f8729aSMark Brown /*
3518f8729aSMark Brown * Get a signal context which should have a ZT frame and registers
3618f8729aSMark Brown * in it.
3718f8729aSMark Brown */
3818f8729aSMark Brown enable_za();
3918f8729aSMark Brown if (!get_current_context(td, &context.uc, sizeof(context)))
4018f8729aSMark Brown return 1;
4118f8729aSMark Brown
4218f8729aSMark Brown head = get_header(head, ZT_MAGIC, GET_BUF_RESV_SIZE(context), &offset);
4318f8729aSMark Brown if (!head) {
4418f8729aSMark Brown fprintf(stderr, "No ZT context\n");
4518f8729aSMark Brown return 1;
4618f8729aSMark Brown }
4718f8729aSMark Brown
4818f8729aSMark Brown zt = (struct zt_context *)head;
4918f8729aSMark Brown if (zt->nregs == 0) {
5018f8729aSMark Brown fprintf(stderr, "Got context with no registers\n");
5118f8729aSMark Brown return 1;
5218f8729aSMark Brown }
5318f8729aSMark Brown
5418f8729aSMark Brown fprintf(stderr, "Got expected size %u for %d registers\n",
5518f8729aSMark Brown head->size, zt->nregs);
5618f8729aSMark Brown
5718f8729aSMark Brown /* We didn't load any data into ZT so it should be all zeros */
5818f8729aSMark Brown zeros = malloc(ZT_SIG_REGS_SIZE(zt->nregs));
5918f8729aSMark Brown if (!zeros) {
6018f8729aSMark Brown fprintf(stderr, "Out of memory, nregs=%u\n", zt->nregs);
6118f8729aSMark Brown return 1;
6218f8729aSMark Brown }
6318f8729aSMark Brown memset(zeros, 0, ZT_SIG_REGS_SIZE(zt->nregs));
6418f8729aSMark Brown
6518f8729aSMark Brown if (memcmp(zeros, (char *)zt + ZT_SIG_REGS_OFFSET,
6618f8729aSMark Brown ZT_SIG_REGS_SIZE(zt->nregs)) != 0) {
6718f8729aSMark Brown fprintf(stderr, "ZT data invalid\n");
68*46862da1SDing Xiang free(zeros);
6918f8729aSMark Brown return 1;
7018f8729aSMark Brown }
7118f8729aSMark Brown
7218f8729aSMark Brown free(zeros);
7318f8729aSMark Brown
7418f8729aSMark Brown td->pass = 1;
7518f8729aSMark Brown
7618f8729aSMark Brown return 0;
7718f8729aSMark Brown }
7818f8729aSMark Brown
7918f8729aSMark Brown struct tdescr tde = {
8018f8729aSMark Brown .name = "ZT register data",
8118f8729aSMark Brown .descr = "Validate that ZT is present and has data when ZA is enabled",
8218f8729aSMark Brown .feats_required = FEAT_SME2,
8318f8729aSMark Brown .timeout = 3,
8418f8729aSMark Brown .sanity_disabled = true,
8518f8729aSMark Brown .run = zt_regs_run,
8618f8729aSMark Brown };
87