OSDN Git Service

KVM: arm/arm64: vgic-new: Implement kvm_vgic_vcpu_pending_irq
authorEric Auger <eric.auger@linaro.org>
Mon, 7 Dec 2015 15:30:38 +0000 (15:30 +0000)
committerChristoffer Dall <christoffer.dall@linaro.org>
Fri, 20 May 2016 13:39:49 +0000 (15:39 +0200)
Tell KVM whether a particular VCPU has an IRQ that needs handling
in the guest. This is used to decide whether a VCPU is runnable.

Signed-off-by: Eric Auger <eric.auger@linaro.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
include/kvm/vgic/vgic.h
virt/kvm/arm/vgic/vgic.c

index 9506267..f663288 100644 (file)
@@ -184,6 +184,8 @@ struct vgic_cpu {
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
                        bool level);
 
+int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
+
 #define irqchip_in_kernel(k)   (!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)    (false)
 #define vgic_ready(k)          ((k)->arch.vgic.ready)
index 0bf0d20..7e01008 100644 (file)
@@ -520,3 +520,28 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
        vgic_flush_lr_state(vcpu);
        spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock);
 }
+
+int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
+{
+       struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+       struct vgic_irq *irq;
+       bool pending = false;
+
+       if (!vcpu->kvm->arch.vgic.enabled)
+               return false;
+
+       spin_lock(&vgic_cpu->ap_list_lock);
+
+       list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
+               spin_lock(&irq->irq_lock);
+               pending = irq->pending && irq->enabled;
+               spin_unlock(&irq->irq_lock);
+
+               if (pending)
+                       break;
+       }
+
+       spin_unlock(&vgic_cpu->ap_list_lock);
+
+       return pending;
+}