Path: blob/master/tools/testing/selftests/arm64/signal/sve_helpers.c
26292 views
// SPDX-License-Identifier: GPL-2.01/*2* Copyright (C) 2024 ARM Limited3*4* Common helper functions for SVE and SME functionality.5*/67#include <stdbool.h>8#include <kselftest.h>9#include <asm/sigcontext.h>10#include <sys/prctl.h>1112unsigned int vls[SVE_VQ_MAX];13unsigned int nvls;1415int sve_fill_vls(bool use_sme, int min_vls)16{17int vq, vl;18int pr_set_vl = use_sme ? PR_SME_SET_VL : PR_SVE_SET_VL;19int len_mask = use_sme ? PR_SME_VL_LEN_MASK : PR_SVE_VL_LEN_MASK;2021/*22* Enumerate up to SVE_VQ_MAX vector lengths23*/24for (vq = SVE_VQ_MAX; vq > 0; --vq) {25vl = prctl(pr_set_vl, vq * 16);26if (vl == -1)27return KSFT_FAIL;2829vl &= len_mask;3031/*32* Unlike SVE, SME does not require the minimum vector length33* to be implemented, or the VLs to be consecutive, so any call34* to the prctl might return the single implemented VL, which35* might be larger than 16. So to avoid this loop never36* terminating, bail out here when we find a higher VL than37* we asked for.38* See the ARM ARM, DDI 0487K.a, B1.4.2: I_QQRNR and I_NWYBP.39*/40if (vq < sve_vq_from_vl(vl))41break;4243/* Skip missing VLs */44vq = sve_vq_from_vl(vl);4546vls[nvls++] = vl;47}4849if (nvls < min_vls) {50fprintf(stderr, "Only %d VL supported\n", nvls);51return KSFT_SKIP;52}5354return KSFT_PASS;55}565758