Files
cubelinux-kernel/tools/testing/selftests/arm64/signal/sve_helpers.c
T
Greg Kroah-Hartman 598cf27219 Linux 6.19.3
Link: https://lore.kernel.org/r/20260217200002.683975158@linuxfoundation.org
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
Tested-by: Takeshi Ogasawara <takeshi.ogasawara@futuring-girl.com>
Tested-by: Peter Schneider <pschneider1968@googlemail.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Salvatore Bonaccorso <carnil@debian.org>
Tested-by: Brett A C Sheffield <bacs@librecast.net>
Tested-by: Mark Brown <broonie@kernel.org>
Tested-by: Luna Jernberg <droidbittin@gmail.com>
Tested-by: Ronald Warsow <rwarsow@gmx.de>
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
Tested-by: Ron Economos <re@w6rz.net>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-19 16:33:27 +01:00

57 lines
1.3 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2024 ARM Limited
*
* Common helper functions for SVE and SME functionality.
*/
#include <stdbool.h>
#include <kselftest.h>
#include <asm/sigcontext.h>
#include <sys/prctl.h>
unsigned int vls[SVE_VQ_MAX];
unsigned int nvls;
int sve_fill_vls(bool use_sme, int min_vls)
{
int vq, vl;
int pr_set_vl = use_sme ? PR_SME_SET_VL : PR_SVE_SET_VL;
int len_mask = use_sme ? PR_SME_VL_LEN_MASK : PR_SVE_VL_LEN_MASK;
/*
* Enumerate up to SVE_VQ_MAX vector lengths
*/
for (vq = SVE_VQ_MAX; vq > 0; --vq) {
vl = prctl(pr_set_vl, vq * 16);
if (vl == -1)
return KSFT_FAIL;
vl &= len_mask;
/*
* Unlike SVE, SME does not require the minimum vector length
* to be implemented, or the VLs to be consecutive, so any call
* to the prctl might return the single implemented VL, which
* might be larger than 16. So to avoid this loop never
* terminating, bail out here when we find a higher VL than
* we asked for.
* See the ARM ARM, DDI 0487K.a, B1.4.2: I_QQRNR and I_NWYBP.
*/
if (vq < sve_vq_from_vl(vl))
break;
/* Skip missing VLs */
vq = sve_vq_from_vl(vl);
vls[nvls++] = vl;
}
if (nvls < min_vls) {
fprintf(stderr, "Only %d VL supported\n", nvls);
return KSFT_SKIP;
}
return KSFT_PASS;
}