summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBin Meng <bmeng@tinylab.org>2023-04-17 12:30:54 +0800
committerAlistair Francis <alistair.francis@wdc.com>2023-05-05 10:49:50 +1000
commiteae04c4c131a8d95087c8568eb2cac1988262f25 (patch)
tree912c19914389dc2da2c5bef23677a1a36a074fb1
parent9e1a30d34212ae05e884c20afad48626cd8070cd (diff)
downloadfocaccia-qemu-eae04c4c131a8d95087c8568eb2cac1988262f25.tar.gz
focaccia-qemu-eae04c4c131a8d95087c8568eb2cac1988262f25.zip
target/riscv: Restore the predicate() NULL check behavior
When reading a non-existent CSR QEMU should raise illegal instruction
exception, but currently it just exits due to the g_assert() check.

This actually reverts commit 0ee342256af9205e7388efdf193a6d8f1ba1a617.
Some comments are also added to indicate that predicate() must be
provided for an implemented CSR.

Reported-by: Fei Wu <fei2.wu@intel.com>
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-Id: <20230417043054.3125614-1-bmeng@tinylab.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-rw-r--r--target/riscv/csr.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 865ee9efda..4451bd1263 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3826,6 +3826,11 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
         return RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* ensure CSR is implemented by checking predicate */
+    if (!csr_ops[csrno].predicate) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
+
     /* privileged spec version check */
     if (env->priv_ver < csr_min_priv) {
         return RISCV_EXCP_ILLEGAL_INST;
@@ -3843,7 +3848,6 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
      * illegal instruction exception should be triggered instead of virtual
      * instruction exception. Hence this comes after the read / write check.
      */
-    g_assert(csr_ops[csrno].predicate != NULL);
     RISCVException ret = csr_ops[csrno].predicate(env, csrno);
     if (ret != RISCV_EXCP_NONE) {
         return ret;
@@ -4032,7 +4036,10 @@ static RISCVException write_jvt(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
-/* Control and Status Register function table */
+/*
+ * Control and Status Register function table
+ * riscv_csr_operations::predicate() must be provided for an implemented CSR
+ */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     /* User Floating-Point CSRs */
     [CSR_FFLAGS]   = { "fflags",   fs,     read_fflags,  write_fflags },