Skip to content

Commit 9324571

Browse files
ConchuODAlexandre Ghiti
authored andcommitted
RISC-V: add vector extension validation checks
Using Clement's new validation callbacks, support checking that dependencies have been satisfied for the vector extensions. From the kernel's perfective, it's not required to differentiate between the conditions for all the various vector subsets - it's the firmware's job to not report impossible combinations. Instead, the kernel only has to check that the correct config options are enabled and to enforce its requirement of the d extension being present for FPU support. Since vector will now be disabled proactively, there's no need to clear the bit in elf_hwcap in riscv_fill_hwcap() any longer. Signed-off-by: Conor Dooley <conor.dooley@microchip.com> Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com> Link: https://lore.kernel.org/r/20250312-eclair-affluent-55b098c3602b@spud Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
1 parent 4701f33 commit 9324571

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

arch/riscv/include/asm/cpufeature.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ void __init riscv_user_isa_enable(void);
5656
#define __RISCV_ISA_EXT_BUNDLE(_name, _bundled_exts) \
5757
_RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
5858
ARRAY_SIZE(_bundled_exts), NULL)
59+
#define __RISCV_ISA_EXT_BUNDLE_VALIDATE(_name, _bundled_exts, _validate) \
60+
_RISCV_ISA_EXT_DATA(_name, RISCV_ISA_EXT_INVALID, _bundled_exts, \
61+
ARRAY_SIZE(_bundled_exts), _validate)
5962

6063
/* Used to declare extensions that are a superset of other extensions (Zvbb for instance) */
6164
#define __RISCV_ISA_EXT_SUPERSET(_name, _id, _sub_exts) \

arch/riscv/kernel/cpufeature.c

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,38 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data,
109109
return 0;
110110
}
111111

112+
static int riscv_ext_vector_x_validate(const struct riscv_isa_ext_data *data,
113+
const unsigned long *isa_bitmap)
114+
{
115+
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
116+
return -EINVAL;
117+
118+
return 0;
119+
}
120+
121+
static int riscv_ext_vector_float_validate(const struct riscv_isa_ext_data *data,
122+
const unsigned long *isa_bitmap)
123+
{
124+
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
125+
return -EINVAL;
126+
127+
if (!IS_ENABLED(CONFIG_FPU))
128+
return -EINVAL;
129+
130+
/*
131+
* The kernel doesn't support systems that don't implement both of
132+
* F and D, so if any of the vector extensions that do floating point
133+
* are to be usable, both floating point extensions need to be usable.
134+
*
135+
* Since this function validates vector only, and v/Zve* are probed
136+
* after f/d, there's no need for a deferral here.
137+
*/
138+
if (!__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_d))
139+
return -EINVAL;
140+
141+
return 0;
142+
}
143+
112144
static int riscv_ext_zca_depends(const struct riscv_isa_ext_data *data,
113145
const unsigned long *isa_bitmap)
114146
{
@@ -326,12 +358,10 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
326358
__RISCV_ISA_EXT_DATA(d, RISCV_ISA_EXT_d),
327359
__RISCV_ISA_EXT_DATA(q, RISCV_ISA_EXT_q),
328360
__RISCV_ISA_EXT_SUPERSET(c, RISCV_ISA_EXT_c, riscv_c_exts),
329-
__RISCV_ISA_EXT_SUPERSET(v, RISCV_ISA_EXT_v, riscv_v_exts),
361+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(v, RISCV_ISA_EXT_v, riscv_v_exts, riscv_ext_vector_float_validate),
330362
__RISCV_ISA_EXT_DATA(h, RISCV_ISA_EXT_h),
331-
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts,
332-
riscv_ext_zicbom_validate),
333-
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts,
334-
riscv_ext_zicboz_validate),
363+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicbom, RISCV_ISA_EXT_ZICBOM, riscv_xlinuxenvcfg_exts, riscv_ext_zicbom_validate),
364+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zicboz, RISCV_ISA_EXT_ZICBOZ, riscv_xlinuxenvcfg_exts, riscv_ext_zicboz_validate),
335365
__RISCV_ISA_EXT_DATA(ziccrse, RISCV_ISA_EXT_ZICCRSE),
336366
__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
337367
__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
@@ -372,11 +402,11 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
372402
__RISCV_ISA_EXT_DATA(ztso, RISCV_ISA_EXT_ZTSO),
373403
__RISCV_ISA_EXT_SUPERSET(zvbb, RISCV_ISA_EXT_ZVBB, riscv_zvbb_exts),
374404
__RISCV_ISA_EXT_DATA(zvbc, RISCV_ISA_EXT_ZVBC),
375-
__RISCV_ISA_EXT_SUPERSET(zve32f, RISCV_ISA_EXT_ZVE32F, riscv_zve32f_exts),
376-
__RISCV_ISA_EXT_DATA(zve32x, RISCV_ISA_EXT_ZVE32X),
377-
__RISCV_ISA_EXT_SUPERSET(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts),
378-
__RISCV_ISA_EXT_SUPERSET(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts),
379-
__RISCV_ISA_EXT_SUPERSET(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts),
405+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve32f, RISCV_ISA_EXT_ZVE32F, riscv_zve32f_exts, riscv_ext_vector_float_validate),
406+
__RISCV_ISA_EXT_DATA_VALIDATE(zve32x, RISCV_ISA_EXT_ZVE32X, riscv_ext_vector_x_validate),
407+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64d, RISCV_ISA_EXT_ZVE64D, riscv_zve64d_exts, riscv_ext_vector_float_validate),
408+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64f, RISCV_ISA_EXT_ZVE64F, riscv_zve64f_exts, riscv_ext_vector_float_validate),
409+
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate),
380410
__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
381411
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
382412
__RISCV_ISA_EXT_DATA(zvkb, RISCV_ISA_EXT_ZVKB),
@@ -960,16 +990,6 @@ void __init riscv_fill_hwcap(void)
960990
riscv_v_setup_vsize();
961991
}
962992

963-
if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
964-
/*
965-
* ISA string in device tree might have 'v' flag, but
966-
* CONFIG_RISCV_ISA_V is disabled in kernel.
967-
* Clear V flag in elf_hwcap if CONFIG_RISCV_ISA_V is disabled.
968-
*/
969-
if (!IS_ENABLED(CONFIG_RISCV_ISA_V))
970-
elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
971-
}
972-
973993
memset(print_str, 0, sizeof(print_str));
974994
for (i = 0, j = 0; i < NUM_ALPHA_EXTS; i++)
975995
if (riscv_isa[0] & BIT_MASK(i))

0 commit comments

Comments
 (0)