Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / arch / arm64 / kvm / vgic / vgic-v2.c
index 2c58020..95a18ce 100644 (file)
@@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
                u32 val = cpuif->vgic_lr[lr];
                u32 cpuid, intid = val & GICH_LR_VIRTUALID;
                struct vgic_irq *irq;
+               bool deactivated;
 
                /* Extract the source vCPU id from the LR */
                cpuid = val & GICH_LR_PHYSID_CPUID;
@@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 
                raw_spin_lock(&irq->irq_lock);
 
-               /* Always preserve the active bit */
+               /* Always preserve the active bit, note deactivation */
+               deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT);
                irq->active = !!(val & GICH_LR_ACTIVE_BIT);
 
                if (irq->active && vgic_irq_is_sgi(intid))
@@ -96,36 +98,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
                if (irq->config == VGIC_CONFIG_LEVEL && !(val & GICH_LR_STATE))
                        irq->pending_latch = false;
 
-               /*
-                * Level-triggered mapped IRQs are special because we only
-                * observe rising edges as input to the VGIC.
-                *
-                * If the guest never acked the interrupt we have to sample
-                * the physical line and set the line level, because the
-                * device state could have changed or we simply need to
-                * process the still pending interrupt later.
-                *
-                * If this causes us to lower the level, we have to also clear
-                * the physical active state, since we will otherwise never be
-                * told when the interrupt becomes asserted again.
-                *
-                * Another case is when the interrupt requires a helping hand
-                * on deactivation (no HW deactivation, for example).
-                */
-               if (vgic_irq_is_mapped_level(irq)) {
-                       bool resample = false;
-
-                       if (val & GICH_LR_PENDING_BIT) {
-                               irq->line_level = vgic_get_phys_line_level(irq);
-                               resample = !irq->line_level;
-                       } else if (vgic_irq_needs_resampling(irq) &&
-                                  !(irq->active || irq->pending_latch)) {
-                               resample = true;
-                       }
-
-                       if (resample)
-                               vgic_irq_set_phys_active(irq, false);
-               }
+               /* Handle resampling for mapped interrupts if required */
+               vgic_irq_handle_resampling(irq, deactivated, val & GICH_LR_PENDING_BIT);
 
                raw_spin_unlock(&irq->irq_lock);
                vgic_put_irq(vcpu->kvm, irq);