14963aeb3SMark Brown // SPDX-License-Identifier: GPL-2.0
24963aeb3SMark Brown /*
34963aeb3SMark Brown * Copyright (C) 2021 ARM Limited
44963aeb3SMark Brown *
54963aeb3SMark Brown * Check that the SME vector length reported in signal contexts is the
64963aeb3SMark Brown * expected one.
74963aeb3SMark Brown */
84963aeb3SMark Brown
94963aeb3SMark Brown #include <signal.h>
104963aeb3SMark Brown #include <ucontext.h>
114963aeb3SMark Brown #include <sys/prctl.h>
124963aeb3SMark Brown
134963aeb3SMark Brown #include "test_signals_utils.h"
144963aeb3SMark Brown #include "testcases.h"
154963aeb3SMark Brown
164963aeb3SMark Brown struct fake_sigframe sf;
174963aeb3SMark Brown unsigned int vl;
184963aeb3SMark Brown
get_sme_vl(struct tdescr * td)194963aeb3SMark Brown static bool get_sme_vl(struct tdescr *td)
204963aeb3SMark Brown {
214963aeb3SMark Brown int ret = prctl(PR_SME_GET_VL);
224963aeb3SMark Brown if (ret == -1)
234963aeb3SMark Brown return false;
244963aeb3SMark Brown
254963aeb3SMark Brown vl = ret;
264963aeb3SMark Brown
274963aeb3SMark Brown return true;
284963aeb3SMark Brown }
294963aeb3SMark Brown
sme_vl(struct tdescr * td,siginfo_t * si,ucontext_t * uc)304963aeb3SMark Brown static int sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
314963aeb3SMark Brown {
324963aeb3SMark Brown size_t resv_sz, offset;
334963aeb3SMark Brown struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
344963aeb3SMark Brown struct za_context *za;
354963aeb3SMark Brown
364963aeb3SMark Brown /* Get a signal context which should have a ZA frame in it */
37*38150a62SMark Brown if (!get_current_context(td, &sf.uc, sizeof(sf.uc)))
384963aeb3SMark Brown return 1;
394963aeb3SMark Brown
404963aeb3SMark Brown resv_sz = GET_SF_RESV_SIZE(sf);
414963aeb3SMark Brown head = get_header(head, ZA_MAGIC, resv_sz, &offset);
424963aeb3SMark Brown if (!head) {
434963aeb3SMark Brown fprintf(stderr, "No ZA context\n");
444963aeb3SMark Brown return 1;
454963aeb3SMark Brown }
464963aeb3SMark Brown za = (struct za_context *)head;
474963aeb3SMark Brown
484963aeb3SMark Brown if (za->vl != vl) {
494963aeb3SMark Brown fprintf(stderr, "ZA sigframe VL %u, expected %u\n",
504963aeb3SMark Brown za->vl, vl);
514963aeb3SMark Brown return 1;
524963aeb3SMark Brown } else {
534963aeb3SMark Brown fprintf(stderr, "got expected VL %u\n", vl);
544963aeb3SMark Brown }
554963aeb3SMark Brown
564963aeb3SMark Brown td->pass = 1;
574963aeb3SMark Brown
584963aeb3SMark Brown return 0;
594963aeb3SMark Brown }
604963aeb3SMark Brown
614963aeb3SMark Brown struct tdescr tde = {
624963aeb3SMark Brown .name = "SME VL",
634963aeb3SMark Brown .descr = "Check that we get the right SME VL reported",
644963aeb3SMark Brown .feats_required = FEAT_SME,
654963aeb3SMark Brown .timeout = 3,
664963aeb3SMark Brown .init = get_sme_vl,
674963aeb3SMark Brown .run = sme_vl,
684963aeb3SMark Brown };
69