On Thu, Dec 3, 2020 at 4:47 AM Yifei Jiang <jiangyifei@xxxxxxxxxx> wrote: > > Only support supervisor external interrupt currently. > > Signed-off-by: Yifei Jiang <jiangyifei@xxxxxxxxxx> > Signed-off-by: Yipeng Yin <yinyipeng1@xxxxxxxxxx> > --- > hw/intc/sifive_plic.c | 31 ++++++++++++++++++++++--------- > target/riscv/kvm.c | 19 +++++++++++++++++++ > target/riscv/kvm_riscv.h | 1 + > 3 files changed, 42 insertions(+), 9 deletions(-) > > diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c > index 97a1a27a9a..a419ca3a3c 100644 > --- a/hw/intc/sifive_plic.c > +++ b/hw/intc/sifive_plic.c > @@ -31,6 +31,8 @@ > #include "target/riscv/cpu.h" > #include "sysemu/sysemu.h" > #include "migration/vmstate.h" > +#include "sysemu/kvm.h" > +#include "kvm_riscv.h" > > #define RISCV_DEBUG_PLIC 0 > > @@ -147,15 +149,26 @@ static void sifive_plic_update(SiFivePLICState *plic) > continue; > } > int level = sifive_plic_irqs_pending(plic, addrid); > - switch (mode) { > - case PLICMode_M: > - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level)); > - break; > - case PLICMode_S: > - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level)); > - break; > - default: > - break; > + if (kvm_enabled()) { > + if (mode == PLICMode_M) { > + continue; > + } > +#ifdef CONFIG_KVM > + kvm_riscv_set_irq(RISCV_CPU(cpu), IRQ_S_EXT, level); > +#endif What if kvm_enalbed() is true, but CONFIG_KVM isn't defined? Alistair > + } else { > + switch (mode) { > + case PLICMode_M: > + riscv_cpu_update_mip(RISCV_CPU(cpu), > + MIP_MEIP, BOOL_TO_MASK(level)); > + break; > + case PLICMode_S: > + riscv_cpu_update_mip(RISCV_CPU(cpu), > + MIP_SEIP, BOOL_TO_MASK(level)); > + break; > + default: > + break; > + } > } > } > > diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c > index 6250ca0c7d..b01ff0754c 100644 > --- a/target/riscv/kvm.c > +++ b/target/riscv/kvm.c > @@ -454,3 +454,22 @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu) > env->satp = 0; > } > > +void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level) > +{ > + int ret; > + unsigned virq = level ? KVM_INTERRUPT_SET : KVM_INTERRUPT_UNSET; > + > + if (irq != IRQ_S_EXT) { > + return; > + } > + > + if (!kvm_enabled()) { > + return; > + } > + > + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq); > + if (ret < 0) { > + perror("Set irq failed"); > + abort(); > + } > +} > diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h > index f38c82bf59..ed281bdce0 100644 > --- a/target/riscv/kvm_riscv.h > +++ b/target/riscv/kvm_riscv.h > @@ -20,5 +20,6 @@ > #define QEMU_KVM_RISCV_H > > void kvm_riscv_reset_vcpu(RISCVCPU *cpu); > +void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level); > > #endif > -- > 2.19.1 > >