diff options
| author | Anup Patel <anup.patel@wdc.com> | 2022-02-04 23:16:40 +0530 |
|---|---|---|
| committer | Alistair Francis <alistair.francis@wdc.com> | 2022-02-16 12:24:18 +1000 |
| commit | 02d9565b92c97af6bac2ff1bb18967a5e95b9694 (patch) | |
| tree | a8fa240303e2707d7a981ba9c9f6000fb78262f6 | |
| parent | cd032fe75c1f7b24ccad772d50bfb689e7f5835d (diff) | |
| download | focaccia-qemu-02d9565b92c97af6bac2ff1bb18967a5e95b9694.tar.gz focaccia-qemu-02d9565b92c97af6bac2ff1bb18967a5e95b9694.zip | |
target/riscv: Improve delivery of guest external interrupts
The guest external interrupts from an interrupt controller are delivered only when the Guest/VM is running (i.e. V=1). This means any guest external interrupt which is triggered while the Guest/VM is not running (i.e. V=0) will be missed on QEMU resulting in Guest with sluggish response to serial console input and other I/O events. To solve this, we check and inject interrupt after setting V=1. Signed-off-by: Anup Patel <anup.patel@wdc.com> Signed-off-by: Anup Patel <anup@brainfault.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Frank Chang <frank.chang@sifive.com> Message-id: 20220204174700.534953-5-anup@brainfault.org Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
| -rw-r--r-- | target/riscv/cpu_helper.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 698389ba1b..e45ca08ea9 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -326,6 +326,19 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable) } env->virt = set_field(env->virt, VIRT_ONOFF, enable); + + if (enable) { + /* + * The guest external interrupts from an interrupt controller are + * delivered only when the Guest/VM is running (i.e. V=1). This means + * any guest external interrupt which is triggered while the Guest/VM + * is not running (i.e. V=0) will be missed on QEMU resulting in guest + * with sluggish response to serial console input and other I/O events. + * + * To solve this, we check and inject interrupt after setting V=1. + */ + riscv_cpu_update_mip(env_archcpu(env), 0, 0); + } } bool riscv_cpu_two_stage_lookup(int mmu_idx) |