aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--virt/kvm/arm/vgic.c88
1 files changed, 83 insertions, 5 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 88599b585362..d08ba28e729a 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -589,6 +589,80 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu,
589 return false; 589 return false;
590} 590}
591 591
592#define LR_CPUID(lr) \
593 (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT)
594#define LR_IRQID(lr) \
595 ((lr) & GICH_LR_VIRTUALID)
596
597static void vgic_retire_lr(int lr_nr, int irq, struct vgic_cpu *vgic_cpu)
598{
599 clear_bit(lr_nr, vgic_cpu->lr_used);
600 vgic_cpu->vgic_lr[lr_nr] &= ~GICH_LR_STATE;
601 vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
602}
603
604/**
605 * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor
606 * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
607 *
608 * Move any pending IRQs that have already been assigned to LRs back to the
609 * emulated distributor state so that the complete emulated state can be read
610 * from the main emulation structures without investigating the LRs.
611 *
612 * Note that IRQs in the active state in the LRs get their pending state moved
613 * to the distributor but the active state stays in the LRs, because we don't
614 * track the active state on the distributor side.
615 */
616static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
617{
618 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
619 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
620 int vcpu_id = vcpu->vcpu_id;
621 int i, irq, source_cpu;
622 u32 *lr;
623
624 for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
625 lr = &vgic_cpu->vgic_lr[i];
626 irq = LR_IRQID(*lr);
627 source_cpu = LR_CPUID(*lr);
628
629 /*
630 * There are three options for the state bits:
631 *
632 * 01: pending
633 * 10: active
634 * 11: pending and active
635 *
636 * If the LR holds only an active interrupt (not pending) then
637 * just leave it alone.
638 */
639 if ((*lr & GICH_LR_STATE) == GICH_LR_ACTIVE_BIT)
640 continue;
641
642 /*
643 * Reestablish the pending state on the distributor and the
644 * CPU interface. It may have already been pending, but that
645 * is fine, then we are only setting a few bits that were
646 * already set.
647 */
648 vgic_dist_irq_set(vcpu, irq);
649 if (irq < VGIC_NR_SGIS)
650 dist->irq_sgi_sources[vcpu_id][irq] |= 1 << source_cpu;
651 *lr &= ~GICH_LR_PENDING_BIT;
652
653 /*
654 * If there's no state left on the LR (it could still be
655 * active), then the LR does not hold any useful info and can
656 * be marked as free for other use.
657 */
658 if (!(*lr & GICH_LR_STATE))
659 vgic_retire_lr(i, irq, vgic_cpu);
660
661 /* Finally update the VGIC state. */
662 vgic_update_state(vcpu->kvm);
663 }
664}
665
592static bool handle_mmio_sgi_clear(struct kvm_vcpu *vcpu, 666static bool handle_mmio_sgi_clear(struct kvm_vcpu *vcpu,
593 struct kvm_exit_mmio *mmio, 667 struct kvm_exit_mmio *mmio,
594 phys_addr_t offset) 668 phys_addr_t offset)
@@ -848,8 +922,6 @@ static void vgic_update_state(struct kvm *kvm)
848 } 922 }
849} 923}
850 924
851#define LR_CPUID(lr) \
852 (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT)
853#define MK_LR_PEND(src, irq) \ 925#define MK_LR_PEND(src, irq) \
854 (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq)) 926 (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq))
855 927
@@ -871,9 +943,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
871 int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; 943 int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
872 944
873 if (!vgic_irq_is_enabled(vcpu, irq)) { 945 if (!vgic_irq_is_enabled(vcpu, irq)) {
874 vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; 946 vgic_retire_lr(lr, irq, vgic_cpu);
875 clear_bit(lr, vgic_cpu->lr_used);
876 vgic_cpu->vgic_lr[lr] &= ~GICH_LR_STATE;
877 if (vgic_irq_is_active(vcpu, irq)) 947 if (vgic_irq_is_active(vcpu, irq))
878 vgic_irq_clear_active(vcpu, irq); 948 vgic_irq_clear_active(vcpu, irq);
879 } 949 }
@@ -1675,6 +1745,14 @@ static int vgic_attr_regs_access(struct kvm_device *dev,
1675 } 1745 }
1676 } 1746 }
1677 1747
1748 /*
1749 * Move all pending IRQs from the LRs on all VCPUs so the pending
1750 * state can be properly represented in the register state accessible
1751 * through this API.
1752 */
1753 kvm_for_each_vcpu(c, tmp_vcpu, dev->kvm)
1754 vgic_unqueue_irqs(tmp_vcpu);
1755
1678 offset -= r->base; 1756 offset -= r->base;
1679 r->handle_mmio(vcpu, &mmio, offset); 1757 r->handle_mmio(vcpu, &mmio, offset);
1680 1758