[RFC PATCH v8 18/21] riscv: Fix an illegal instruction exception when accessing vlenb without enable vector first
From: Greentime Hu
Date: Wed Sep 08 2021 - 13:46:46 EST
It triggered an illegal instruction exception when accessing vlenb CSR
without enable vector first. To fix this issue, we should enable vector
before using it and disable vector after using it.
Co-developed-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Greentime Hu <greentime.hu@xxxxxxxxxx>
---
arch/riscv/include/asm/vector.h | 2 ++
arch/riscv/kernel/cpufeature.c | 3 +++
arch/riscv/kernel/kernel_mode_vector.c | 6 ++++--
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index 5d7f14453f68..ca063c8f47f2 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -8,6 +8,8 @@
#include <linux/types.h>
+void rvv_enable(void);
+void rvv_disable(void);
void kernel_rvv_begin(void);
void kernel_rvv_end(void);
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 7265d947d981..af984f875f60 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -22,6 +22,7 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
__ro_after_init DEFINE_STATIC_KEY_FALSE(cpu_hwcap_fpu);
#endif
#ifdef CONFIG_VECTOR
+#include <asm/vector.h>
bool has_vector __read_mostly;
unsigned long riscv_vsize __read_mostly;
#endif
@@ -158,7 +159,9 @@ void __init riscv_fill_hwcap(void)
if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
has_vector = true;
/* There are 32 vector registers with vlenb length. */
+ rvv_enable();
riscv_vsize = csr_read(CSR_VLENB) * 32;
+ rvv_disable();
}
#endif
}
diff --git a/arch/riscv/kernel/kernel_mode_vector.c b/arch/riscv/kernel/kernel_mode_vector.c
index b84618630edf..0d990bd8b8dd 100644
--- a/arch/riscv/kernel/kernel_mode_vector.c
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -71,15 +71,17 @@ static void put_cpu_vector_context(void)
preempt_enable();
}
-static void rvv_enable(void)
+void rvv_enable(void)
{
csr_set(CSR_STATUS, SR_VS);
}
+EXPORT_SYMBOL(rvv_enable);
-static void rvv_disable(void)
+void rvv_disable(void)
{
csr_clear(CSR_STATUS, SR_VS);
}
+EXPORT_SYMBOL(rvv_disable);
static void vector_flush_cpu_state(void)
{
--
2.31.1