KVM: arm64: GICv4.1: Reload VLPI configuration on distributor enable/disable
authorMarc Zyngier <maz@kernel.org>
Wed, 4 Mar 2020 20:33:28 +0000 (20:33 +0000)
committerMarc Zyngier <maz@kernel.org>
Tue, 24 Mar 2020 12:15:51 +0000 (12:15 +0000)
Each time a Group-enable bit gets flipped, the state of these bits
needs to be forwarded to the hardware. This is a pretty heavy
handed operation, requiring all vcpus to reload their GICv4
configuration. It is thus implemented as a new request type.

These enable bits are programmed into the HW by setting the VGrp{0,1}En
fields of GICR_VPENDBASER when the vPEs are made resident again.

Of course, we only support Group-1 for now...

Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
Link: https://lore.kernel.org/r/20200304203330.4967-22-maz@kernel.org
arch/arm/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_host.h
virt/kvm/arm/arm.c
virt/kvm/arm/vgic/vgic-mmio-v3.c

index a827b4d60d389f3936a8185c4769f01fe9397226..3da57e863df625d749a9c818d068225c6daae79e 100644 (file)
@@ -39,6 +39,7 @@
 #define KVM_REQ_IRQ_PENDING    KVM_ARCH_REQ(1)
 #define KVM_REQ_VCPU_RESET     KVM_ARCH_REQ(2)
 #define KVM_REQ_RECORD_STEAL   KVM_ARCH_REQ(3)
+#define KVM_REQ_RELOAD_GICv4   KVM_ARCH_REQ(4)
 
 DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 
index 57fd46acd05823ed650a34bf16d7412013f7607c..32c8a675e5a4a33c89a12cdfd69d3d558b92f95f 100644 (file)
@@ -44,6 +44,7 @@
 #define KVM_REQ_IRQ_PENDING    KVM_ARCH_REQ(1)
 #define KVM_REQ_VCPU_RESET     KVM_ARCH_REQ(2)
 #define KVM_REQ_RECORD_STEAL   KVM_ARCH_REQ(3)
+#define KVM_REQ_RELOAD_GICv4   KVM_ARCH_REQ(4)
 
 DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 
index eda7b624eab8c46250789267a2118c50affab453..4d864f857ac8f39657c72ef5a84dc46d516baaef 100644 (file)
@@ -625,6 +625,14 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu)
 
                if (kvm_check_request(KVM_REQ_RECORD_STEAL, vcpu))
                        kvm_update_stolen_time(vcpu);
+
+               if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) {
+                       /* The distributor enable bits were changed */
+                       preempt_disable();
+                       vgic_v4_put(vcpu, false);
+                       vgic_v4_load(vcpu);
+                       preempt_enable();
+               }
        }
 }
 
index 905032a038865f4cda3e01edd6c780470be4b7d1..e72dcc4542475a74fa1f890532d26cd6945fdad5 100644 (file)
@@ -132,7 +132,10 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
                if (is_hwsgi != dist->nassgireq)
                        vgic_v4_configure_vsgis(vcpu->kvm);
 
-               if (!was_enabled && dist->enabled)
+               if (kvm_vgic_global_state.has_gicv4_1 &&
+                   was_enabled != dist->enabled)
+                       kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_RELOAD_GICv4);
+               else if (!was_enabled && dist->enabled)
                        vgic_kick_vcpus(vcpu->kvm);
 
                mutex_unlock(&vcpu->kvm->lock);