Message ID | 20240413105929.7030-2-alexei.filippov@syntacore.com |
---|---|
State | New |
Headers | show |
Series | [1/2] target/riscv: prioritize pmp errors in raise_mmu_exception() | expand |
On 4/13/24 07:59, Alexei Filippov wrote: > 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> > target/riscv/cpu_helper.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index 196166f8dd..89e659fe3a 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -1410,17 +1410,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 {
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 196166f8dd..89e659fe3a 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1410,17 +1410,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 {
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> --- target/riscv/cpu_helper.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)