summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2017-10-27 10:28:46 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2017-11-10 03:38:22 -0500
commit6ce18e3a5f3308670b49093b1c350d2834428358 (patch)
treea1ce82edadd6471061e11288ab82729bc1d28f4c /virt
parentaf340f992c56f824eb9b2cab6dce8d46ec31c98c (diff)
KVM: arm/arm64: GICv4: Handle INVALL applied to a vPE
There is no need to perform an INV for each interrupt when updating multiple interrupts. Instead, we can rely on the final VINVALL that gets sent to the ITS to do the work for all of them. Acked-by: Christoffer Dall <cdall@linaro.org> Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/vgic/vgic-its.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 4768a0e21cc5..bf571f6d2b32 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -38,7 +38,7 @@ static int vgic_its_save_tables_v0(struct vgic_its *its);
38static int vgic_its_restore_tables_v0(struct vgic_its *its); 38static int vgic_its_restore_tables_v0(struct vgic_its *its);
39static int vgic_its_commit_v0(struct vgic_its *its); 39static int vgic_its_commit_v0(struct vgic_its *its);
40static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq, 40static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
41 struct kvm_vcpu *filter_vcpu); 41 struct kvm_vcpu *filter_vcpu, bool needs_inv);
42 42
43/* 43/*
44 * Creates a new (reference to a) struct vgic_irq for a given LPI. 44 * Creates a new (reference to a) struct vgic_irq for a given LPI.
@@ -106,7 +106,7 @@ out_unlock:
106 * However we only have those structs for mapped IRQs, so we read in 106 * However we only have those structs for mapped IRQs, so we read in
107 * the respective config data from memory here upon mapping the LPI. 107 * the respective config data from memory here upon mapping the LPI.
108 */ 108 */
109 ret = update_lpi_config(kvm, irq, NULL); 109 ret = update_lpi_config(kvm, irq, NULL, false);
110 if (ret) 110 if (ret)
111 return ERR_PTR(ret); 111 return ERR_PTR(ret);
112 112
@@ -273,7 +273,7 @@ static struct its_collection *find_collection(struct vgic_its *its, int coll_id)
273 * VCPU. Unconditionally applies if filter_vcpu is NULL. 273 * VCPU. Unconditionally applies if filter_vcpu is NULL.
274 */ 274 */
275static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq, 275static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
276 struct kvm_vcpu *filter_vcpu) 276 struct kvm_vcpu *filter_vcpu, bool needs_inv)
277{ 277{
278 u64 propbase = GICR_PROPBASER_ADDRESS(kvm->arch.vgic.propbaser); 278 u64 propbase = GICR_PROPBASER_ADDRESS(kvm->arch.vgic.propbaser);
279 u8 prop; 279 u8 prop;
@@ -298,7 +298,7 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
298 } 298 }
299 299
300 if (irq->hw) 300 if (irq->hw)
301 return its_prop_update_vlpi(irq->host_irq, prop, true); 301 return its_prop_update_vlpi(irq->host_irq, prop, needs_inv);
302 302
303 return 0; 303 return 0;
304} 304}
@@ -1117,7 +1117,7 @@ static int vgic_its_cmd_handle_inv(struct kvm *kvm, struct vgic_its *its,
1117 if (!ite) 1117 if (!ite)
1118 return E_ITS_INV_UNMAPPED_INTERRUPT; 1118 return E_ITS_INV_UNMAPPED_INTERRUPT;
1119 1119
1120 return update_lpi_config(kvm, ite->irq, NULL); 1120 return update_lpi_config(kvm, ite->irq, NULL, true);
1121} 1121}
1122 1122
1123/* 1123/*
@@ -1152,12 +1152,15 @@ static int vgic_its_cmd_handle_invall(struct kvm *kvm, struct vgic_its *its,
1152 irq = vgic_get_irq(kvm, NULL, intids[i]); 1152 irq = vgic_get_irq(kvm, NULL, intids[i]);
1153 if (!irq) 1153 if (!irq)
1154 continue; 1154 continue;
1155 update_lpi_config(kvm, irq, vcpu); 1155 update_lpi_config(kvm, irq, vcpu, false);
1156 vgic_put_irq(kvm, irq); 1156 vgic_put_irq(kvm, irq);
1157 } 1157 }
1158 1158
1159 kfree(intids); 1159 kfree(intids);
1160 1160
1161 if (vcpu->arch.vgic_cpu.vgic_v3.its_vpe.its_vm)
1162 its_invall_vpe(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe);
1163
1161 return 0; 1164 return 0;
1162} 1165}
1163 1166