* [PATCH v5 1/2] target/riscv: Align pmp size to pmp-granularity
2026-05-20 6:36 [PATCH v5 0/2] target/riscv: Fix PMP address alignment Jay Chang
@ 2026-05-20 6:36 ` Jay Chang
2026-05-20 7:05 ` Chao Liu
2026-05-20 6:36 ` [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability Jay Chang
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Jay Chang @ 2026-05-20 6:36 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Jay Chang,
Frank Chang
When configuring pmpcfg (TOR, NA4, or NAPOT) and pmpaddr, if the
value is smaller than the PMP granularity, it needs to be aligned
to the PMP granularity.
Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
---
target/riscv/pmp.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index a71091a316..8adf7c9719 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -179,11 +179,12 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
}
/*
* When granularity g >= 1 (i.e., granularity > 4 bytes),
- * the NA4 (Naturally Aligned 4-byte) mode is not selectable
+ * the NA4 (Naturally Aligned 4-byte) mode is not selectable.
+ * In this case, an NA4 setting is reinterpreted as a NAPOT mode.
*/
if ((riscv_cpu_cfg(env)->pmp_granularity >
MIN_RISCV_PMP_GRANULARITY) && (a_field == PMP_AMATCH_NA4)) {
- return false;
+ val |= PMP_AMATCH;
}
env->pmp_state.pmp[pmp_index].cfg_reg = val;
pmp_update_rule_addr(env, pmp_index);
@@ -263,6 +264,11 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
break;
case PMP_AMATCH_NAPOT:
+ /* Bits [g-2:0] need to be all one to align pmp granularity */
+ if (g >= 2) {
+ this_addr = deposit64(this_addr, 0, g - 1, -1ULL);
+ }
+
pmp_decode_napot(this_addr, &sa, &ea);
break;
--
2.48.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v5 1/2] target/riscv: Align pmp size to pmp-granularity
2026-05-20 6:36 ` [PATCH v5 1/2] target/riscv: Align pmp size to pmp-granularity Jay Chang
@ 2026-05-20 7:05 ` Chao Liu
0 siblings, 0 replies; 8+ messages in thread
From: Chao Liu @ 2026-05-20 7:05 UTC (permalink / raw)
To: Jay Chang
Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Frank Chang
On Wed, May 20, 2026 at 02:36:05PM +0800, Jay Chang wrote:
> When configuring pmpcfg (TOR, NA4, or NAPOT) and pmpaddr, if the
> value is smaller than the PMP granularity, it needs to be aligned
> to the PMP granularity.
>
> Signed-off-by: Jay Chang <jay.chang@sifive.com>
> Reviewed-by: Frank Chang <frank.chang@sifive.com>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> ---
> target/riscv/pmp.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index a71091a316..8adf7c9719 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -179,11 +179,12 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
> }
> /*
> * When granularity g >= 1 (i.e., granularity > 4 bytes),
> - * the NA4 (Naturally Aligned 4-byte) mode is not selectable
> + * the NA4 (Naturally Aligned 4-byte) mode is not selectable.
> + * In this case, an NA4 setting is reinterpreted as a NAPOT mode.
> */
> if ((riscv_cpu_cfg(env)->pmp_granularity >
> MIN_RISCV_PMP_GRANULARITY) && (a_field == PMP_AMATCH_NA4)) {
> - return false;
> + val |= PMP_AMATCH;
> }
> env->pmp_state.pmp[pmp_index].cfg_reg = val;
> pmp_update_rule_addr(env, pmp_index);
> @@ -263,6 +264,11 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
> break;
>
> case PMP_AMATCH_NAPOT:
> + /* Bits [g-2:0] need to be all one to align pmp granularity */
> + if (g >= 2) {
> + this_addr = deposit64(this_addr, 0, g - 1, -1ULL);
> + }
> +
> pmp_decode_napot(this_addr, &sa, &ea);
> break;
>
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability
2026-05-20 6:36 [PATCH v5 0/2] target/riscv: Fix PMP address alignment Jay Chang
2026-05-20 6:36 ` [PATCH v5 1/2] target/riscv: Align pmp size to pmp-granularity Jay Chang
@ 2026-05-20 6:36 ` Jay Chang
2026-05-20 7:06 ` Chao Liu
2026-05-26 2:23 ` Alistair Francis
2026-05-20 6:50 ` [PATCH v5 0/2] target/riscv: Fix PMP address alignment Philippe Mathieu-Daudé
2026-05-26 2:24 ` Alistair Francis
3 siblings, 2 replies; 8+ messages in thread
From: Jay Chang @ 2026-05-20 6:36 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Jay Chang
Replace manual bit manipulation for better readability:
- TOR: Use ROUND_DOWN() to clear lower bits
- NAPOT: Use deposit64() to set lower bits
Signed-off-by: Jay Chang <jay.chang@sifive.com>
---
target/riscv/pmp.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 8adf7c9719..58a8923d0d 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -247,8 +247,9 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
case PMP_AMATCH_TOR:
/* Bits pmpaddr[G-1:0] do not affect the TOR address-matching logic. */
if (g >= 1) {
- prev_addr &= ~((1ULL << g) - 1ULL);
- this_addr &= ~((1ULL << g) - 1ULL);
+ uint64_t granule = 1ULL << g;
+ prev_addr = ROUND_DOWN(prev_addr, granule);
+ this_addr = ROUND_DOWN(this_addr, granule);
}
if (prev_addr >= this_addr) {
sa = ea = 0u;
@@ -641,13 +642,14 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
case PMP_AMATCH_TOR:
/* Bit [g-1:0] read all zero */
if (g >= 1 && g < TARGET_LONG_BITS) {
- val &= ~((1ULL << g) - 1ULL);
+ uint64_t granule = 1ULL << g;
+ val = ROUND_DOWN(val, granule);
}
break;
case PMP_AMATCH_NAPOT:
/* Bit [g-2:0] read all one */
if (g >= 2 && g < TARGET_LONG_BITS) {
- val |= ((1ULL << (g - 1)) - 1ULL);
+ val = deposit64(val, 0, g - 1, -1ULL);
}
break;
default:
--
2.48.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability
2026-05-20 6:36 ` [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability Jay Chang
@ 2026-05-20 7:06 ` Chao Liu
2026-05-26 2:23 ` Alistair Francis
1 sibling, 0 replies; 8+ messages in thread
From: Chao Liu @ 2026-05-20 7:06 UTC (permalink / raw)
To: Jay Chang
Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei
On Wed, May 20, 2026 at 02:36:06PM +0800, Jay Chang wrote:
> Replace manual bit manipulation for better readability:
>
> - TOR: Use ROUND_DOWN() to clear lower bits
> - NAPOT: Use deposit64() to set lower bits
>
> Signed-off-by: Jay Chang <jay.chang@sifive.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> ---
> target/riscv/pmp.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 8adf7c9719..58a8923d0d 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -247,8 +247,9 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
> case PMP_AMATCH_TOR:
> /* Bits pmpaddr[G-1:0] do not affect the TOR address-matching logic. */
> if (g >= 1) {
> - prev_addr &= ~((1ULL << g) - 1ULL);
> - this_addr &= ~((1ULL << g) - 1ULL);
> + uint64_t granule = 1ULL << g;
> + prev_addr = ROUND_DOWN(prev_addr, granule);
> + this_addr = ROUND_DOWN(this_addr, granule);
> }
> if (prev_addr >= this_addr) {
> sa = ea = 0u;
> @@ -641,13 +642,14 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
> case PMP_AMATCH_TOR:
> /* Bit [g-1:0] read all zero */
> if (g >= 1 && g < TARGET_LONG_BITS) {
> - val &= ~((1ULL << g) - 1ULL);
> + uint64_t granule = 1ULL << g;
> + val = ROUND_DOWN(val, granule);
> }
> break;
> case PMP_AMATCH_NAPOT:
> /* Bit [g-2:0] read all one */
> if (g >= 2 && g < TARGET_LONG_BITS) {
> - val |= ((1ULL << (g - 1)) - 1ULL);
> + val = deposit64(val, 0, g - 1, -1ULL);
> }
> break;
> default:
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability
2026-05-20 6:36 ` [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability Jay Chang
2026-05-20 7:06 ` Chao Liu
@ 2026-05-26 2:23 ` Alistair Francis
1 sibling, 0 replies; 8+ messages in thread
From: Alistair Francis @ 2026-05-26 2:23 UTC (permalink / raw)
To: Jay Chang
Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu
On Wed, May 20, 2026 at 4:36 PM Jay Chang <jay.chang@sifive.com> wrote:
>
> Replace manual bit manipulation for better readability:
>
> - TOR: Use ROUND_DOWN() to clear lower bits
> - NAPOT: Use deposit64() to set lower bits
>
> Signed-off-by: Jay Chang <jay.chang@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/pmp.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 8adf7c9719..58a8923d0d 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -247,8 +247,9 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
> case PMP_AMATCH_TOR:
> /* Bits pmpaddr[G-1:0] do not affect the TOR address-matching logic. */
> if (g >= 1) {
> - prev_addr &= ~((1ULL << g) - 1ULL);
> - this_addr &= ~((1ULL << g) - 1ULL);
> + uint64_t granule = 1ULL << g;
> + prev_addr = ROUND_DOWN(prev_addr, granule);
> + this_addr = ROUND_DOWN(this_addr, granule);
> }
> if (prev_addr >= this_addr) {
> sa = ea = 0u;
> @@ -641,13 +642,14 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
> case PMP_AMATCH_TOR:
> /* Bit [g-1:0] read all zero */
> if (g >= 1 && g < TARGET_LONG_BITS) {
> - val &= ~((1ULL << g) - 1ULL);
> + uint64_t granule = 1ULL << g;
> + val = ROUND_DOWN(val, granule);
> }
> break;
> case PMP_AMATCH_NAPOT:
> /* Bit [g-2:0] read all one */
> if (g >= 2 && g < TARGET_LONG_BITS) {
> - val |= ((1ULL << (g - 1)) - 1ULL);
> + val = deposit64(val, 0, g - 1, -1ULL);
> }
> break;
> default:
> --
> 2.48.1
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 0/2] target/riscv: Fix PMP address alignment
2026-05-20 6:36 [PATCH v5 0/2] target/riscv: Fix PMP address alignment Jay Chang
2026-05-20 6:36 ` [PATCH v5 1/2] target/riscv: Align pmp size to pmp-granularity Jay Chang
2026-05-20 6:36 ` [PATCH v5 2/2] target/riscv: Improve PMP address alignment readability Jay Chang
@ 2026-05-20 6:50 ` Philippe Mathieu-Daudé
2026-05-26 2:24 ` Alistair Francis
3 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-05-20 6:50 UTC (permalink / raw)
To: Jay Chang, qemu-devel, qemu-riscv
Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, Chao Liu
On 20/5/26 08:36, Jay Chang wrote:
> This series fixes PMP address alignment to comply with the RISC-V
> specification WARL (Write-Any, Read-Legal) semantics.
>
> When configuring pmpcfg (TOR, NA4, or NAPOT) and pmpaddr, if the
> value is smaller than the PMP granularity, it needs to be aligned
> to the PMP granularity.
>
> Chagnes in v5:
> - Use uint64_t for granule, in preparation for upcoming single-binary work:
> https://lore.kernel.org/qemu-devel/20260515180437.23620-1-anjo@rev.ng/
Thank you! Series LGTM.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 0/2] target/riscv: Fix PMP address alignment
2026-05-20 6:36 [PATCH v5 0/2] target/riscv: Fix PMP address alignment Jay Chang
` (2 preceding siblings ...)
2026-05-20 6:50 ` [PATCH v5 0/2] target/riscv: Fix PMP address alignment Philippe Mathieu-Daudé
@ 2026-05-26 2:24 ` Alistair Francis
3 siblings, 0 replies; 8+ messages in thread
From: Alistair Francis @ 2026-05-26 2:24 UTC (permalink / raw)
To: Jay Chang
Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu
On Wed, May 20, 2026 at 4:36 PM Jay Chang <jay.chang@sifive.com> wrote:
>
> This series fixes PMP address alignment to comply with the RISC-V
> specification WARL (Write-Any, Read-Legal) semantics.
>
> When configuring pmpcfg (TOR, NA4, or NAPOT) and pmpaddr, if the
> value is smaller than the PMP granularity, it needs to be aligned
> to the PMP granularity.
>
> Chagnes in v5:
> - Use uint64_t for granule, in preparation for upcoming single-binary work:
> https://lore.kernel.org/qemu-devel/20260515180437.23620-1-anjo@rev.ng/
>
> Changes in v4:
> - Rebase riscv-to-apply.next
>
> Changes in v3:
> - Use ROUND_UP() macro for NAPOT address alignment
>
> Changes in v2:
> - Fixed commit message grammar ("it needs to be aligned")
> - Use ROUND_DOWN() macro for TOR address alignment to improve
> code readability
>
> Jay Chang (2):
> target/riscv: Align pmp size to pmp-granularity
> target/riscv: Improve PMP address alignment readability
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> target/riscv/pmp.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> --
> 2.48.1
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread