Rather than having the device code calling into an ARM-private function in target-arm/kvm.c to deliver interrupts, we can use the generic kvm_set_irq() function. Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx> --- hw/arm_pic.c | 28 ++++++++++++++++++++++++++-- kvm.h | 2 -- target-arm/kvm.c | 39 ++++----------------------------------- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/hw/arm_pic.c b/hw/arm_pic.c index 9f60375..950e6c4 100644 --- a/hw/arm_pic.c +++ b/hw/arm_pic.c @@ -33,12 +33,36 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level) default: hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq); } +} - if (kvm_enabled()) - kvm_arch_interrupt(env, irq, level); +#ifdef CONFIG_KVM +static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + int kvm_irq; + + switch (irq) { + case ARM_PIC_CPU_IRQ: + kvm_irq = KVM_ARM_IRQ_LINE; + break; + case ARM_PIC_CPU_FIQ: + kvm_irq = KVM_ARM_FIQ_LINE; + break; + default: + hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq); + } + kvm_irq |= (env->cpu_index << 1); + kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0); } +#endif qemu_irq *arm_pic_init_cpu(ARMCPU *cpu) { +#ifdef CONFIG_KVM + if (kvm_enabled()) { + return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2); + } +#endif return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2); } diff --git a/kvm.h b/kvm.h index 4f6508a..5b8f588 100644 --- a/kvm.h +++ b/kvm.h @@ -182,8 +182,6 @@ int kvm_arch_init_vcpu(CPUArchState *env); void kvm_arch_reset_vcpu(CPUArchState *env); -int kvm_arch_interrupt(CPUArchState *env, int irq, int level); - int kvm_arch_on_sigbus_vcpu(CPUArchState *env, int code, void *addr); int kvm_arch_on_sigbus(int code, void *addr); diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 29bb51f..c0ee422 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -29,6 +29,10 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { int kvm_arch_init(KVMState *s) { + /* For ARM interrupt delivery is always asynchronous, + * whether we are using an in-kernel VGIC or not. + */ + kvm_async_interrupts_allowed = true; return 0; } @@ -151,41 +155,6 @@ int kvm_arch_get_registers(CPUARMState *env) return 0; } -#define KVM_ARM_EXCEPTION_IRQ 0x02 -#define KVM_ARM_EXCEPTION_FIQ 0x01 -int kvm_arch_interrupt(CPUARMState *env, int irq, int level) -{ - struct kvm_irq_level irq_level; - int vcpu_idx = env->cpu_index; - KVMState *s = kvm_state; - int ret; - - if (level) - irq_level.level = 1; - else - irq_level.level = 0; - - switch (irq) { - case ARM_PIC_CPU_IRQ: - irq_level.irq = KVM_ARM_IRQ_LINE | (vcpu_idx << 1); - break; - case ARM_PIC_CPU_FIQ: - irq_level.irq = KVM_ARM_FIQ_LINE | (vcpu_idx << 1); - break; - default: - fprintf(stderr, "unsupported ARM irq injection\n"); - abort(); - } - - ret = kvm_vm_ioctl(s, KVM_IRQ_LINE, &irq_level); - if (ret) { - fprintf(stderr, "kvm_vm_ioctl(s, KVM_IRQ_LINE, &irq_level) failed\n"); - abort(); - } - - return 0; -} - void kvm_arch_pre_run(CPUARMState *env, struct kvm_run *run) { } -- 1.7.9.5 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm