File Index
Files and directories
Sign in
FILE

sve_regs.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/arm64/signal/testcases/sve_regs.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2021 ARM Limited
  4 *
  5 * Verify that the SVE register context in signal frames is set up as
  6 * 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 sve_get_vls(struct tdescr *td)
 24{
 25	int res = sve_fill_vls(VLS_USE_SVE, 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_sve_regs(void)
 37{
 38	/* RDVL x16, #1 so we should have SVE regs; real data is TODO */
 39	asm volatile(".inst 0x04bf5030" : : : "x16" );
 40}
 41
 42static int do_one_sve_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 *sve;
 48
 49	fprintf(stderr, "Testing VL %d\n", vl);
 50
 51	if (prctl(PR_SVE_SET_VL, vl) == -1) {
 52		fprintf(stderr, "Failed to set VL\n");
 53		return 1;
 54	}
 55
 56	/*
 57	 * Get a signal context which should have a SVE frame and registers
 58	 * in it.
 59	 */
 60	setup_sve_regs();
 61	if (!get_current_context(td, &context.uc, sizeof(context)))
 62		return 1;
 63
 64	head = get_header(head, SVE_MAGIC, GET_BUF_RESV_SIZE(context),
 65			  &offset);
 66	if (!head) {
 67		fprintf(stderr, "No SVE context\n");
 68		return 1;
 69	}
 70
 71	sve = (struct sve_context *)head;
 72	if (sve->vl != vl) {
 73		fprintf(stderr, "Got VL %d, expected %d\n", sve->vl, vl);
 74		return 1;
 75	}
 76
 77	/* The actual size validation is done in get_current_context() */
 78	fprintf(stderr, "Got expected size %u and VL %d\n",
 79		head->size, sve->vl);
 80
 81	return 0;
 82}
 83
 84static int sve_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
 85{
 86	int i;
 87
 88	for (i = 0; i < nvls; i++) {
 89		if (do_one_sve_vl(td, si, uc, vls[i]))
 90			return 1;
 91	}
 92
 93	td->pass = 1;
 94
 95	return 0;
 96}
 97
 98struct tdescr tde = {
 99	.name = "SVE registers",
100	.descr = "Check that we get the right SVE registers reported",
101	.feats_required = FEAT_SVE,
102	.timeout = 3,
103	.init = sve_get_vls,
104	.run = sve_regs,
105};
~/ Read-only file preview.