diff options
author | Alexei Filippov <alexei.filippov@syntacore.com> | 2024-05-03 13:30:52 +0300 |
---|---|---|
committer | Michael Tokarev <mjt@tls.msk.ru> | 2024-06-05 13:05:48 +0300 |
commit | a58758c5df749a0d7133231cf68c9d9384424304 (patch) | |
tree | f388a85a080271b7cd7aa1fc228cc759759e8826 /target | |
parent | ab2d6e74127bda26f4cc42e7b52f0ae224dc2a4e (diff) |
target/riscv: do not set mtval2 for non guest-page faults
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
translation part, mtval2 will be set in case of successes 2 stage translation but
failed pmp check.
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
page-fault is taken into M-mode, mtval2 is written with either zero or guest
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
is set to zero...*
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 6c9a344247132ac6c3d0eb9670db45149a29c88f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Diffstat (limited to 'target')
-rw-r--r-- | target/riscv/cpu_helper.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index e3a7797d00..484edad900 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1375,17 +1375,17 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, __func__, pa, ret, prot_pmp, tlb_size); prot &= prot_pmp; - } - - if (ret != TRANSLATE_SUCCESS) { + } else { /* * Guest physical address translation failed, this is a HS * level exception */ first_stage_error = false; - env->guest_phys_fault_addr = (im_address | - (address & - (TARGET_PAGE_SIZE - 1))) >> 2; + if (ret != TRANSLATE_PMP_FAIL) { + env->guest_phys_fault_addr = (im_address | + (address & + (TARGET_PAGE_SIZE - 1))) >> 2; + } } } } else { |