diff options
| -rw-r--r-- | virt/kvm/arm/vgic.c | 88 |
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 | |||
| 597 | static 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 | */ | ||
| 616 | static 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 | |||
| 592 | static bool handle_mmio_sgi_clear(struct kvm_vcpu *vcpu, | 666 | static 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 | ||
