Loading arch/arm/kvm/vgic.c +14 −21 Original line number Diff line number Diff line Loading @@ -883,8 +883,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) lr, irq, vgic_cpu->vgic_lr[lr]); BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; goto out; return true; } /* Try to use another LR for this interrupt */ Loading @@ -898,7 +897,6 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) vgic_cpu->vgic_irq_lr_map[irq] = lr; set_bit(lr, vgic_cpu->lr_used); out: if (!vgic_irq_is_edge(vcpu, irq)) vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; Loading Loading @@ -1018,21 +1016,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); /* * We do not need to take the distributor lock here, since the only * action we perform is clearing the irq_active_bit for an EOIed * level interrupt. There is a potential race with * the queuing of an interrupt in __kvm_vgic_flush_hwstate(), where we * check if the interrupt is already active. Two possibilities: * * - The queuing is occurring on the same vcpu: cannot happen, * as we're already in the context of this vcpu, and * executing the handler * - The interrupt has been migrated to another vcpu, and we * ignore this interrupt for this run. Big deal. It is still * pending though, and will get considered when this vcpu * exits. */ if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { /* * Some level interrupts have been EOIed. Clear their Loading @@ -1054,6 +1037,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } else { vgic_cpu_irq_clear(vcpu, irq); } /* * Despite being EOIed, the LR may not have * been marked as empty. */ set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; } } Loading @@ -1064,9 +1054,8 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } /* * Sync back the VGIC state after a guest run. We do not really touch * the distributor here (the irq_pending_on_cpu bit is safe to set), * so there is no need for taking its lock. * Sync back the VGIC state after a guest run. The distributor lock is * needed so we don't get preempted in the middle of the state processing. */ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { Loading Loading @@ -1112,10 +1101,14 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { struct vgic_dist *dist = &vcpu->kvm->arch.vgic; if (!irqchip_in_kernel(vcpu->kvm)) return; spin_lock(&dist->lock); __kvm_vgic_sync_hwstate(vcpu); spin_unlock(&dist->lock); } int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) Loading Loading
arch/arm/kvm/vgic.c +14 −21 Original line number Diff line number Diff line Loading @@ -883,8 +883,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) lr, irq, vgic_cpu->vgic_lr[lr]); BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; goto out; return true; } /* Try to use another LR for this interrupt */ Loading @@ -898,7 +897,6 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) vgic_cpu->vgic_irq_lr_map[irq] = lr; set_bit(lr, vgic_cpu->lr_used); out: if (!vgic_irq_is_edge(vcpu, irq)) vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; Loading Loading @@ -1018,21 +1016,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); /* * We do not need to take the distributor lock here, since the only * action we perform is clearing the irq_active_bit for an EOIed * level interrupt. There is a potential race with * the queuing of an interrupt in __kvm_vgic_flush_hwstate(), where we * check if the interrupt is already active. Two possibilities: * * - The queuing is occurring on the same vcpu: cannot happen, * as we're already in the context of this vcpu, and * executing the handler * - The interrupt has been migrated to another vcpu, and we * ignore this interrupt for this run. Big deal. It is still * pending though, and will get considered when this vcpu * exits. */ if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { /* * Some level interrupts have been EOIed. Clear their Loading @@ -1054,6 +1037,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } else { vgic_cpu_irq_clear(vcpu, irq); } /* * Despite being EOIed, the LR may not have * been marked as empty. */ set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; } } Loading @@ -1064,9 +1054,8 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } /* * Sync back the VGIC state after a guest run. We do not really touch * the distributor here (the irq_pending_on_cpu bit is safe to set), * so there is no need for taking its lock. * Sync back the VGIC state after a guest run. The distributor lock is * needed so we don't get preempted in the middle of the state processing. */ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { Loading Loading @@ -1112,10 +1101,14 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { struct vgic_dist *dist = &vcpu->kvm->arch.vgic; if (!irqchip_in_kernel(vcpu->kvm)) return; spin_lock(&dist->lock); __kvm_vgic_sync_hwstate(vcpu); spin_unlock(&dist->lock); } int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) Loading