File Index
Files and directories
Sign in
FILE

ssve_regs.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2021 ARM Limited
  4 *
  5 * Verify that the streaming SVE register context in signal frames is
  6 * set up as expected.
  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 * 64];
 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_ssve_regs(void)
 37{
 38	/* smstart sm; real data is TODO */
 39	asm volatile(".inst 0xd503437f" : : : );
 40}
 41
 42static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
 43			 unsigned int vl)
 44{
 45	size_t offset;
 46	struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context);
 47	struct sve_context *ssve;
 48	int ret;
 49
 50	fprintf(stderr, "Testing VL %d\n", vl);
 51
 52	ret = prctl(PR_SME_SET_VL, vl);
 53	if (ret != vl) {
 54		fprintf(stderr, "Failed to set VL, got %d\n", ret);
 55		return 1;
 56	}
 57
 58	/*
 59	 * Get a signal context which should have a SVE frame and registers
 60	 * in it.
 61	 */
 62	setup_ssve_regs();
 63	if (!get_current_context(td, &context.uc, sizeof(context)))
 64		return 1;
 65
 66	head = get_header(head, SVE_MAGIC, GET_BUF_RESV_SIZE(context),
 67			  &offset);
 68	if (!head) {
 69		fprintf(stderr, "No SVE context\n");
 70		return 1;
 71	}
 72
 73	ssve = (struct sve_context *)head;
 74	if (ssve->vl != vl) {
 75		fprintf(stderr, "Got VL %d, expected %d\n", ssve->vl, vl);
 76		return 1;
 77	}
 78
 79	if (!(ssve->flags & SVE_SIG_FLAG_SM)) {
 80		fprintf(stderr, "SVE_SIG_FLAG_SM not set in SVE record\n");
 81		return 1;
 82	}
 83
 84	/* The actual size validation is done in get_current_context() */
 85	fprintf(stderr, "Got expected size %u and VL %d\n",
 86		head->size, ssve->vl);
 87
 88	if (get_svcr() != 0) {
 89		fprintf(stderr, "Unexpected SVCR %lx\n", get_svcr());
 90		return 1;
 91	}
 92
 93	return 0;
 94}
 95
 96static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
 97{
 98	int i;
 99
100	for (i = 0; i < nvls; i++) {
101		if (do_one_sme_vl(td, si, uc, vls[i]))
102			return 1;
103	}
104
105	td->pass = 1;
106
107	return 0;
108}
109
110struct tdescr tde = {
111	.name = "Streaming SVE registers",
112	.descr = "Check that we get the right Streaming SVE registers reported",
113	.feats_required = FEAT_SME,
114	.timeout = 3,
115	.init = sme_get_vls,
116	.run = sme_regs,
117};
~/ Read-only file preview.