When call kvm_vgic_inject_irq to inject irq, we can known which vcpu the IRQ for by the irq_num and the cpuid. So we should just kick this vcpu to avoid iterating through all. Signed-off-by: Shannon Zhao <zhaoshenglong@xxxxxxxxxx> --- virt/kvm/arm/vgic.c | 32 ++++++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 8 deletions(-) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 82db9d6..9dad67a 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -95,6 +95,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); static void vgic_update_state(struct kvm *kvm); static void vgic_kick_vcpus(struct kvm *kvm); +static void vgic_kick_vcpu(struct kvm *kvm, int cpuid); static u8 *vgic_get_sgi_sources(struct vgic_dist *dist, int vcpu_id, int sgi); static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); @@ -1589,6 +1590,21 @@ static void vgic_kick_vcpus(struct kvm *kvm) } } +static void vgic_kick_vcpu(struct kvm *kvm, int cpuid) +{ + struct kvm_vcpu *vcpu; + + /* + * We've injected an interrupt, kick the specified vcpu + */ + if (cpuid < atomic_read(&kvm->online_vcpus)) { + vcpu = kvm_get_vcpu(kvm, cpuid); + if (vcpu != NULL) { + kvm_vcpu_kick(vcpu); + } + } +} + static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level) { int edge_triggered = vgic_irq_is_edge(vcpu, irq); @@ -1607,7 +1623,7 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level) } } -static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, +static bool vgic_update_irq_pending(struct kvm *kvm, int *cpuid, unsigned int irq_num, bool level) { struct vgic_dist *dist = &kvm->arch.vgic; @@ -1618,7 +1634,7 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, spin_lock(&dist->lock); - vcpu = kvm_get_vcpu(kvm, cpuid); + vcpu = kvm_get_vcpu(kvm, *cpuid); edge_triggered = vgic_irq_is_edge(vcpu, irq_num); level_triggered = !edge_triggered; @@ -1628,11 +1644,11 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, } if (irq_num >= VGIC_NR_PRIVATE_IRQS) { - cpuid = dist->irq_spi_cpu[irq_num - VGIC_NR_PRIVATE_IRQS]; - vcpu = kvm_get_vcpu(kvm, cpuid); + *cpuid = dist->irq_spi_cpu[irq_num - VGIC_NR_PRIVATE_IRQS]; + vcpu = kvm_get_vcpu(kvm, *cpuid); } - kvm_debug("Inject IRQ%d level %d CPU%d\n", irq_num, level, cpuid); + kvm_debug("Inject IRQ%d level %d CPU%d\n", irq_num, level, *cpuid); if (level) { if (level_triggered) @@ -1666,7 +1682,7 @@ static bool vgic_update_irq_pending(struct kvm *kvm, int cpuid, if (level) { vgic_cpu_irq_set(vcpu, irq_num); - set_bit(cpuid, dist->irq_pending_on_cpu); + set_bit(*cpuid, dist->irq_pending_on_cpu); } out: @@ -1693,8 +1709,8 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, bool level) { if (likely(vgic_initialized(kvm)) && - vgic_update_irq_pending(kvm, cpuid, irq_num, level)) - vgic_kick_vcpus(kvm); + vgic_update_irq_pending(kvm, &cpuid, irq_num, level)) + vgic_kick_vcpu(kvm, cpuid); return 0; } -- 1.7.1 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm