* [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-11-23 9:09 ` LIU Zhiwei
0 siblings, 0 replies; 12+ messages in thread
From: LIU Zhiwei @ 2021-11-23 9:09 UTC (permalink / raw)
To: qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis, LIU Zhiwei
Only the pmp index that be checked by pmp_hart_has_privs can be used
by pmp_get_tlb_size to avoid an error pmp index.
Before modification, we may use an error pmp index. For example,
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
will return true;
However, this checked pmp index is discarded as pmp_hart_has_privs
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
a pmp rule [0x10, 0x4]. It will be misused as it is legal in
pmp_get_tlb_size.
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
target/riscv/cpu_helper.c | 16 ++++++-----
target/riscv/pmp.c | 56 +++++++++++++--------------------------
target/riscv/pmp.h | 6 ++---
3 files changed, 31 insertions(+), 47 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9eeed38c7e..4239bd2ca5 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
int mode)
{
pmp_priv_t pmp_priv;
- target_ulong tlb_size_pmp = 0;
+ int pmp_index = -1;
if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
}
- if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
- mode)) {
+ pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+ &pmp_priv, mode);
+ if (pmp_index < 0) {
*prot = 0;
return TRANSLATE_PMP_FAIL;
}
*prot = pmp_priv_to_page_prot(pmp_priv);
- if (tlb_size != NULL) {
- if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
- *tlb_size = tlb_size_pmp;
- }
+ if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
+ target_ulong tlb_sa = addr & ~(*tlb_size - 1);
+ target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
+
+ *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
}
return TRANSLATE_SUCCESS;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 54abf42583..1172142e34 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
/*
* Check if the address has required RWX privs to complete desired operation
+ * Return PMP rule index if a pmp rule match
+ * Return MAX_RISCV_PMPS if default match
+ * Return negtive value if no match
*/
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
target_ulong mode)
{
@@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
/* Short cut if no rules */
if (0 == pmp_get_num_rules(env)) {
- return pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode);
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
+ allowed_privs, mode)) {
+ ret = MAX_RISCV_PMPS;
+ }
}
if (size == 0) {
@@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
if ((s + e) == 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"pmp violation - access is partially inside\n");
- ret = 0;
+ ret = -1;
break;
}
@@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
}
}
- ret = ((privs & *allowed_privs) == privs);
+ if ((privs & *allowed_privs) == privs) {
+ ret = i;
+ }
break;
}
}
/* No rule matched */
if (ret == -1) {
- return pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode);
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
+ allowed_privs, mode)) {
+ ret = MAX_RISCV_PMPS;
+ }
}
- return ret == 1 ? true : false;
+ return ret;
}
/*
@@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
* Calculate the TLB size if the start address or the end address of
* PMP entry is presented in the TLB page.
*/
-static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
- target_ulong tlb_sa, target_ulong tlb_ea)
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+ target_ulong tlb_sa, target_ulong tlb_ea)
{
target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
@@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
return 0;
}
-/*
- * Check is there a PMP entry which range covers this page. If so,
- * try to find the minimum granularity for the TLB size.
- */
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
- target_ulong *tlb_size)
-{
- int i;
- target_ulong val;
- target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
-
- for (i = 0; i < MAX_RISCV_PMPS; i++) {
- val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
- if (val) {
- if (*tlb_size == 0 || *tlb_size > val) {
- *tlb_size = val;
- }
- }
- }
-
- if (*tlb_size != 0) {
- return true;
- }
-
- return false;
-}
-
/*
* Convert PMP privilege to TLB page privilege.
*/
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index a9a0b363a7..94c0b960fb 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
target_ulong mode);
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
- target_ulong *tlb_size);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+ target_ulong tlb_sa, target_ulong tlb_ea);
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-11-23 9:09 ` LIU Zhiwei
0 siblings, 0 replies; 12+ messages in thread
From: LIU Zhiwei @ 2021-11-23 9:09 UTC (permalink / raw)
To: qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng, LIU Zhiwei
Only the pmp index that be checked by pmp_hart_has_privs can be used
by pmp_get_tlb_size to avoid an error pmp index.
Before modification, we may use an error pmp index. For example,
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
will return true;
However, this checked pmp index is discarded as pmp_hart_has_privs
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
a pmp rule [0x10, 0x4]. It will be misused as it is legal in
pmp_get_tlb_size.
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
target/riscv/cpu_helper.c | 16 ++++++-----
target/riscv/pmp.c | 56 +++++++++++++--------------------------
target/riscv/pmp.h | 6 ++---
3 files changed, 31 insertions(+), 47 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9eeed38c7e..4239bd2ca5 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
int mode)
{
pmp_priv_t pmp_priv;
- target_ulong tlb_size_pmp = 0;
+ int pmp_index = -1;
if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
}
- if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
- mode)) {
+ pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+ &pmp_priv, mode);
+ if (pmp_index < 0) {
*prot = 0;
return TRANSLATE_PMP_FAIL;
}
*prot = pmp_priv_to_page_prot(pmp_priv);
- if (tlb_size != NULL) {
- if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
- *tlb_size = tlb_size_pmp;
- }
+ if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
+ target_ulong tlb_sa = addr & ~(*tlb_size - 1);
+ target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
+
+ *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
}
return TRANSLATE_SUCCESS;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 54abf42583..1172142e34 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
/*
* Check if the address has required RWX privs to complete desired operation
+ * Return PMP rule index if a pmp rule match
+ * Return MAX_RISCV_PMPS if default match
+ * Return negtive value if no match
*/
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
target_ulong mode)
{
@@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
/* Short cut if no rules */
if (0 == pmp_get_num_rules(env)) {
- return pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode);
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
+ allowed_privs, mode)) {
+ ret = MAX_RISCV_PMPS;
+ }
}
if (size == 0) {
@@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
if ((s + e) == 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"pmp violation - access is partially inside\n");
- ret = 0;
+ ret = -1;
break;
}
@@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
}
}
- ret = ((privs & *allowed_privs) == privs);
+ if ((privs & *allowed_privs) == privs) {
+ ret = i;
+ }
break;
}
}
/* No rule matched */
if (ret == -1) {
- return pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode);
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
+ allowed_privs, mode)) {
+ ret = MAX_RISCV_PMPS;
+ }
}
- return ret == 1 ? true : false;
+ return ret;
}
/*
@@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
* Calculate the TLB size if the start address or the end address of
* PMP entry is presented in the TLB page.
*/
-static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
- target_ulong tlb_sa, target_ulong tlb_ea)
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+ target_ulong tlb_sa, target_ulong tlb_ea)
{
target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
@@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
return 0;
}
-/*
- * Check is there a PMP entry which range covers this page. If so,
- * try to find the minimum granularity for the TLB size.
- */
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
- target_ulong *tlb_size)
-{
- int i;
- target_ulong val;
- target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
-
- for (i = 0; i < MAX_RISCV_PMPS; i++) {
- val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
- if (val) {
- if (*tlb_size == 0 || *tlb_size > val) {
- *tlb_size = val;
- }
- }
- }
-
- if (*tlb_size != 0) {
- return true;
- }
-
- return false;
-}
-
/*
* Convert PMP privilege to TLB page privilege.
*/
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index a9a0b363a7..94c0b960fb 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
target_ulong mode);
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
- target_ulong *tlb_size);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+ target_ulong tlb_sa, target_ulong tlb_ea);
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
2021-11-23 9:09 ` LIU Zhiwei
@ 2021-12-08 1:04 ` Alistair Francis
-1 siblings, 0 replies; 12+ messages in thread
From: Alistair Francis @ 2021-12-08 1:04 UTC (permalink / raw)
To: LIU Zhiwei
Cc: Palmer Dabbelt, Alistair Francis, Bin Meng, open list:RISC-V,
qemu-devel@nongnu.org Developers
On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Only the pmp index that be checked by pmp_hart_has_privs can be used
> by pmp_get_tlb_size to avoid an error pmp index.
>
> Before modification, we may use an error pmp index. For example,
> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> will return true;
>
> However, this checked pmp index is discarded as pmp_hart_has_privs
> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> pmp_get_tlb_size.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu_helper.c | 16 ++++++-----
> target/riscv/pmp.c | 56 +++++++++++++--------------------------
> target/riscv/pmp.h | 6 ++---
> 3 files changed, 31 insertions(+), 47 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9eeed38c7e..4239bd2ca5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> int mode)
> {
> pmp_priv_t pmp_priv;
> - target_ulong tlb_size_pmp = 0;
> + int pmp_index = -1;
>
> if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
> *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return TRANSLATE_SUCCESS;
> }
>
> - if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
> - mode)) {
> + pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
> + &pmp_priv, mode);
> + if (pmp_index < 0) {
> *prot = 0;
> return TRANSLATE_PMP_FAIL;
> }
>
> *prot = pmp_priv_to_page_prot(pmp_priv);
> - if (tlb_size != NULL) {
> - if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
> - *tlb_size = tlb_size_pmp;
> - }
> + if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
> + target_ulong tlb_sa = addr & ~(*tlb_size - 1);
> + target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
> +
> + *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
> }
>
> return TRANSLATE_SUCCESS;
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..1172142e34 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
>
> /*
> * Check if the address has required RWX privs to complete desired operation
> + * Return PMP rule index if a pmp rule match
> + * Return MAX_RISCV_PMPS if default match
> + * Return negtive value if no match
> */
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode)
> {
> @@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>
> /* Short cut if no rules */
> if (0 == pmp_get_num_rules(env)) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> if (size == 0) {
> @@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> if ((s + e) == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "pmp violation - access is partially inside\n");
> - ret = 0;
> + ret = -1;
> break;
> }
>
> @@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> }
> }
>
> - ret = ((privs & *allowed_privs) == privs);
> + if ((privs & *allowed_privs) == privs) {
> + ret = i;
> + }
> break;
> }
> }
>
> /* No rule matched */
> if (ret == -1) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> - return ret == 1 ? true : false;
> + return ret;
> }
>
> /*
> @@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
> * Calculate the TLB size if the start address or the end address of
> * PMP entry is presented in the TLB page.
> */
> -static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> - target_ulong tlb_sa, target_ulong tlb_ea)
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea)
> {
> target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
> target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
> @@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> return 0;
> }
>
> -/*
> - * Check is there a PMP entry which range covers this page. If so,
> - * try to find the minimum granularity for the TLB size.
> - */
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size)
> -{
> - int i;
> - target_ulong val;
> - target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
> -
> - for (i = 0; i < MAX_RISCV_PMPS; i++) {
> - val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
> - if (val) {
> - if (*tlb_size == 0 || *tlb_size > val) {
> - *tlb_size = val;
> - }
> - }
> - }
> -
> - if (*tlb_size != 0) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> /*
> * Convert PMP privilege to TLB page privilege.
> */
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index a9a0b363a7..94c0b960fb 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
> void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val);
> target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode);
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size);
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea);
> void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-12-08 1:04 ` Alistair Francis
0 siblings, 0 replies; 12+ messages in thread
From: Alistair Francis @ 2021-12-08 1:04 UTC (permalink / raw)
To: LIU Zhiwei
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Bin Meng, Alistair Francis
On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Only the pmp index that be checked by pmp_hart_has_privs can be used
> by pmp_get_tlb_size to avoid an error pmp index.
>
> Before modification, we may use an error pmp index. For example,
> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> will return true;
>
> However, this checked pmp index is discarded as pmp_hart_has_privs
> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> pmp_get_tlb_size.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu_helper.c | 16 ++++++-----
> target/riscv/pmp.c | 56 +++++++++++++--------------------------
> target/riscv/pmp.h | 6 ++---
> 3 files changed, 31 insertions(+), 47 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9eeed38c7e..4239bd2ca5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> int mode)
> {
> pmp_priv_t pmp_priv;
> - target_ulong tlb_size_pmp = 0;
> + int pmp_index = -1;
>
> if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
> *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return TRANSLATE_SUCCESS;
> }
>
> - if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
> - mode)) {
> + pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
> + &pmp_priv, mode);
> + if (pmp_index < 0) {
> *prot = 0;
> return TRANSLATE_PMP_FAIL;
> }
>
> *prot = pmp_priv_to_page_prot(pmp_priv);
> - if (tlb_size != NULL) {
> - if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
> - *tlb_size = tlb_size_pmp;
> - }
> + if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
> + target_ulong tlb_sa = addr & ~(*tlb_size - 1);
> + target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
> +
> + *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
> }
>
> return TRANSLATE_SUCCESS;
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..1172142e34 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
>
> /*
> * Check if the address has required RWX privs to complete desired operation
> + * Return PMP rule index if a pmp rule match
> + * Return MAX_RISCV_PMPS if default match
> + * Return negtive value if no match
> */
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode)
> {
> @@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>
> /* Short cut if no rules */
> if (0 == pmp_get_num_rules(env)) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> if (size == 0) {
> @@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> if ((s + e) == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "pmp violation - access is partially inside\n");
> - ret = 0;
> + ret = -1;
> break;
> }
>
> @@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> }
> }
>
> - ret = ((privs & *allowed_privs) == privs);
> + if ((privs & *allowed_privs) == privs) {
> + ret = i;
> + }
> break;
> }
> }
>
> /* No rule matched */
> if (ret == -1) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> - return ret == 1 ? true : false;
> + return ret;
> }
>
> /*
> @@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
> * Calculate the TLB size if the start address or the end address of
> * PMP entry is presented in the TLB page.
> */
> -static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> - target_ulong tlb_sa, target_ulong tlb_ea)
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea)
> {
> target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
> target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
> @@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> return 0;
> }
>
> -/*
> - * Check is there a PMP entry which range covers this page. If so,
> - * try to find the minimum granularity for the TLB size.
> - */
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size)
> -{
> - int i;
> - target_ulong val;
> - target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
> -
> - for (i = 0; i < MAX_RISCV_PMPS; i++) {
> - val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
> - if (val) {
> - if (*tlb_size == 0 || *tlb_size > val) {
> - *tlb_size = val;
> - }
> - }
> - }
> -
> - if (*tlb_size != 0) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> /*
> * Convert PMP privilege to TLB page privilege.
> */
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index a9a0b363a7..94c0b960fb 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
> void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val);
> target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode);
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size);
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea);
> void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
2021-11-23 9:09 ` LIU Zhiwei
@ 2021-12-08 3:23 ` Alistair Francis
-1 siblings, 0 replies; 12+ messages in thread
From: Alistair Francis @ 2021-12-08 3:23 UTC (permalink / raw)
To: LIU Zhiwei
Cc: Palmer Dabbelt, Alistair Francis, Bin Meng, open list:RISC-V,
qemu-devel@nongnu.org Developers
On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Only the pmp index that be checked by pmp_hart_has_privs can be used
> by pmp_get_tlb_size to avoid an error pmp index.
>
> Before modification, we may use an error pmp index. For example,
> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> will return true;
>
> However, this checked pmp index is discarded as pmp_hart_has_privs
> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> pmp_get_tlb_size.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> target/riscv/cpu_helper.c | 16 ++++++-----
> target/riscv/pmp.c | 56 +++++++++++++--------------------------
> target/riscv/pmp.h | 6 ++---
> 3 files changed, 31 insertions(+), 47 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9eeed38c7e..4239bd2ca5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> int mode)
> {
> pmp_priv_t pmp_priv;
> - target_ulong tlb_size_pmp = 0;
> + int pmp_index = -1;
>
> if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
> *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return TRANSLATE_SUCCESS;
> }
>
> - if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
> - mode)) {
> + pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
> + &pmp_priv, mode);
> + if (pmp_index < 0) {
> *prot = 0;
> return TRANSLATE_PMP_FAIL;
> }
>
> *prot = pmp_priv_to_page_prot(pmp_priv);
> - if (tlb_size != NULL) {
> - if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
> - *tlb_size = tlb_size_pmp;
> - }
> + if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
> + target_ulong tlb_sa = addr & ~(*tlb_size - 1);
> + target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
> +
> + *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
> }
>
> return TRANSLATE_SUCCESS;
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..1172142e34 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
>
> /*
> * Check if the address has required RWX privs to complete desired operation
> + * Return PMP rule index if a pmp rule match
> + * Return MAX_RISCV_PMPS if default match
> + * Return negtive value if no match
> */
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode)
> {
> @@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>
> /* Short cut if no rules */
> if (0 == pmp_get_num_rules(env)) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> if (size == 0) {
> @@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> if ((s + e) == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "pmp violation - access is partially inside\n");
> - ret = 0;
> + ret = -1;
> break;
> }
>
> @@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> }
> }
>
> - ret = ((privs & *allowed_privs) == privs);
> + if ((privs & *allowed_privs) == privs) {
> + ret = i;
> + }
> break;
> }
> }
>
> /* No rule matched */
> if (ret == -1) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> - return ret == 1 ? true : false;
> + return ret;
> }
>
> /*
> @@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
> * Calculate the TLB size if the start address or the end address of
> * PMP entry is presented in the TLB page.
> */
> -static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> - target_ulong tlb_sa, target_ulong tlb_ea)
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea)
> {
> target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
> target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
> @@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> return 0;
> }
>
> -/*
> - * Check is there a PMP entry which range covers this page. If so,
> - * try to find the minimum granularity for the TLB size.
> - */
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size)
> -{
> - int i;
> - target_ulong val;
> - target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
> -
> - for (i = 0; i < MAX_RISCV_PMPS; i++) {
> - val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
> - if (val) {
> - if (*tlb_size == 0 || *tlb_size > val) {
> - *tlb_size = val;
> - }
> - }
> - }
> -
> - if (*tlb_size != 0) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> /*
> * Convert PMP privilege to TLB page privilege.
> */
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index a9a0b363a7..94c0b960fb 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
> void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val);
> target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode);
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size);
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea);
> void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-12-08 3:23 ` Alistair Francis
0 siblings, 0 replies; 12+ messages in thread
From: Alistair Francis @ 2021-12-08 3:23 UTC (permalink / raw)
To: LIU Zhiwei
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Bin Meng, Alistair Francis
On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Only the pmp index that be checked by pmp_hart_has_privs can be used
> by pmp_get_tlb_size to avoid an error pmp index.
>
> Before modification, we may use an error pmp index. For example,
> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> will return true;
>
> However, this checked pmp index is discarded as pmp_hart_has_privs
> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> pmp_get_tlb_size.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> target/riscv/cpu_helper.c | 16 ++++++-----
> target/riscv/pmp.c | 56 +++++++++++++--------------------------
> target/riscv/pmp.h | 6 ++---
> 3 files changed, 31 insertions(+), 47 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9eeed38c7e..4239bd2ca5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> int mode)
> {
> pmp_priv_t pmp_priv;
> - target_ulong tlb_size_pmp = 0;
> + int pmp_index = -1;
>
> if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
> *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return TRANSLATE_SUCCESS;
> }
>
> - if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
> - mode)) {
> + pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
> + &pmp_priv, mode);
> + if (pmp_index < 0) {
> *prot = 0;
> return TRANSLATE_PMP_FAIL;
> }
>
> *prot = pmp_priv_to_page_prot(pmp_priv);
> - if (tlb_size != NULL) {
> - if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
> - *tlb_size = tlb_size_pmp;
> - }
> + if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
> + target_ulong tlb_sa = addr & ~(*tlb_size - 1);
> + target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
> +
> + *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
> }
>
> return TRANSLATE_SUCCESS;
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..1172142e34 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
>
> /*
> * Check if the address has required RWX privs to complete desired operation
> + * Return PMP rule index if a pmp rule match
> + * Return MAX_RISCV_PMPS if default match
> + * Return negtive value if no match
> */
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode)
> {
> @@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>
> /* Short cut if no rules */
> if (0 == pmp_get_num_rules(env)) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> if (size == 0) {
> @@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> if ((s + e) == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "pmp violation - access is partially inside\n");
> - ret = 0;
> + ret = -1;
> break;
> }
>
> @@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> }
> }
>
> - ret = ((privs & *allowed_privs) == privs);
> + if ((privs & *allowed_privs) == privs) {
> + ret = i;
> + }
> break;
> }
> }
>
> /* No rule matched */
> if (ret == -1) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> - return ret == 1 ? true : false;
> + return ret;
> }
>
> /*
> @@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
> * Calculate the TLB size if the start address or the end address of
> * PMP entry is presented in the TLB page.
> */
> -static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> - target_ulong tlb_sa, target_ulong tlb_ea)
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea)
> {
> target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
> target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
> @@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> return 0;
> }
>
> -/*
> - * Check is there a PMP entry which range covers this page. If so,
> - * try to find the minimum granularity for the TLB size.
> - */
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size)
> -{
> - int i;
> - target_ulong val;
> - target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
> -
> - for (i = 0; i < MAX_RISCV_PMPS; i++) {
> - val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
> - if (val) {
> - if (*tlb_size == 0 || *tlb_size > val) {
> - *tlb_size = val;
> - }
> - }
> - }
> -
> - if (*tlb_size != 0) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> /*
> * Convert PMP privilege to TLB page privilege.
> */
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index a9a0b363a7..94c0b960fb 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
> void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val);
> target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode);
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size);
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea);
> void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
2021-12-08 3:23 ` Alistair Francis
@ 2021-12-17 0:37 ` Alistair Francis
-1 siblings, 0 replies; 12+ messages in thread
From: Alistair Francis @ 2021-12-17 0:37 UTC (permalink / raw)
To: LIU Zhiwei
Cc: Palmer Dabbelt, Alistair Francis, Bin Meng, open list:RISC-V,
qemu-devel@nongnu.org Developers
On Wed, Dec 8, 2021 at 1:23 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
> >
> > Only the pmp index that be checked by pmp_hart_has_privs can be used
> > by pmp_get_tlb_size to avoid an error pmp index.
> >
> > Before modification, we may use an error pmp index. For example,
> > we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> > is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> > will return true;
> >
> > However, this checked pmp index is discarded as pmp_hart_has_privs
> > return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> > rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> > a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> > pmp_get_tlb_size.
> >
> > Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>
> Thanks!
>
> Applied to riscv-to-apply.next
This patch causes lots of Linux boot failures. I see messages like this:
Invalid write at addr 0x22048, size 8, region '(null)', reason: rejected
from QEMU and the guest fails to start.
Alistair
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-12-17 0:37 ` Alistair Francis
0 siblings, 0 replies; 12+ messages in thread
From: Alistair Francis @ 2021-12-17 0:37 UTC (permalink / raw)
To: LIU Zhiwei
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Bin Meng, Alistair Francis
On Wed, Dec 8, 2021 at 1:23 PM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
> >
> > Only the pmp index that be checked by pmp_hart_has_privs can be used
> > by pmp_get_tlb_size to avoid an error pmp index.
> >
> > Before modification, we may use an error pmp index. For example,
> > we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> > is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> > will return true;
> >
> > However, this checked pmp index is discarded as pmp_hart_has_privs
> > return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> > rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> > a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> > pmp_get_tlb_size.
> >
> > Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>
> Thanks!
>
> Applied to riscv-to-apply.next
This patch causes lots of Linux boot failures. I see messages like this:
Invalid write at addr 0x22048, size 8, region '(null)', reason: rejected
from QEMU and the guest fails to start.
Alistair
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
2021-12-17 0:37 ` Alistair Francis
@ 2021-12-17 3:06 ` LIU Zhiwei
-1 siblings, 0 replies; 12+ messages in thread
From: LIU Zhiwei @ 2021-12-17 3:06 UTC (permalink / raw)
To: Alistair Francis
Cc: Palmer Dabbelt, Alistair Francis, Bin Meng, open list:RISC-V,
qemu-devel@nongnu.org Developers
On 2021/12/17 上午8:37, Alistair Francis wrote:
> On Wed, Dec 8, 2021 at 1:23 PM Alistair Francis <alistair23@gmail.com> wrote:
>> On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>>> Only the pmp index that be checked by pmp_hart_has_privs can be used
>>> by pmp_get_tlb_size to avoid an error pmp index.
>>>
>>> Before modification, we may use an error pmp index. For example,
>>> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
>>> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
>>> will return true;
>>>
>>> However, this checked pmp index is discarded as pmp_hart_has_privs
>>> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
>>> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
>>> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
>>> pmp_get_tlb_size.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> Thanks!
>>
>> Applied to riscv-to-apply.next
> This patch causes lots of Linux boot failures. I see messages like this:
>
> Invalid write at addr 0x22048, size 8, region '(null)', reason: rejected
>
> from QEMU and the guest fails to start.
Yes, it's an error. Send it again later.
Thanks,
Zhiwei
> Alistair
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-12-17 3:06 ` LIU Zhiwei
0 siblings, 0 replies; 12+ messages in thread
From: LIU Zhiwei @ 2021-12-17 3:06 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Bin Meng, Alistair Francis
On 2021/12/17 上午8:37, Alistair Francis wrote:
> On Wed, Dec 8, 2021 at 1:23 PM Alistair Francis <alistair23@gmail.com> wrote:
>> On Tue, Nov 23, 2021 at 7:09 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>>> Only the pmp index that be checked by pmp_hart_has_privs can be used
>>> by pmp_get_tlb_size to avoid an error pmp index.
>>>
>>> Before modification, we may use an error pmp index. For example,
>>> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
>>> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
>>> will return true;
>>>
>>> However, this checked pmp index is discarded as pmp_hart_has_privs
>>> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
>>> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
>>> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
>>> pmp_get_tlb_size.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> Thanks!
>>
>> Applied to riscv-to-apply.next
> This patch causes lots of Linux boot failures. I see messages like this:
>
> Invalid write at addr 0x22048, size 8, region '(null)', reason: rejected
>
> from QEMU and the guest fails to start.
Yes, it's an error. Send it again later.
Thanks,
Zhiwei
> Alistair
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
2021-11-23 9:09 ` LIU Zhiwei
@ 2021-12-17 3:28 ` LIU Zhiwei
-1 siblings, 0 replies; 12+ messages in thread
From: LIU Zhiwei @ 2021-12-17 3:28 UTC (permalink / raw)
To: qemu-devel, qemu-riscv; +Cc: Alistair.Francis, bin.meng, palmer
On 2021/11/23 下午5:09, LIU Zhiwei wrote:
> Only the pmp index that be checked by pmp_hart_has_privs can be used
> by pmp_get_tlb_size to avoid an error pmp index.
>
> Before modification, we may use an error pmp index. For example,
> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> will return true;
>
> However, this checked pmp index is discarded as pmp_hart_has_privs
> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> pmp_get_tlb_size.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
> target/riscv/cpu_helper.c | 16 ++++++-----
> target/riscv/pmp.c | 56 +++++++++++++--------------------------
> target/riscv/pmp.h | 6 ++---
> 3 files changed, 31 insertions(+), 47 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9eeed38c7e..4239bd2ca5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> int mode)
> {
> pmp_priv_t pmp_priv;
> - target_ulong tlb_size_pmp = 0;
> + int pmp_index = -1;
>
> if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
> *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return TRANSLATE_SUCCESS;
> }
>
> - if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
> - mode)) {
> + pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
> + &pmp_priv, mode);
> + if (pmp_index < 0) {
> *prot = 0;
> return TRANSLATE_PMP_FAIL;
> }
>
> *prot = pmp_priv_to_page_prot(pmp_priv);
> - if (tlb_size != NULL) {
> - if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
> - *tlb_size = tlb_size_pmp;
> - }
> + if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
> + target_ulong tlb_sa = addr & ~(*tlb_size - 1);
> + target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
> +
> + *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
> }
>
> return TRANSLATE_SUCCESS;
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..1172142e34 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
>
> /*
> * Check if the address has required RWX privs to complete desired operation
> + * Return PMP rule index if a pmp rule match
> + * Return MAX_RISCV_PMPS if default match
> + * Return negtive value if no match
> */
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode)
> {
> @@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>
> /* Short cut if no rules */
> if (0 == pmp_get_num_rules(env)) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> if (size == 0) {
> @@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> if ((s + e) == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "pmp violation - access is partially inside\n");
> - ret = 0;
> + ret = -1;
> break;
> }
>
> @@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> }
> }
>
> - ret = ((privs & *allowed_privs) == privs);
> + if ((privs & *allowed_privs) == privs) {
> + ret = i;
> + }
> break;
> }
> }
>
> /* No rule matched */
> if (ret == -1) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> - return ret == 1 ? true : false;
> + return ret;
> }
>
> /*
> @@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
> * Calculate the TLB size if the start address or the end address of
> * PMP entry is presented in the TLB page.
> */
> -static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> - target_ulong tlb_sa, target_ulong tlb_ea)
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea)
> {
> target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
> target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
Error here.
Add "
+ if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
+ return tlb_ea - tlb_sa + 1;
+ }
"
Thanks,
Zhiwei
> @@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> return 0;
> }
>
> -/*
> - * Check is there a PMP entry which range covers this page. If so,
> - * try to find the minimum granularity for the TLB size.
> - */
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size)
> -{
> - int i;
> - target_ulong val;
> - target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
> -
> - for (i = 0; i < MAX_RISCV_PMPS; i++) {
> - val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
> - if (val) {
> - if (*tlb_size == 0 || *tlb_size > val) {
> - *tlb_size = val;
> - }
> - }
> - }
> -
> - if (*tlb_size != 0) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> /*
> * Convert PMP privilege to TLB page privilege.
> */
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index a9a0b363a7..94c0b960fb 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
> void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val);
> target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode);
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size);
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea);
> void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb
@ 2021-12-17 3:28 ` LIU Zhiwei
0 siblings, 0 replies; 12+ messages in thread
From: LIU Zhiwei @ 2021-12-17 3:28 UTC (permalink / raw)
To: qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis
On 2021/11/23 下午5:09, LIU Zhiwei wrote:
> Only the pmp index that be checked by pmp_hart_has_privs can be used
> by pmp_get_tlb_size to avoid an error pmp index.
>
> Before modification, we may use an error pmp index. For example,
> we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
> is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
> will return true;
>
> However, this checked pmp index is discarded as pmp_hart_has_privs
> return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
> rules. The tlb_sa will be 0x0, and tlb_ea will be 0x4fff. If there is
> a pmp rule [0x10, 0x4]. It will be misused as it is legal in
> pmp_get_tlb_size.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
> target/riscv/cpu_helper.c | 16 ++++++-----
> target/riscv/pmp.c | 56 +++++++++++++--------------------------
> target/riscv/pmp.h | 6 ++---
> 3 files changed, 31 insertions(+), 47 deletions(-)
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 9eeed38c7e..4239bd2ca5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -362,24 +362,26 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
> int mode)
> {
> pmp_priv_t pmp_priv;
> - target_ulong tlb_size_pmp = 0;
> + int pmp_index = -1;
>
> if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
> *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
> return TRANSLATE_SUCCESS;
> }
>
> - if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
> - mode)) {
> + pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
> + &pmp_priv, mode);
> + if (pmp_index < 0) {
> *prot = 0;
> return TRANSLATE_PMP_FAIL;
> }
>
> *prot = pmp_priv_to_page_prot(pmp_priv);
> - if (tlb_size != NULL) {
> - if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
> - *tlb_size = tlb_size_pmp;
> - }
> + if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
> + target_ulong tlb_sa = addr & ~(*tlb_size - 1);
> + target_ulong tlb_ea = tlb_sa + *tlb_size - 1;
> +
> + *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
> }
>
> return TRANSLATE_SUCCESS;
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..1172142e34 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -297,8 +297,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
>
> /*
> * Check if the address has required RWX privs to complete desired operation
> + * Return PMP rule index if a pmp rule match
> + * Return MAX_RISCV_PMPS if default match
> + * Return negtive value if no match
> */
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode)
> {
> @@ -310,8 +313,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
>
> /* Short cut if no rules */
> if (0 == pmp_get_num_rules(env)) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> if (size == 0) {
> @@ -338,7 +343,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> if ((s + e) == 1) {
> qemu_log_mask(LOG_GUEST_ERROR,
> "pmp violation - access is partially inside\n");
> - ret = 0;
> + ret = -1;
> break;
> }
>
> @@ -441,18 +446,22 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> }
> }
>
> - ret = ((privs & *allowed_privs) == privs);
> + if ((privs & *allowed_privs) == privs) {
> + ret = i;
> + }
> break;
> }
> }
>
> /* No rule matched */
> if (ret == -1) {
> - return pmp_hart_has_privs_default(env, addr, size, privs,
> - allowed_privs, mode);
> + if (pmp_hart_has_privs_default(env, addr, size, privs,
> + allowed_privs, mode)) {
> + ret = MAX_RISCV_PMPS;
> + }
> }
>
> - return ret == 1 ? true : false;
> + return ret;
> }
>
> /*
> @@ -595,8 +604,8 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
> * Calculate the TLB size if the start address or the end address of
> * PMP entry is presented in the TLB page.
> */
> -static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> - target_ulong tlb_sa, target_ulong tlb_ea)
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea)
> {
> target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
> target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
Error here.
Add "
+ if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
+ return tlb_ea - tlb_sa + 1;
+ }
"
Thanks,
Zhiwei
> @@ -616,33 +625,6 @@ static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> return 0;
> }
>
> -/*
> - * Check is there a PMP entry which range covers this page. If so,
> - * try to find the minimum granularity for the TLB size.
> - */
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size)
> -{
> - int i;
> - target_ulong val;
> - target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
> -
> - for (i = 0; i < MAX_RISCV_PMPS; i++) {
> - val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
> - if (val) {
> - if (*tlb_size == 0 || *tlb_size > val) {
> - *tlb_size = val;
> - }
> - }
> - }
> -
> - if (*tlb_size != 0) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> /*
> * Convert PMP privilege to TLB page privilege.
> */
> diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
> index a9a0b363a7..94c0b960fb 100644
> --- a/target/riscv/pmp.h
> +++ b/target/riscv/pmp.h
> @@ -68,11 +68,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
> void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val);
> target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
> -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> +int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
> target_ulong mode);
> -bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
> - target_ulong *tlb_size);
> +target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
> + target_ulong tlb_sa, target_ulong tlb_ea);
> void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
> void pmp_update_rule_nums(CPURISCVState *env);
> uint32_t pmp_get_num_rules(CPURISCVState *env);
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-12-17 3:30 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-23 9:09 [PATCH v3 1/1] target/riscv: Fix PMP propagation for tlb LIU Zhiwei
2021-11-23 9:09 ` LIU Zhiwei
2021-12-08 1:04 ` Alistair Francis
2021-12-08 1:04 ` Alistair Francis
2021-12-08 3:23 ` Alistair Francis
2021-12-08 3:23 ` Alistair Francis
2021-12-17 0:37 ` Alistair Francis
2021-12-17 0:37 ` Alistair Francis
2021-12-17 3:06 ` LIU Zhiwei
2021-12-17 3:06 ` LIU Zhiwei
2021-12-17 3:28 ` LIU Zhiwei
2021-12-17 3:28 ` LIU Zhiwei
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.