KVM: arm64: add active register handling to GICv3 emulation as well
authorAndre Przywara <andre.przywara@arm.com>
Thu, 23 Apr 2015 19:01:53 +0000 (20:01 +0100)
committerMarc Zyngier <marc.zyngier@arm.com>
Tue, 9 Jun 2015 17:05:17 +0000 (18:05 +0100)
Commit 47a98b15ba7c ("arm/arm64: KVM: support for un-queuing active
IRQs") introduced handling of the GICD_I[SC]ACTIVER registers,
but only for the GICv2 emulation. For the sake of completeness and
as this is a pre-requisite for save/restore of the GICv3 distributor
state, we should also emulate their handling in the distributor and
redistributor frames of an emulated GICv3.

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
virt/kvm/arm/vgic-v3-emul.c

index e9c3a7a83833bf2ef058cfd407b92bafe20da073..2b369de04e8e8b0a700809199d1d1c36456834b6 100644 (file)
@@ -173,6 +173,32 @@ static bool handle_mmio_clear_pending_reg_dist(struct kvm_vcpu *vcpu,
        return false;
 }
 
+static bool handle_mmio_set_active_reg_dist(struct kvm_vcpu *vcpu,
+                                           struct kvm_exit_mmio *mmio,
+                                           phys_addr_t offset)
+{
+       if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8))
+               return vgic_handle_set_active_reg(vcpu->kvm, mmio, offset,
+                                                  vcpu->vcpu_id);
+
+       vgic_reg_access(mmio, NULL, offset,
+                       ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
+       return false;
+}
+
+static bool handle_mmio_clear_active_reg_dist(struct kvm_vcpu *vcpu,
+                                             struct kvm_exit_mmio *mmio,
+                                             phys_addr_t offset)
+{
+       if (likely(offset >= VGIC_NR_PRIVATE_IRQS / 8))
+               return vgic_handle_clear_active_reg(vcpu->kvm, mmio, offset,
+                                                   vcpu->vcpu_id);
+
+       vgic_reg_access(mmio, NULL, offset,
+                       ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
+       return false;
+}
+
 static bool handle_mmio_priority_reg_dist(struct kvm_vcpu *vcpu,
                                          struct kvm_exit_mmio *mmio,
                                          phys_addr_t offset)
@@ -428,13 +454,13 @@ static const struct vgic_io_range vgic_v3_dist_ranges[] = {
                .base           = GICD_ISACTIVER,
                .len            = 0x80,
                .bits_per_irq   = 1,
-               .handle_mmio    = handle_mmio_raz_wi,
+               .handle_mmio    = handle_mmio_set_active_reg_dist,
        },
        {
                .base           = GICD_ICACTIVER,
                .len            = 0x80,
                .bits_per_irq   = 1,
-               .handle_mmio    = handle_mmio_raz_wi,
+               .handle_mmio    = handle_mmio_clear_active_reg_dist,
        },
        {
                .base           = GICD_IPRIORITYR,
@@ -561,6 +587,26 @@ static bool handle_mmio_clear_enable_reg_redist(struct kvm_vcpu *vcpu,
                                      ACCESS_WRITE_CLEARBIT);
 }
 
+static bool handle_mmio_set_active_reg_redist(struct kvm_vcpu *vcpu,
+                                             struct kvm_exit_mmio *mmio,
+                                             phys_addr_t offset)
+{
+       struct kvm_vcpu *redist_vcpu = mmio->private;
+
+       return vgic_handle_set_active_reg(vcpu->kvm, mmio, offset,
+                                         redist_vcpu->vcpu_id);
+}
+
+static bool handle_mmio_clear_active_reg_redist(struct kvm_vcpu *vcpu,
+                                               struct kvm_exit_mmio *mmio,
+                                               phys_addr_t offset)
+{
+       struct kvm_vcpu *redist_vcpu = mmio->private;
+
+       return vgic_handle_clear_active_reg(vcpu->kvm, mmio, offset,
+                                            redist_vcpu->vcpu_id);
+}
+
 static bool handle_mmio_set_pending_reg_redist(struct kvm_vcpu *vcpu,
                                               struct kvm_exit_mmio *mmio,
                                               phys_addr_t offset)
@@ -674,13 +720,13 @@ static const struct vgic_io_range vgic_redist_ranges[] = {
                .base           = SGI_base(GICR_ISACTIVER0),
                .len            = 0x04,
                .bits_per_irq   = 1,
-               .handle_mmio    = handle_mmio_raz_wi,
+               .handle_mmio    = handle_mmio_set_active_reg_redist,
        },
        {
                .base           = SGI_base(GICR_ICACTIVER0),
                .len            = 0x04,
                .bits_per_irq   = 1,
-               .handle_mmio    = handle_mmio_raz_wi,
+               .handle_mmio    = handle_mmio_clear_active_reg_redist,
        },
        {
                .base           = SGI_base(GICR_IPRIORITYR0),