From 88d616f1c2f12532f8ff517fc5be5b8c8c067051 Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Wed, 27 Mar 2024 16:18:12 +0800 Subject: [PATCH] AIA: Take interrupts at VS level through vstopi instead of vsip and vsie An interrupt is pending at VS level if and only if vstopi is not 0. The modification is backward compatible because hvictl is implicitly 0 without AIA. --- riscv/processor.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/riscv/processor.cc b/riscv/processor.cc index 91b6d0b33c..6dfa09c569 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -907,9 +907,11 @@ reg_t processor_t::select_an_interrupt_with_default_priority(reg_t enabled_inter void processor_t::take_interrupt(reg_t pending_interrupts) { const reg_t s_pending_interrupts = state.nonvirtual_sip->read() & state.nonvirtual_sie->read(); + const reg_t vstopi = state.vstopi->read(); + const reg_t vs_pending_interrupt = vstopi ? ((reg_t(1) << get_field(vstopi, MTOPI_IID)) << 1) : 0; // SSIP -> VSSIP, etc // Do nothing if no pending interrupts - if (!pending_interrupts && !s_pending_interrupts) { + if (!pending_interrupts && !s_pending_interrupts && !vs_pending_interrupt == 0) { return; } @@ -928,9 +930,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) enabled_interrupts = s_pending_interrupts & deleg_to_hs & -hs_enabled; if (state.v && enabled_interrupts == 0) { // VS-ints have least priority and can only be taken with virt enabled - const reg_t deleg_to_vs = state.hideleg->read(); const reg_t vs_enabled = state.prv < PRV_S || (state.prv == PRV_S && sie); - enabled_interrupts = pending_interrupts & deleg_to_vs & -vs_enabled; + enabled_interrupts = vs_pending_interrupt & -vs_enabled; } }