* [PATCH v3] target/riscv: fix H extension TVM trap
@ 2023-03-10 16:42 Yi Chen
2023-03-12 9:28 ` liweiwei
0 siblings, 1 reply; 2+ messages in thread
From: Yi Chen @ 2023-03-10 16:42 UTC (permalink / raw)
To: qemu-devel
Cc: Yi Chen, Palmer Dabbelt, Alistair Francis, Bin Meng, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, open list:RISC-V TCG CPUs
- Trap satp/hgatp accesses from HS-mode when MSTATUS.TVM is enabled.
- Trap satp accesses from VS-mode when HSTATUS.VTVM is enabled.
- Raise RISCV_EXCP_ILLEGAL_INST when U-mode executes SFENCE.VMA/SINVAL.VMA.
- Raise RISCV_EXCP_VIRT_INSTRUCTION_FAULT when VU-mode executes
SFENCE.VMA/SINVAL.VMA or VS-mode executes SFENCE.VMA/SINVAL.VMA with
HSTATUS.VTVM enabled.
- Raise RISCV_EXCP_VIRT_INSTRUCTION_FAULT when VU-mode executes
HFENCE.GVMA/HFENCE.VVMA/HINVAL.GVMA/HINVAL.VVMA.
Signed-off-by: Yi Chen <chenyi2000@zju.edu.cn>
---
target/riscv/csr.c | 56 +++++++++++++++++++++++++---------------
target/riscv/op_helper.c | 12 ++++-----
2 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d522efc0b6..26a02e57bd 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -443,6 +443,30 @@ static RISCVException sstc_32(CPURISCVState *env, int csrno)
return sstc(env, csrno);
}
+static RISCVException satp(CPURISCVState *env, int csrno)
+{
+ if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
+ get_field(env->mstatus, MSTATUS_TVM)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ if (env->priv == PRV_S && riscv_cpu_virt_enabled(env) &&
+ get_field(env->hstatus, HSTATUS_VTVM)) {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+
+ return smode(env, csrno);
+}
+
+static RISCVException hgatp(CPURISCVState *env, int csrno)
+{
+ if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
+ get_field(env->mstatus, MSTATUS_TVM)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return hmode(env, csrno);
+}
+
/* Checks if PointerMasking registers could be accessed */
static RISCVException pointer_masking(CPURISCVState *env, int csrno)
{
@@ -2655,13 +2679,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
*val = 0;
return RISCV_EXCP_NONE;
}
-
- if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
- return RISCV_EXCP_ILLEGAL_INST;
- } else {
- *val = env->satp;
- }
-
+ *val = env->satp;
return RISCV_EXCP_NONE;
}
@@ -2684,18 +2702,14 @@ static RISCVException write_satp(CPURISCVState *env, int csrno,
}
if (vm && mask) {
- if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
- return RISCV_EXCP_ILLEGAL_INST;
- } else {
- /*
- * The ISA defines SATP.MODE=Bare as "no translation", but we still
- * pass these through QEMU's TLB emulation as it improves
- * performance. Flushing the TLB on SATP writes with paging
- * enabled avoids leaking those invalid cached mappings.
- */
- tlb_flush(env_cpu(env));
- env->satp = val;
- }
+ /*
+ * The ISA defines SATP.MODE=Bare as "no translation", but we still
+ * pass these through QEMU's TLB emulation as it improves
+ * performance. Flushing the TLB on SATP writes with paging
+ * enabled avoids leaking those invalid cached mappings.
+ */
+ tlb_flush(env_cpu(env));
+ env->satp = val;
}
return RISCV_EXCP_NONE;
}
@@ -4180,7 +4194,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
.min_priv_ver = PRIV_VERSION_1_12_0 },
/* Supervisor Protection and Translation */
- [CSR_SATP] = { "satp", smode, read_satp, write_satp },
+ [CSR_SATP] = { "satp", satp, read_satp, write_satp },
/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
[CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
@@ -4217,7 +4231,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
.min_priv_ver = PRIV_VERSION_1_12_0 },
[CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
.min_priv_ver = PRIV_VERSION_1_12_0 },
- [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
+ [CSR_HGATP] = { "hgatp", hgatp, read_hgatp, write_hgatp,
.min_priv_ver = PRIV_VERSION_1_12_0 },
[CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta,
write_htimedelta,
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 84ee018f7d..093c2c6154 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -381,12 +381,12 @@ void helper_wfi(CPURISCVState *env)
void helper_tlb_flush(CPURISCVState *env)
{
CPUState *cs = env_cpu(env);
- if (!(env->priv >= PRV_S) ||
- (env->priv == PRV_S &&
- get_field(env->mstatus, MSTATUS_TVM))) {
+ if (!riscv_cpu_virt_enabled(env) &&
+ (env->priv == PRV_U ||
+ (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)))) {
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
- } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
- get_field(env->hstatus, HSTATUS_VTVM)) {
+ } else if (riscv_cpu_virt_enabled(env) &&
+ (env->priv == PRV_U || get_field(env->hstatus, HSTATUS_VTVM))) {
riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
} else {
tlb_flush(cs);
@@ -403,7 +403,7 @@ void helper_hyp_tlb_flush(CPURISCVState *env)
{
CPUState *cs = env_cpu(env);
- if (env->priv == PRV_S && riscv_cpu_virt_enabled(env)) {
+ if (env->priv <= PRV_S && riscv_cpu_virt_enabled(env)) {
riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
}
--
2.39.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v3] target/riscv: fix H extension TVM trap
2023-03-10 16:42 [PATCH v3] target/riscv: fix H extension TVM trap Yi Chen
@ 2023-03-12 9:28 ` liweiwei
0 siblings, 0 replies; 2+ messages in thread
From: liweiwei @ 2023-03-12 9:28 UTC (permalink / raw)
To: Yi Chen, qemu-devel
Cc: Palmer Dabbelt, Alistair Francis, Bin Meng, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei, open list:RISC-V TCG CPUs
On 2023/3/11 00:42, Yi Chen wrote:
> - Trap satp/hgatp accesses from HS-mode when MSTATUS.TVM is enabled.
> - Trap satp accesses from VS-mode when HSTATUS.VTVM is enabled.
> - Raise RISCV_EXCP_ILLEGAL_INST when U-mode executes SFENCE.VMA/SINVAL.VMA.
> - Raise RISCV_EXCP_VIRT_INSTRUCTION_FAULT when VU-mode executes
> SFENCE.VMA/SINVAL.VMA or VS-mode executes SFENCE.VMA/SINVAL.VMA with
> HSTATUS.VTVM enabled.
> - Raise RISCV_EXCP_VIRT_INSTRUCTION_FAULT when VU-mode executes
> HFENCE.GVMA/HFENCE.VVMA/HINVAL.GVMA/HINVAL.VVMA.
>
> Signed-off-by: Yi Chen <chenyi2000@zju.edu.cn>
I remember I have sent reviewed-by for this patch. Please add the
Reviewed-by.
> ---
It's better to describe the changes between different versions here.
> target/riscv/csr.c | 56 +++++++++++++++++++++++++---------------
> target/riscv/op_helper.c | 12 ++++-----
> 2 files changed, 41 insertions(+), 27 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d522efc0b6..26a02e57bd 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -443,6 +443,30 @@ static RISCVException sstc_32(CPURISCVState *env, int csrno)
> return sstc(env, csrno);
> }
>
> +static RISCVException satp(CPURISCVState *env, int csrno)
> +{
> + if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
> + get_field(env->mstatus, MSTATUS_TVM)) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> + if (env->priv == PRV_S && riscv_cpu_virt_enabled(env) &&
> + get_field(env->hstatus, HSTATUS_VTVM)) {
> + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> + }
> +
> + return smode(env, csrno);
> +}
> +
> +static RISCVException hgatp(CPURISCVState *env, int csrno)
> +{
> + if (env->priv == PRV_S && !riscv_cpu_virt_enabled(env) &&
> + get_field(env->mstatus, MSTATUS_TVM)) {
> + return RISCV_EXCP_ILLEGAL_INST;
> + }
> +
> + return hmode(env, csrno);
> +}
> +
> /* Checks if PointerMasking registers could be accessed */
> static RISCVException pointer_masking(CPURISCVState *env, int csrno)
> {
> @@ -2655,13 +2679,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
> *val = 0;
> return RISCV_EXCP_NONE;
> }
> -
> - if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - } else {
> - *val = env->satp;
> - }
> -
> + *val = env->satp;
> return RISCV_EXCP_NONE;
> }
>
> @@ -2684,18 +2702,14 @@ static RISCVException write_satp(CPURISCVState *env, int csrno,
> }
>
> if (vm && mask) {
> - if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
> - return RISCV_EXCP_ILLEGAL_INST;
> - } else {
> - /*
> - * The ISA defines SATP.MODE=Bare as "no translation", but we still
> - * pass these through QEMU's TLB emulation as it improves
> - * performance. Flushing the TLB on SATP writes with paging
> - * enabled avoids leaking those invalid cached mappings.
> - */
> - tlb_flush(env_cpu(env));
> - env->satp = val;
> - }
> + /*
> + * The ISA defines SATP.MODE=Bare as "no translation", but we still
> + * pass these through QEMU's TLB emulation as it improves
> + * performance. Flushing the TLB on SATP writes with paging
> + * enabled avoids leaking those invalid cached mappings.
> + */
> + tlb_flush(env_cpu(env));
> + env->satp = val;
> }
> return RISCV_EXCP_NONE;
> }
> @@ -4180,7 +4194,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> .min_priv_ver = PRIV_VERSION_1_12_0 },
>
> /* Supervisor Protection and Translation */
> - [CSR_SATP] = { "satp", smode, read_satp, write_satp },
> + [CSR_SATP] = { "satp", satp, read_satp, write_satp },
>
> /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
> [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
> @@ -4217,7 +4231,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> .min_priv_ver = PRIV_VERSION_1_12_0 },
> [CSR_HGEIP] = { "hgeip", hmode, read_hgeip,
> .min_priv_ver = PRIV_VERSION_1_12_0 },
> - [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp,
> + [CSR_HGATP] = { "hgatp", hgatp, read_hgatp, write_hgatp,
> .min_priv_ver = PRIV_VERSION_1_12_0 },
> [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta,
> write_htimedelta,
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 84ee018f7d..093c2c6154 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -381,12 +381,12 @@ void helper_wfi(CPURISCVState *env)
> void helper_tlb_flush(CPURISCVState *env)
> {
> CPUState *cs = env_cpu(env);
> - if (!(env->priv >= PRV_S) ||
> - (env->priv == PRV_S &&
> - get_field(env->mstatus, MSTATUS_TVM))) {
> + if (!riscv_cpu_virt_enabled(env) &&
> + (env->priv == PRV_U ||
> + (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)))) {
> riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> - } else if (riscv_has_ext(env, RVH) && riscv_cpu_virt_enabled(env) &&
> - get_field(env->hstatus, HSTATUS_VTVM)) {
> + } else if (riscv_cpu_virt_enabled(env) &&
> + (env->priv == PRV_U || get_field(env->hstatus, HSTATUS_VTVM))) {
> riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
> } else {
> tlb_flush(cs);
> @@ -403,7 +403,7 @@ void helper_hyp_tlb_flush(CPURISCVState *env)
> {
> CPUState *cs = env_cpu(env);
>
> - if (env->priv == PRV_S && riscv_cpu_virt_enabled(env)) {
> + if (env->priv <= PRV_S && riscv_cpu_virt_enabled(env)) {
> riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
> }
By the way, the check for "env->priv <= PRV_S " is not neccessary when
riscv_cpu_virt_enabled(env) is true
since only VS/VU mode is supported currently.
Regards,
Weiwei Li
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-03-12 9:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-10 16:42 [PATCH v3] target/riscv: fix H extension TVM trap Yi Chen
2023-03-12 9:28 ` liweiwei
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.