xref: /openbmc/linux/tools/testing/selftests/arm64/signal/testcases/sme_vl.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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