diff options
author | Yifei Jiang <jiangyifei@huawei.com> | 2022-01-12 16:13:23 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2022-01-21 15:52:56 +1000 |
commit | 2b650fbbcc2b5d34943bb5697d8799b2c1a885e1 (patch) | |
tree | 0dc8990b7f8e79dc9b006e5a54ef9deb02c6b960 /target | |
parent | ad40be27084536408b47a9209181f776ec2c54a5 (diff) | |
download | qemu-2b650fbbcc2b5d34943bb5697d8799b2c1a885e1.zip qemu-2b650fbbcc2b5d34943bb5697d8799b2c1a885e1.tar.gz qemu-2b650fbbcc2b5d34943bb5697d8799b2c1a885e1.tar.bz2 |
target/riscv: Support setting external interrupt by KVM
When KVM is enabled, set the S-mode external interrupt through
kvm_riscv_set_irq function.
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
Signed-off-by: Mingwang Li <limingwang@huawei.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Message-id: 20220112081329.1835-8-jiangyifei@huawei.com
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/riscv/cpu.c | 6 | ||||
-rw-r--r-- | target/riscv/kvm-stub.c | 5 | ||||
-rw-r--r-- | target/riscv/kvm.c | 17 | ||||
-rw-r--r-- | target/riscv/kvm_riscv.h | 1 |
4 files changed, 28 insertions, 1 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index a6922dd..53b0524 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -630,7 +630,11 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) case IRQ_S_EXT: case IRQ_VS_EXT: case IRQ_M_EXT: - riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); + if (kvm_enabled()) { + kvm_riscv_set_irq(cpu, irq, level); + } else { + riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); + } break; default: g_assert_not_reached(); diff --git a/target/riscv/kvm-stub.c b/target/riscv/kvm-stub.c index 39b96fe..4e8fc31 100644 --- a/target/riscv/kvm-stub.c +++ b/target/riscv/kvm-stub.c @@ -23,3 +23,8 @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu) { abort(); } + +void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level) +{ + abort(); +} diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c index d5c6a9d..0ba6479 100644 --- a/target/riscv/kvm.c +++ b/target/riscv/kvm.c @@ -385,6 +385,23 @@ 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) { + perror("kvm riscv set irq != IRQ_S_EXT\n"); + abort(); + } + + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq); + if (ret < 0) { + perror("Set irq failed"); + abort(); + } +} + bool kvm_arch_cpu_check_are_resettable(void) { return true; diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h index f38c82b..ed281bd 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 |