[RFC PATCH v7 19/21] riscv: Fix an illegal instruction exception when accessing vlenb without enable vector first
Greentime Hu
greentime.hu at sifive.com
Thu Sep 10 04:12:14 EDT 2020
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.
Signed-off-by: Greentime Hu <greentime.hu at sifive.com>
---
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 3fc8d84e23c6..a99bbda7f4ba 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -10,6 +10,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 4d4f78f6a5db..817980d38603 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;
bool has_fpu __read_mostly;
#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 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.28.0
More information about the linux-riscv
mailing list