[PATCH v2] target/riscv: Apply UXL WARL handling to vsstatus

SeungJu Cheon posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260625081521.595683-1-suunj1331@gmail.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu.zevorn@gmail.com>
target/riscv/csr.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
[PATCH v2] target/riscv: Apply UXL WARL handling to vsstatus
Posted by SeungJu Cheon 1 month ago
write_mstatus() already handles the reserved UXL value by writing a
legal value instead.

Apply the same handling when writing vsstatus so that reserved UXL
values follow the same WARL behavior.

Factor the common logic into a local helper riscv_write_uxl() and use
it for both mstatus and vsstatus.

Suggested-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Fixes: f310df58bd2 ("target/riscv: Enable uxl field write")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
 target/riscv/csr.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index dd9726fcf4..12f1ce5180 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2012,6 +2012,20 @@ static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
     return val;
 }
 
+static uint64_t riscv_write_uxl(CPURISCVState *env, uint64_t val,
+                                uint64_t field)
+{
+    RISCVMXL xl = riscv_cpu_mxl(env);
+    uint64_t uxl = get_field(val, field);
+
+    if (uxl == MXL_RV128) {
+        uxl = xl == MXL_RV128 ? MXL_RV64 : xl;
+        val = set_field(val, field, uxl);
+    }
+
+    return val;
+}
+
 static RISCVException write_mstatus(CPURISCVState *env, int csrno,
                                     target_ulong val, uintptr_t ra)
 {
@@ -2058,17 +2072,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
 
     if (xl != MXL_RV32 || env->debugger) {
         if ((val & MSTATUS64_UXL) != 0) {
-            uint64_t uxl = val & MSTATUS64_UXL >> 32;
             mask |= MSTATUS64_UXL;
-
-            /*
-             * uxl = 3 is reserved so write the current xl instead.
-             * In case xl = MXL_RV128 (3) write MXL_RV64.
-             */
-            if (uxl == 3) {
-                uxl = xl == MXL_RV128 ? MXL_RV64 : xl;
-                val = deposit64(val, 32, 2, uxl);
-            }
+            val = riscv_write_uxl(env, val, MSTATUS64_UXL);
         }
     }
 
@@ -5226,6 +5231,8 @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
     uint64_t mask = (target_ulong)-1;
     if ((val & VSSTATUS64_UXL) == 0) {
         mask &= ~VSSTATUS64_UXL;
+    } else {
+        val = riscv_write_uxl(env, val, VSSTATUS64_UXL);
     }
     if ((env->henvcfg & HENVCFG_DTE)) {
         if ((val & SSTATUS_SDT) != 0) {
-- 
2.52.0
Re: [PATCH v2] target/riscv: Apply UXL WARL handling to vsstatus
Posted by Alistair Francis 3 weeks, 6 days ago
On Thu, Jun 25, 2026 at 6:17 PM SeungJu Cheon <suunj1331@gmail.com> wrote:
>
> write_mstatus() already handles the reserved UXL value by writing a
> legal value instead.
>
> Apply the same handling when writing vsstatus so that reserved UXL
> values follow the same WARL behavior.
>
> Factor the common logic into a local helper riscv_write_uxl() and use
> it for both mstatus and vsstatus.
>
> Suggested-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Fixes: f310df58bd2 ("target/riscv: Enable uxl field write")
> Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/csr.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index dd9726fcf4..12f1ce5180 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2012,6 +2012,20 @@ static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
>      return val;
>  }
>
> +static uint64_t riscv_write_uxl(CPURISCVState *env, uint64_t val,
> +                                uint64_t field)
> +{
> +    RISCVMXL xl = riscv_cpu_mxl(env);
> +    uint64_t uxl = get_field(val, field);
> +
> +    if (uxl == MXL_RV128) {
> +        uxl = xl == MXL_RV128 ? MXL_RV64 : xl;
> +        val = set_field(val, field, uxl);
> +    }
> +
> +    return val;
> +}
> +
>  static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>                                      target_ulong val, uintptr_t ra)
>  {
> @@ -2058,17 +2072,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>
>      if (xl != MXL_RV32 || env->debugger) {
>          if ((val & MSTATUS64_UXL) != 0) {
> -            uint64_t uxl = val & MSTATUS64_UXL >> 32;
>              mask |= MSTATUS64_UXL;
> -
> -            /*
> -             * uxl = 3 is reserved so write the current xl instead.
> -             * In case xl = MXL_RV128 (3) write MXL_RV64.
> -             */
> -            if (uxl == 3) {
> -                uxl = xl == MXL_RV128 ? MXL_RV64 : xl;
> -                val = deposit64(val, 32, 2, uxl);
> -            }
> +            val = riscv_write_uxl(env, val, MSTATUS64_UXL);
>          }
>      }
>
> @@ -5226,6 +5231,8 @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
>      uint64_t mask = (target_ulong)-1;
>      if ((val & VSSTATUS64_UXL) == 0) {
>          mask &= ~VSSTATUS64_UXL;
> +    } else {
> +        val = riscv_write_uxl(env, val, VSSTATUS64_UXL);
>      }
>      if ((env->henvcfg & HENVCFG_DTE)) {
>          if ((val & SSTATUS_SDT) != 0) {
> --
> 2.52.0
>
>
Re: [PATCH v2] target/riscv: Apply UXL WARL handling to vsstatus
Posted by Daniel Henrique Barboza 1 month ago

On 6/25/2026 5:15 AM, SeungJu Cheon wrote:
> write_mstatus() already handles the reserved UXL value by writing a
> legal value instead.
> 
> Apply the same handling when writing vsstatus so that reserved UXL
> values follow the same WARL behavior.
> 
> Factor the common logic into a local helper riscv_write_uxl() and use
> it for both mstatus and vsstatus.
> 
> Suggested-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Fixes: f310df58bd2 ("target/riscv: Enable uxl field write")
> Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
> ---

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>

>   target/riscv/csr.c | 27 +++++++++++++++++----------
>   1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index dd9726fcf4..12f1ce5180 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2012,6 +2012,20 @@ static target_ulong legalize_mpp(CPURISCVState *env, target_ulong old_mpp,
>       return val;
>   }
>   
> +static uint64_t riscv_write_uxl(CPURISCVState *env, uint64_t val,
> +                                uint64_t field)
> +{
> +    RISCVMXL xl = riscv_cpu_mxl(env);
> +    uint64_t uxl = get_field(val, field);
> +
> +    if (uxl == MXL_RV128) {
> +        uxl = xl == MXL_RV128 ? MXL_RV64 : xl;
> +        val = set_field(val, field, uxl);
> +    }
> +
> +    return val;
> +}
> +
>   static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>                                       target_ulong val, uintptr_t ra)
>   {
> @@ -2058,17 +2072,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>   
>       if (xl != MXL_RV32 || env->debugger) {
>           if ((val & MSTATUS64_UXL) != 0) {
> -            uint64_t uxl = val & MSTATUS64_UXL >> 32;
>               mask |= MSTATUS64_UXL;
> -
> -            /*
> -             * uxl = 3 is reserved so write the current xl instead.
> -             * In case xl = MXL_RV128 (3) write MXL_RV64.
> -             */
> -            if (uxl == 3) {
> -                uxl = xl == MXL_RV128 ? MXL_RV64 : xl;
> -                val = deposit64(val, 32, 2, uxl);
> -            }
> +            val = riscv_write_uxl(env, val, MSTATUS64_UXL);
>           }
>       }
>   
> @@ -5226,6 +5231,8 @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
>       uint64_t mask = (target_ulong)-1;
>       if ((val & VSSTATUS64_UXL) == 0) {
>           mask &= ~VSSTATUS64_UXL;
> +    } else {
> +        val = riscv_write_uxl(env, val, VSSTATUS64_UXL);
>       }
>       if ((env->henvcfg & HENVCFG_DTE)) {
>           if ((val & SSTATUS_SDT) != 0) {