OSDN Git Service

irqchip/gic-v4.1: Move doorbell management to the GICv4 abstraction layer
[tomoyo/tomoyo-test1.git] / virt / kvm / arm / vgic / vgic-v4.c
index 46f8755..1eb0f8c 100644 (file)
  * it. And if we've migrated our vcpu from one CPU to another, we must
  * tell the ITS (so that the messages reach the right redistributor).
  * This is done in two steps: first issue a irq_set_affinity() on the
- * irq corresponding to the vcpu, then call its_schedule_vpe(). You
- * must be in a non-preemptible context. On exit, another call to
- * its_schedule_vpe() tells the redistributor that we're done with the
- * vcpu.
+ * irq corresponding to the vcpu, then call its_make_vpe_resident().
+ * You must be in a non-preemptible context. On exit, a call to
+ * its_make_vpe_non_resident() tells the redistributor that we're done
+ * with the vcpu.
  *
  * Finally, the doorbell handling: Each vcpu is allocated an interrupt
  * which will fire each time a VLPI is made pending whilst the vcpu is
@@ -86,7 +86,8 @@ static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
        struct kvm_vcpu *vcpu = info;
 
        /* We got the message, no need to fire again */
-       if (!irqd_irq_disabled(&irq_to_desc(irq)->irq_data))
+       if (!kvm_vgic_global_state.has_gicv4_1 &&
+           !irqd_irq_disabled(&irq_to_desc(irq)->irq_data))
                disable_irq_nosync(irq);
 
        vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true;
@@ -199,19 +200,11 @@ void vgic_v4_teardown(struct kvm *kvm)
 int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db)
 {
        struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
-       struct irq_desc *desc = irq_to_desc(vpe->irq);
 
        if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident)
                return 0;
 
-       /*
-        * If blocking, a doorbell is required. Undo the nested
-        * disable_irq() calls...
-        */
-       while (need_db && irqd_irq_disabled(&desc->irq_data))
-               enable_irq(vpe->irq);
-
-       return its_schedule_vpe(vpe, false);
+       return its_make_vpe_non_resident(vpe, need_db);
 }
 
 int vgic_v4_load(struct kvm_vcpu *vcpu)
@@ -232,18 +225,19 @@ int vgic_v4_load(struct kvm_vcpu *vcpu)
        if (err)
                return err;
 
-       /* Disabled the doorbell, as we're about to enter the guest */
-       disable_irq_nosync(vpe->irq);
-
-       err = its_schedule_vpe(vpe, true);
+       err = its_make_vpe_resident(vpe, false, vcpu->kvm->arch.vgic.enabled);
        if (err)
                return err;
 
        /*
         * Now that the VPE is resident, let's get rid of a potential
-        * doorbell interrupt that would still be pending.
+        * doorbell interrupt that would still be pending. This is a
+        * GICv4.0 only "feature"...
         */
-       return irq_set_irqchip_state(vpe->irq, IRQCHIP_STATE_PENDING, false);
+       if (!kvm_vgic_global_state.has_gicv4_1)
+               err = irq_set_irqchip_state(vpe->irq, IRQCHIP_STATE_PENDING, false);
+
+       return err;
 }
 
 static struct vgic_its *vgic_get_its(struct kvm *kvm,