[RFC PATCH] riscv: cpu: check U-Mode before counteren write

From: Nikita Shubin n.shubin@yadro.com
The Priv ISA states: "In systems without U-mode, the mcounteren register should not exist."
Check U-Mode is present in MISA before writing to counteren, otherwise we endup with Illegal Instruction exception on systems without U-Mode.
Also make checking MISA default for M-Mode.
Signed-off-by: Nikita Shubin n.shubin@yadro.com --- This seems obvious at first glance, but i've never seen 'u' extension enywhere in "riscv,isa" device tree property, even qemu doesn't set this, and if we simply enable this check - this will break existing board for sure.
We can rely on MISA completely if we are in M-Mode, as we currently check only 'd', 'f' and 'u', which are standart and nothing fancy. --- arch/riscv/cpu/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 0f323b26b3..917f71c8d7 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -31,7 +31,9 @@ u32 available_harts_lock = 1;
static inline bool supports_extension(char ext) { -#ifdef CONFIG_CPU +#if CONFIG_IS_ENABLED(RISCV_MMODE) + return csr_read(CSR_MISA) & (1 << (ext - 'a')); +#elif CONFIG_CPU struct udevice *dev; char desc[32];
@@ -48,13 +50,9 @@ static inline bool supports_extension(char ext)
return false; #else /* !CONFIG_CPU */ -#if CONFIG_IS_ENABLED(RISCV_MMODE) - return csr_read(CSR_MISA) & (1 << (ext - 'a')); -#else /* !CONFIG_IS_ENABLED(RISCV_MMODE) */ #warning "There is no way to determine the available extensions in S-mode." #warning "Please convert your board to use the RISC-V CPU driver." return false; -#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */ #endif /* CONFIG_CPU */ }
@@ -102,12 +100,14 @@ int riscv_cpu_setup(void *ctx, struct event *event) * Enable perf counters for cycle, time, * and instret counters only */ + if (supports_extension('u')) { #ifdef CONFIG_RISCV_PRIV_1_9 - csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0)); - csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0)); + csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0)); + csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0)); #else - csr_write(CSR_MCOUNTEREN, GENMASK(2, 0)); + csr_write(CSR_MCOUNTEREN, GENMASK(2, 0)); #endif + }
/* Disable paging */ if (supports_extension('s'))

On Wed, Dec 14, 2022 at 08:58:43AM +0300, Nikita Shubin wrote:
From: Nikita Shubin n.shubin@yadro.com
The Priv ISA states: "In systems without U-mode, the mcounteren register should not exist."
Check U-Mode is present in MISA before writing to counteren, otherwise we endup with Illegal Instruction exception on systems without U-Mode.
Also make checking MISA default for M-Mode.
Signed-off-by: Nikita Shubin n.shubin@yadro.com
This seems obvious at first glance, but i've never seen 'u' extension enywhere in "riscv,isa" device tree property, even qemu doesn't set this, and if we simply enable this check - this will break existing board for sure.
We can rely on MISA completely if we are in M-Mode, as we currently check only 'd', 'f' and 'u', which are standart and nothing fancy.
arch/riscv/cpu/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
Reviewed-by: Leo Yu-Chi Liang ycliang@andestech.com
participants (2)
-
Leo Liang
-
Nikita Shubin