File Index
Files and directories
Sign in
FILE

ssve_za_regs.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2021 ARM Limited
  4 *
  5 * Verify that both the streaming SVE and ZA register context in
  6 * signal frames is set up as expected when enabled simultaneously.
  7 */
  8
  9#include <kselftest.h>
 10#include <signal.h>
 11#include <ucontext.h>
 12#include <sys/prctl.h>
 13
 14#include "test_signals_utils.h"
 15#include "sve_helpers.h"
 16#include "testcases.h"
 17
 18static union {
 19	ucontext_t uc;
 20	char buf[1024 * 128];
 21} context;
 22
 23static bool sme_get_vls(struct tdescr *td)
 24{
 25	int res = sve_fill_vls(VLS_USE_SME, 1);
 26
 27	if (!res)
 28		return true;
 29
 30	if (res == KSFT_SKIP)
 31		td->result = KSFT_SKIP;
 32
 33	return false;
 34}
 35
 36static void setup_regs(void)
 37{
 38	/* smstart sm; real data is TODO */
 39	asm volatile(".inst 0xd503437f" : : : );
 40
 41	/* smstart za; real data is TODO */
 42	asm volatile(".inst 0xd503457f" : : : );
 43}
 44
 45static char zeros[ZA_SIG_REGS_SIZE(SVE_VQ_MAX)];
 46
 47static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
 48			 unsigned int vl)
 49{
 50	size_t offset;
 51	struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
 52	struct _aarch64_ctx *regs;
 53	struct sve_context *ssve;
 54	struct za_context *za;
 55	int ret;
 56
 57	fprintf(stderr, "Testing VL %d\n", vl);
 58
 59	ret = prctl(PR_SME_SET_VL, vl);
 60	if (ret != vl) {
 61		fprintf(stderr, "Failed to set VL, got %d\n", ret);
 62		return 1;
 63	}
 64
 65	/*
 66	 * Get a signal context which should have the SVE and ZA
 67	 * frames in it.
 68	 */
 69	setup_regs();
 70	if (!get_current_context(td, &context.uc, sizeof(context)))
 71		return 1;
 72
 73	regs = get_header(head, SVE_MAGIC, GET_BUF_RESV_SIZE(context),
 74			  &offset);
 75	if (!regs) {
 76		fprintf(stderr, "No SVE context\n");
 77		return 1;
 78	}
 79
 80	ssve = (struct sve_context *)regs;
 81	if (ssve->vl != vl) {
 82		fprintf(stderr, "Got SSVE VL %d, expected %d\n", ssve->vl, vl);
 83		return 1;
 84	}
 85
 86	if (!(ssve->flags & SVE_SIG_FLAG_SM)) {
 87		fprintf(stderr, "SVE_SIG_FLAG_SM not set in SVE record\n");
 88		return 1;
 89	}
 90
 91	fprintf(stderr, "Got expected SSVE size %u and VL %d\n",
 92		regs->size, ssve->vl);
 93
 94	regs = get_header(head, ZA_MAGIC, GET_BUF_RESV_SIZE(context),
 95			  &offset);
 96	if (!regs) {
 97		fprintf(stderr, "No ZA context\n");
 98		return 1;
 99	}
100
101	za = (struct za_context *)regs;
102	if (za->vl != vl) {
103		fprintf(stderr, "Got ZA VL %d, expected %d\n", za->vl, vl);
104		return 1;
105	}
106
107	fprintf(stderr, "Got expected ZA size %u and VL %d\n",
108		regs->size, za->vl);
109
110	/* We didn't load any data into ZA so it should be all zeros */
111	if (memcmp(zeros, (char *)za + ZA_SIG_REGS_OFFSET,
112		   ZA_SIG_REGS_SIZE(sve_vq_from_vl(za->vl))) != 0) {
113		fprintf(stderr, "ZA data invalid\n");
114		return 1;
115	}
116
117	return 0;
118}
119
120static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
121{
122	int i;
123
124	for (i = 0; i < nvls; i++) {
125		if (do_one_sme_vl(td, si, uc, vls[i]))
126			return 1;
127	}
128
129	td->pass = 1;
130
131	return 0;
132}
133
134struct tdescr tde = {
135	.name = "Streaming SVE registers",
136	.descr = "Check that we get the right Streaming SVE registers reported",
137	.feats_required = FEAT_SME,
138	.timeout = 3,
139	.init = sme_get_vls,
140	.run = sme_regs,
141};
~/ Read-only file preview.