brintos

brintos / linux-shallow public Read only

0
0
Text · 1.3 KiB · 0acc121 Raw
57 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2024 ARM Limited4 *5 * Common helper functions for SVE and SME functionality.6 */7 8#include <stdbool.h>9#include <kselftest.h>10#include <asm/sigcontext.h>11#include <sys/prctl.h>12 13unsigned int vls[SVE_VQ_MAX];14unsigned int nvls;15 16int sve_fill_vls(bool use_sme, int min_vls)17{18	int vq, vl;19	int pr_set_vl = use_sme ? PR_SME_SET_VL : PR_SVE_SET_VL;20	int len_mask = use_sme ? PR_SME_VL_LEN_MASK : PR_SVE_VL_LEN_MASK;21 22	/*23	 * Enumerate up to SVE_VQ_MAX vector lengths24	 */25	for (vq = SVE_VQ_MAX; vq > 0; --vq) {26		vl = prctl(pr_set_vl, vq * 16);27		if (vl == -1)28			return KSFT_FAIL;29 30		vl &= len_mask;31 32		/*33		 * Unlike SVE, SME does not require the minimum vector length34		 * to be implemented, or the VLs to be consecutive, so any call35		 * to the prctl might return the single implemented VL, which36		 * might be larger than 16. So to avoid this loop never37		 * terminating,  bail out here when we find a higher VL than38		 * we asked for.39		 * See the ARM ARM, DDI 0487K.a, B1.4.2: I_QQRNR and I_NWYBP.40		 */41		if (vq < sve_vq_from_vl(vl))42			break;43 44		/* Skip missing VLs */45		vq = sve_vq_from_vl(vl);46 47		vls[nvls++] = vl;48	}49 50	if (nvls < min_vls) {51		fprintf(stderr, "Only %d VL supported\n", nvls);52		return KSFT_SKIP;53	}54 55	return KSFT_PASS;56}57