|
@@ -1694,16 +1694,26 @@ out:
|
|
|
int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
|
|
|
bool level)
|
|
|
{
|
|
|
+ int ret = 0;
|
|
|
int vcpu_id;
|
|
|
|
|
|
- if (likely(vgic_ready(kvm))) {
|
|
|
- vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
|
|
|
- if (vcpu_id >= 0)
|
|
|
- /* kick the specified vcpu */
|
|
|
- kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
|
|
|
+ if (unlikely(!vgic_initialized(kvm))) {
|
|
|
+ mutex_lock(&kvm->lock);
|
|
|
+ ret = vgic_init(kvm);
|
|
|
+ mutex_unlock(&kvm->lock);
|
|
|
+
|
|
|
+ if (ret)
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
- return 0;
|
|
|
+ vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
|
|
|
+ if (vcpu_id >= 0) {
|
|
|
+ /* kick the specified vcpu */
|
|
|
+ kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
|
|
|
+ }
|
|
|
+
|
|
|
+out:
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static irqreturn_t vgic_maintenance_handler(int irq, void *data)
|