[PATCH] target/riscv/cpu_helper.c: fault with reserved PTE.PBMT val

Daniel Henrique Barboza posted 1 patch 1 week, 2 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260521130727.2311629-1-daniel.barboza@oss.qualcomm.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/cpu_helper.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
[PATCH] target/riscv/cpu_helper.c: fault with reserved PTE.PBMT val
Posted by Daniel Henrique Barboza 1 week, 2 days ago
We need to fault during any access done while PTE bits 62-61 are both
set, according to the RISC-V priv spec.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3494
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
 target/riscv/cpu_helper.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 17305e1bb7..bc63713ddf 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1446,6 +1446,25 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
                 return TRANSLATE_FAIL;
             }
 
+            /*
+             * priv spec, "Svpbmt" chapter:
+             * "For non-leaf PTEs, bits 62-61 are reserved for future
+             * standard use.  Until their use is defined by a standard
+             * extension, they must be cleared by software for forward
+             * compatibility, or else a page-fault exception is raised."
+             *
+             * For leaf PTEs the same bits are also reserved but in that
+             * case the page-fault is mandatory.  Make both cases consistent
+             * by also page faulting here.
+             */
+            if ((pte & PTE_PBMT) == PTE_PBMT) {
+                qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are "
+                        "reserved but are set in PTE: "
+                        "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
+                        __func__, pte_addr, pte);
+                return TRANSLATE_FAIL;
+            }
+
             if (!riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
                 /* Reserved without Svnapot extension */
                 qemu_log_mask(LOG_GUEST_ERROR, "%s: N bit set in PTE, "
@@ -1498,6 +1517,23 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
         return TRANSLATE_FAIL;
     }
 
+    /*
+     * priv spec, "Svpbmt" chapter:
+     * "For leaf PTEs, setting bits 62-61 to the value 3 is reserved
+     * for future standard use. Until this value is defined by a
+     * standard extension, using this reserved value in a leaf PTE
+     * raises a page-fault exception. "
+     *
+     * Raise a fault if 62-61 (i.e. PTE_PBMT) are set.
+     */
+    if ((pte & PTE_PBMT) == PTE_PBMT) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are "
+                      "reserved but are set in leaf PTE: "
+                      "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
+                      __func__, pte_addr, pte);
+        return TRANSLATE_FAIL;
+    }
+
     target_ulong rwx = pte & (PTE_R | PTE_W | PTE_X);
     /* Check for reserved combinations of RWX flags. */
     switch (rwx) {
-- 
2.43.0
Re: [PATCH] target/riscv/cpu_helper.c: fault with reserved PTE.PBMT val
Posted by Alistair Francis 3 days, 15 hours ago
On Thu, 2026-05-21 at 10:07 -0300, Daniel Henrique Barboza wrote:
> We need to fault during any access done while PTE bits 62-61 are both
> set, according to the RISC-V priv spec.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3494
> Signed-off-by: Daniel Henrique Barboza
> <daniel.barboza@oss.qualcomm.com>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/cpu_helper.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 17305e1bb7..bc63713ddf 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -1446,6 +1446,25 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>                  return TRANSLATE_FAIL;
>              }
>  
> +            /*
> +             * priv spec, "Svpbmt" chapter:
> +             * "For non-leaf PTEs, bits 62-61 are reserved for
> future
> +             * standard use.  Until their use is defined by a
> standard
> +             * extension, they must be cleared by software for
> forward
> +             * compatibility, or else a page-fault exception is
> raised."
> +             *
> +             * For leaf PTEs the same bits are also reserved but in
> that
> +             * case the page-fault is mandatory.  Make both cases
> consistent
> +             * by also page faulting here.
> +             */
> +            if ((pte & PTE_PBMT) == PTE_PBMT) {
> +                qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and
> 61 are "
> +                        "reserved but are set in PTE: "
> +                        "addr: 0x%" HWADDR_PRIx " pte: 0x"
> TARGET_FMT_lx "\n",
> +                        __func__, pte_addr, pte);
> +                return TRANSLATE_FAIL;
> +            }
> +
>              if (!riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
>                  /* Reserved without Svnapot extension */
>                  qemu_log_mask(LOG_GUEST_ERROR, "%s: N bit set in
> PTE, "
> @@ -1498,6 +1517,23 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>          return TRANSLATE_FAIL;
>      }
>  
> +    /*
> +     * priv spec, "Svpbmt" chapter:
> +     * "For leaf PTEs, setting bits 62-61 to the value 3 is reserved
> +     * for future standard use. Until this value is defined by a
> +     * standard extension, using this reserved value in a leaf PTE
> +     * raises a page-fault exception. "
> +     *
> +     * Raise a fault if 62-61 (i.e. PTE_PBMT) are set.
> +     */
> +    if ((pte & PTE_PBMT) == PTE_PBMT) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are
> "
> +                      "reserved but are set in leaf PTE: "
> +                      "addr: 0x%" HWADDR_PRIx " pte: 0x"
> TARGET_FMT_lx "\n",
> +                      __func__, pte_addr, pte);
> +        return TRANSLATE_FAIL;
> +    }
> +
>      target_ulong rwx = pte & (PTE_R | PTE_W | PTE_X);
>      /* Check for reserved combinations of RWX flags. */
>      switch (rwx) {
Re: [PATCH] target/riscv/cpu_helper.c: fault with reserved PTE.PBMT val
Posted by Alistair Francis 3 days, 16 hours ago
On Thu, 2026-05-21 at 10:07 -0300, Daniel Henrique Barboza wrote:
> We need to fault during any access done while PTE bits 62-61 are both
> set, according to the RISC-V priv spec.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3494
> Signed-off-by: Daniel Henrique Barboza
> <daniel.barboza@oss.qualcomm.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu_helper.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 17305e1bb7..bc63713ddf 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -1446,6 +1446,25 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>                  return TRANSLATE_FAIL;
>              }
>  
> +            /*
> +             * priv spec, "Svpbmt" chapter:
> +             * "For non-leaf PTEs, bits 62-61 are reserved for
> future
> +             * standard use.  Until their use is defined by a
> standard
> +             * extension, they must be cleared by software for
> forward
> +             * compatibility, or else a page-fault exception is
> raised."
> +             *
> +             * For leaf PTEs the same bits are also reserved but in
> that
> +             * case the page-fault is mandatory.  Make both cases
> consistent
> +             * by also page faulting here.
> +             */
> +            if ((pte & PTE_PBMT) == PTE_PBMT) {
> +                qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and
> 61 are "
> +                        "reserved but are set in PTE: "
> +                        "addr: 0x%" HWADDR_PRIx " pte: 0x"
> TARGET_FMT_lx "\n",
> +                        __func__, pte_addr, pte);
> +                return TRANSLATE_FAIL;
> +            }
> +
>              if (!riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
>                  /* Reserved without Svnapot extension */
>                  qemu_log_mask(LOG_GUEST_ERROR, "%s: N bit set in
> PTE, "
> @@ -1498,6 +1517,23 @@ static int get_physical_address(CPURISCVState
> *env, hwaddr *physical,
>          return TRANSLATE_FAIL;
>      }
>  
> +    /*
> +     * priv spec, "Svpbmt" chapter:
> +     * "For leaf PTEs, setting bits 62-61 to the value 3 is reserved
> +     * for future standard use. Until this value is defined by a
> +     * standard extension, using this reserved value in a leaf PTE
> +     * raises a page-fault exception. "
> +     *
> +     * Raise a fault if 62-61 (i.e. PTE_PBMT) are set.
> +     */
> +    if ((pte & PTE_PBMT) == PTE_PBMT) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are
> "
> +                      "reserved but are set in leaf PTE: "
> +                      "addr: 0x%" HWADDR_PRIx " pte: 0x"
> TARGET_FMT_lx "\n",
> +                      __func__, pte_addr, pte);
> +        return TRANSLATE_FAIL;
> +    }
> +
>      target_ulong rwx = pte & (PTE_R | PTE_W | PTE_X);
>      /* Check for reserved combinations of RWX flags. */
>      switch (rwx) {