* [PATCH 0/2] hw/riscv/riscv-iommu.c: additional PTE checks
@ 2026-06-29 12:13 Daniel Henrique Barboza
2026-06-29 12:13 ` [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits Daniel Henrique Barboza
2026-06-29 12:13 ` [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access Daniel Henrique Barboza
0 siblings, 2 replies; 7+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-29 12:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, andrew.jones, Daniel Henrique Barboza
Hi,
This is a short series of mostly trivial patches that fixes two gitlab
bugs.
I'm sending them together because they happen to conflict with one
another if applied in separate.
Daniel Henrique Barboza (2):
hw/riscv/riscv-iommu.c: check for reserved PTE bits
hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access
hw/riscv/riscv-iommu.c | 10 ++++++++++
tests/qtest/libqos/qos-riscv-iommu.h | 4 ++--
2 files changed, 12 insertions(+), 2 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits
2026-06-29 12:13 [PATCH 0/2] hw/riscv/riscv-iommu.c: additional PTE checks Daniel Henrique Barboza
@ 2026-06-29 12:13 ` Daniel Henrique Barboza
2026-06-30 7:25 ` Nutty.Liu
2026-06-30 9:51 ` Chao Liu
2026-06-29 12:13 ` [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access Daniel Henrique Barboza
1 sibling, 2 replies; 7+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-29 12:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, andrew.jones, Daniel Henrique Barboza,
Palmer Dabbelt
We need to fault if reserved PTE bits (60:54) are set.
Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3554
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/riscv-iommu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index c9687e01a8..453601d7a5 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -468,6 +468,8 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
if (!(pte & PTE_V)) {
break; /* Invalid PTE */
+ } else if (pte & PTE_RESERVED(false)) {
+ break; /* Reserved PTE bits set */
} else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
} else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access
2026-06-29 12:13 [PATCH 0/2] hw/riscv/riscv-iommu.c: additional PTE checks Daniel Henrique Barboza
2026-06-29 12:13 ` [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits Daniel Henrique Barboza
@ 2026-06-29 12:13 ` Daniel Henrique Barboza
2026-06-30 7:38 ` Nutty.Liu
2026-06-30 9:51 ` Chao Liu
1 sibling, 2 replies; 7+ messages in thread
From: Daniel Henrique Barboza @ 2026-06-29 12:13 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, andrew.jones, Daniel Henrique Barboza,
Palmer Dabbelt, Tao Tang, Fabiano Rosas, Laurent Vivier,
Paolo Bonzini
All IOMMU accesses are assumed to be user mode unless told otherwise,
i.e. we have a process_id. In case we have a non-user mode leaf PTE
(PTE_U isn't set) and we are running in user mode, we need to throw a
fault.
This also reflects on qos-riscv-iommu tests: the tests always run in
user mode so our PTEs must have PTE_U (bit 0x10) set.
Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3553
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
hw/riscv/riscv-iommu.c | 8 ++++++++
tests/qtest/libqos/qos-riscv-iommu.h | 4 ++--
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
index 453601d7a5..e6d2ca94bc 100644
--- a/hw/riscv/riscv-iommu.c
+++ b/hw/riscv/riscv-iommu.c
@@ -297,6 +297,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
G_STAGE = 1,
} pass;
MemTxResult ret;
+ bool pv = !!ctx->process_id;
satp = get_field(ctx->satp, RISCV_IOMMU_ATP_MODE_FIELD);
gatp = get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD);
@@ -470,6 +471,13 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
break; /* Invalid PTE */
} else if (pte & PTE_RESERVED(false)) {
break; /* Reserved PTE bits set */
+ } else if (!(pte & PTE_U) && !pv) {
+ /*
+ * All accesses are assumed to be User mode unless
+ * process_id is valid (pv). In case we have a
+ * non-user mode PTE and !pv we need to fault.
+ */
+ break;
} else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
} else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
diff --git a/tests/qtest/libqos/qos-riscv-iommu.h b/tests/qtest/libqos/qos-riscv-iommu.h
index 90e69a5d73..c218e9d66d 100644
--- a/tests/qtest/libqos/qos-riscv-iommu.h
+++ b/tests/qtest/libqos/qos-riscv-iommu.h
@@ -54,8 +54,8 @@
* PTE masks for RISC-V IOMMU page tables.
* Values match PTE_V, PTE_R, PTE_W, PTE_A, PTE_D in target/riscv/cpu_bits.h
*/
-#define QRIOMMU_NON_LEAF_PTE_MASK 0x001 /* PTE_V */
-#define QRIOMMU_LEAF_PTE_RW_MASK 0x0c7 /* V|R|W|A|D */
+#define QRIOMMU_NON_LEAF_PTE_MASK 0x011 /* PTE_V | PTE_U */
+#define QRIOMMU_LEAF_PTE_RW_MASK 0x0d7 /* V | R | W | A | D | PTE_U */
#define QRIOMMU_PTE_PPN_MASK 0x003ffffffffffc00ull
/* Address-space base offset for test tables */
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits
2026-06-29 12:13 ` [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits Daniel Henrique Barboza
@ 2026-06-30 7:25 ` Nutty.Liu
2026-06-30 9:51 ` Chao Liu
1 sibling, 0 replies; 7+ messages in thread
From: Nutty.Liu @ 2026-06-30 7:25 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, andrew.jones, Palmer Dabbelt
On 6/29/2026 8:13 PM, Daniel Henrique Barboza wrote:
> We need to fault if reserved PTE bits (60:54) are set.
>
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3554
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Thanks,
Nutty
> ---
> hw/riscv/riscv-iommu.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index c9687e01a8..453601d7a5 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -468,6 +468,8 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
>
> if (!(pte & PTE_V)) {
> break; /* Invalid PTE */
> + } else if (pte & PTE_RESERVED(false)) {
> + break; /* Reserved PTE bits set */
> } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
> base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
> } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access
2026-06-29 12:13 ` [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access Daniel Henrique Barboza
@ 2026-06-30 7:38 ` Nutty.Liu
2026-06-30 9:51 ` Chao Liu
1 sibling, 0 replies; 7+ messages in thread
From: Nutty.Liu @ 2026-06-30 7:38 UTC (permalink / raw)
To: Daniel Henrique Barboza, qemu-devel
Cc: qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
chao.liu.zevorn, andrew.jones, Palmer Dabbelt, Tao Tang,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini
On 6/29/2026 8:13 PM, Daniel Henrique Barboza wrote:
> All IOMMU accesses are assumed to be user mode unless told otherwise,
> i.e. we have a process_id. In case we have a non-user mode leaf PTE
> (PTE_U isn't set) and we are running in user mode, we need to throw a
> fault.
>
> This also reflects on qos-riscv-iommu tests: the tests always run in
> user mode so our PTEs must have PTE_U (bit 0x10) set.
>
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3553
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Thanks,
Nutty
> ---
> hw/riscv/riscv-iommu.c | 8 ++++++++
> tests/qtest/libqos/qos-riscv-iommu.h | 4 ++--
> 2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 453601d7a5..e6d2ca94bc 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -297,6 +297,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
> G_STAGE = 1,
> } pass;
> MemTxResult ret;
> + bool pv = !!ctx->process_id;
>
> satp = get_field(ctx->satp, RISCV_IOMMU_ATP_MODE_FIELD);
> gatp = get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD);
> @@ -470,6 +471,13 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
> break; /* Invalid PTE */
> } else if (pte & PTE_RESERVED(false)) {
> break; /* Reserved PTE bits set */
> + } else if (!(pte & PTE_U) && !pv) {
> + /*
> + * All accesses are assumed to be User mode unless
> + * process_id is valid (pv). In case we have a
> + * non-user mode PTE and !pv we need to fault.
> + */
> + break;
> } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
> base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
> } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
> diff --git a/tests/qtest/libqos/qos-riscv-iommu.h b/tests/qtest/libqos/qos-riscv-iommu.h
> index 90e69a5d73..c218e9d66d 100644
> --- a/tests/qtest/libqos/qos-riscv-iommu.h
> +++ b/tests/qtest/libqos/qos-riscv-iommu.h
> @@ -54,8 +54,8 @@
> * PTE masks for RISC-V IOMMU page tables.
> * Values match PTE_V, PTE_R, PTE_W, PTE_A, PTE_D in target/riscv/cpu_bits.h
> */
> -#define QRIOMMU_NON_LEAF_PTE_MASK 0x001 /* PTE_V */
> -#define QRIOMMU_LEAF_PTE_RW_MASK 0x0c7 /* V|R|W|A|D */
> +#define QRIOMMU_NON_LEAF_PTE_MASK 0x011 /* PTE_V | PTE_U */
> +#define QRIOMMU_LEAF_PTE_RW_MASK 0x0d7 /* V | R | W | A | D | PTE_U */
> #define QRIOMMU_PTE_PPN_MASK 0x003ffffffffffc00ull
>
> /* Address-space base offset for test tables */
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access
2026-06-29 12:13 ` [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access Daniel Henrique Barboza
2026-06-30 7:38 ` Nutty.Liu
@ 2026-06-30 9:51 ` Chao Liu
1 sibling, 0 replies; 7+ messages in thread
From: Chao Liu @ 2026-06-30 9:51 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
andrew.jones, Palmer Dabbelt, Tao Tang, Fabiano Rosas,
Laurent Vivier, Paolo Bonzini
On Mon, Jun 29, 2026 at 09:13:34AM +0800, Daniel Henrique Barboza wrote:
> All IOMMU accesses are assumed to be user mode unless told otherwise,
> i.e. we have a process_id. In case we have a non-user mode leaf PTE
> (PTE_U isn't set) and we are running in user mode, we need to throw a
> fault.
>
> This also reflects on qos-riscv-iommu tests: the tests always run in
> user mode so our PTEs must have PTE_U (bit 0x10) set.
>
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3553
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> ---
> hw/riscv/riscv-iommu.c | 8 ++++++++
> tests/qtest/libqos/qos-riscv-iommu.h | 4 ++--
> 2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 453601d7a5..e6d2ca94bc 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -297,6 +297,7 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
> G_STAGE = 1,
> } pass;
> MemTxResult ret;
> + bool pv = !!ctx->process_id;
>
> satp = get_field(ctx->satp, RISCV_IOMMU_ATP_MODE_FIELD);
> gatp = get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD);
> @@ -470,6 +471,13 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
> break; /* Invalid PTE */
> } else if (pte & PTE_RESERVED(false)) {
> break; /* Reserved PTE bits set */
> + } else if (!(pte & PTE_U) && !pv) {
> + /*
> + * All accesses are assumed to be User mode unless
> + * process_id is valid (pv). In case we have a
> + * non-user mode PTE and !pv we need to fault.
> + */
> + break;
> } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
> base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
> } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
> diff --git a/tests/qtest/libqos/qos-riscv-iommu.h b/tests/qtest/libqos/qos-riscv-iommu.h
> index 90e69a5d73..c218e9d66d 100644
> --- a/tests/qtest/libqos/qos-riscv-iommu.h
> +++ b/tests/qtest/libqos/qos-riscv-iommu.h
> @@ -54,8 +54,8 @@
> * PTE masks for RISC-V IOMMU page tables.
> * Values match PTE_V, PTE_R, PTE_W, PTE_A, PTE_D in target/riscv/cpu_bits.h
> */
> -#define QRIOMMU_NON_LEAF_PTE_MASK 0x001 /* PTE_V */
> -#define QRIOMMU_LEAF_PTE_RW_MASK 0x0c7 /* V|R|W|A|D */
> +#define QRIOMMU_NON_LEAF_PTE_MASK 0x011 /* PTE_V | PTE_U */
> +#define QRIOMMU_LEAF_PTE_RW_MASK 0x0d7 /* V | R | W | A | D | PTE_U */
> #define QRIOMMU_PTE_PPN_MASK 0x003ffffffffffc00ull
>
> /* Address-space base offset for test tables */
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits
2026-06-29 12:13 ` [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits Daniel Henrique Barboza
2026-06-30 7:25 ` Nutty.Liu
@ 2026-06-30 9:51 ` Chao Liu
1 sibling, 0 replies; 7+ messages in thread
From: Chao Liu @ 2026-06-30 9:51 UTC (permalink / raw)
To: Daniel Henrique Barboza
Cc: qemu-devel, qemu-riscv, alistair.francis, liwei1518, zhiwei_liu,
andrew.jones, Palmer Dabbelt
On Mon, Jun 29, 2026 at 09:13:33AM +0800, Daniel Henrique Barboza wrote:
> We need to fault if reserved PTE bits (60:54) are set.
>
> Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3554
> Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> ---
> hw/riscv/riscv-iommu.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index c9687e01a8..453601d7a5 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -468,6 +468,8 @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
>
> if (!(pte & PTE_V)) {
> break; /* Invalid PTE */
> + } else if (pte & PTE_RESERVED(false)) {
> + break; /* Reserved PTE bits set */
> } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
> base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
> } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-06-30 9:52 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-29 12:13 [PATCH 0/2] hw/riscv/riscv-iommu.c: additional PTE checks Daniel Henrique Barboza
2026-06-29 12:13 ` [PATCH 1/2] hw/riscv/riscv-iommu.c: check for reserved PTE bits Daniel Henrique Barboza
2026-06-30 7:25 ` Nutty.Liu
2026-06-30 9:51 ` Chao Liu
2026-06-29 12:13 ` [PATCH 2/2] hw/riscv/riscv-iommu.c: fault when !PTE_U and no priv access Daniel Henrique Barboza
2026-06-30 7:38 ` Nutty.Liu
2026-06-30 9:51 ` Chao Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox