Unverified Commit ac295b67 authored by Andy Chiu's avatar Andy Chiu Committed by Palmer Dabbelt
Browse files

riscv: vector: adjust minimum Vector requirement to ZVE32X



Make has_vector() to check for ZVE32X. Every in-kernel usage of V that
requires a more complicate version of V must then call out explicitly.

Also, change riscv_v_first_use_handler(), and boot code that calls
riscv_v_setup_vsize() to accept ZVE32X.

Most kernel/user interfaces requires minimum of ZVE32X. Thus, programs
compiled and run with ZVE32X should be supported by the kernel on most
aspects. This includes context-switch, signal, ptrace, prctl, and
hwprobe.

One exception is that ELF_HWCAP returns 'V' only if full V is supported
on the platform. This means that the system without a full V must not
rely on ELF_HWCAP to tell whether it is allowable to execute Vector
without first invoking a prctl() check.

Signed-off-by: default avatarAndy Chiu <andy.chiu@sifive.com>
Acked-by: default avatarJoel Granados <j.granados@samsung.com>
Link: https://lore.kernel.org/r/20240510-zve-detection-v5-7-0711bdd26c12@sifive.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent de8f8282
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ static inline u32 riscv_v_flags(void)

static __always_inline bool has_vector(void)
{
	return riscv_has_extension_unlikely(RISCV_ISA_EXT_v);
	return riscv_has_extension_unlikely(RISCV_ISA_EXT_ZVE32X);
}

static inline void __riscv_v_vstate_clean(struct pt_regs *regs)
@@ -91,7 +91,7 @@ static __always_inline void __vstate_csr_restore(struct __riscv_v_ext_state *src
{
	asm volatile (
		".option push\n\t"
		".option arch, +v\n\t"
		".option arch, +zve32x\n\t"
		"vsetvl	 x0, %2, %1\n\t"
		".option pop\n\t"
		"csrw	" __stringify(CSR_VSTART) ", %0\n\t"
@@ -109,7 +109,7 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
	__vstate_csr_save(save_to);
	asm volatile (
		".option push\n\t"
		".option arch, +v\n\t"
		".option arch, +zve32x\n\t"
		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
		"vse8.v		v0, (%1)\n\t"
		"add		%1, %1, %0\n\t"
@@ -131,7 +131,7 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
	riscv_v_enable();
	asm volatile (
		".option push\n\t"
		".option arch, +v\n\t"
		".option arch, +zve32x\n\t"
		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
		"vle8.v		v0, (%1)\n\t"
		"add		%1, %1, %0\n\t"
@@ -153,7 +153,7 @@ static inline void __riscv_v_vstate_discard(void)
	riscv_v_enable();
	asm volatile (
		".option push\n\t"
		".option arch, +v\n\t"
		".option arch, +zve32x\n\t"
		"vsetvli	%0, x0, e8, m8, ta, ma\n\t"
		"vmv.v.i	v0, -1\n\t"
		"vmv.v.i	v8, -1\n\t"
+4 −1
Original line number Diff line number Diff line
@@ -724,11 +724,14 @@ void __init riscv_fill_hwcap(void)
		elf_hwcap &= ~COMPAT_HWCAP_ISA_F;
	}

	if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
	if (__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZVE32X)) {
		/*
		 * This cannot fail when called on the boot hart
		 */
		riscv_v_setup_vsize();
	}

	if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
		/*
		 * ISA string in device tree might have 'v' flag, but
		 * CONFIG_RISCV_ISA_V is disabled in kernel.
+5 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
	if (riscv_isa_extension_available(NULL, c))
		pair->value |= RISCV_HWPROBE_IMA_C;

	if (has_vector())
	if (has_vector() && riscv_isa_extension_available(NULL, v))
		pair->value |= RISCV_HWPROBE_IMA_V;

	/*
@@ -113,6 +113,10 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
		EXT_KEY(ZICOND);
		EXT_KEY(ZIHINTPAUSE);

		/*
		 * All the following extensions must depend on the kernel
		 * support of V.
		 */
		if (has_vector()) {
			EXT_KEY(ZVE32X);
			EXT_KEY(ZVE32F);
+4 −1
Original line number Diff line number Diff line
@@ -173,8 +173,11 @@ bool riscv_v_first_use_handler(struct pt_regs *regs)
	u32 __user *epc = (u32 __user *)regs->epc;
	u32 insn = (u32)regs->badaddr;

	if (!has_vector())
		return false;

	/* Do not handle if V is not supported, or disabled */
	if (!(ELF_HWCAP & COMPAT_HWCAP_ISA_V))
	if (!riscv_v_vstate_ctrl_user_allowed())
		return false;

	/* If V has been enabled then it is not the first-use trap */
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@

SYM_FUNC_START(__asm_copy_to_user)
#ifdef CONFIG_RISCV_ISA_V
	ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_v, CONFIG_RISCV_ISA_V)
	ALTERNATIVE("j fallback_scalar_usercopy", "nop", 0, RISCV_ISA_EXT_ZVE32X, CONFIG_RISCV_ISA_V)
	REG_L	t0, riscv_v_usercopy_threshold
	bltu	a2, t0, fallback_scalar_usercopy
	tail enter_vector_usercopy