[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] riscv/target: fix vs interrupt delegation
From: |
Jose Martins |
Subject: |
[PATCH] riscv/target: fix vs interrupt delegation |
Date: |
Tue, 28 Jan 2020 17:12:35 +0000 |
User-agent: |
NeoMutt/20171215 |
Hello,
I've been having an issue delegating external interrupts to VS mode. I've set
the VSEI bit in hideleg. Then, to trigger the interrupt I set the VSEIP bit in
hip. However, this does not forward the external interrupt to VS mode, but to
HS mode.
Looking through the code, I see the VS to S interrupt cause translation is done
in riscv_cpu_local_irq_pending by immediately shifting right the pending vs
interrupts. So, this function will return the same cause either this is a HS
interrupt or a VS interrupt. Later, in riscv_cpu_do_interrupt, this is not
taken into account when checking the pending interrupt against the hypervisor
interrupt delegation register (hideleg). There will never be a match as the
"normal"
supervisor interrupt cannot be delegated to VS mode.
I believe an easy fix is to delay the cause translation until we know this
is indeed a delegated VS mode interrupt. Here is a patch:
Signed-off-by: José Martins <address@hidden>
---
target/riscv/cpu_helper.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7166e6199e..161dc34e0d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -46,7 +46,7 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
target_ulong pending = env->mip & env->mie &
~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
target_ulong vspending = (env->mip & env->mie &
- (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) >> 1;
+ (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP));
target_ulong mie = env->priv < PRV_M ||
(env->priv == PRV_M && mstatus_mie);
@@ -892,6 +892,9 @@ void riscv_cpu_do_interrupt(CPUState *cs)
if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1) &&
!riscv_cpu_force_hs_excep_enabled(env)) {
/* Trap to VS mode */
+ if(async){
+ cause -= 1;
+ }
} else if (riscv_cpu_virt_enabled(env)) {
/* Trap into HS mode, from virt */
riscv_cpu_swap_hypervisor_regs(env);
--
2.17.1
Regards,
Jose
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] riscv/target: fix vs interrupt delegation,
Jose Martins <=