Hi Marc, On 6/11/19 7:03 PM, Marc Zyngier wrote: > The LPI translation cache needs to be discarded when an ITS command > may affect the translation of an LPI (DISCARD and MAPD with V=0) or > the routing of an LPI to a redistributor with disabled LPIs (MOVI, > MOVALL). > > We decide to perform a full invalidation of the cache, irrespective > of the LPI that is affected. Commands are supposed to be rare enough > that it doesn't matter. > > Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx> > --- > virt/kvm/arm/vgic/vgic-its.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c > index 9b6b66204b97..5254bb762e1b 100644 > --- a/virt/kvm/arm/vgic/vgic-its.c > +++ b/virt/kvm/arm/vgic/vgic-its.c > @@ -733,6 +733,8 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its, > * don't bother here since we clear the ITTE anyway and the > * pending state is a property of the ITTE struct. > */ > + vgic_its_invalidate_cache(kvm); > + > its_free_ite(kvm, ite); > return 0; > } > @@ -768,6 +770,8 @@ static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its, > ite->collection = collection; > vcpu = kvm_get_vcpu(kvm, collection->target_addr); > > + vgic_its_invalidate_cache(kvm); > + > return update_affinity(ite->irq, vcpu); > } > > @@ -996,6 +1000,8 @@ static void vgic_its_free_device(struct kvm *kvm, struct its_device *device) > list_for_each_entry_safe(ite, temp, &device->itt_head, ite_list) > its_free_ite(kvm, ite); > > + vgic_its_invalidate_cache(kvm); > + > list_del(&device->dev_list); > kfree(device); > } > @@ -1249,6 +1255,8 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its, > vgic_put_irq(kvm, irq); > } > > + vgic_its_invalidate_cache(kvm); All the commands are executed with the its_lock held. Now we don't take it anymore on the fast cache injection path. Don't we have a window where the move has been applied at table level and the cache is not yet invalidated? Same question for vgic_its_free_device(). Thanks Eric > + > kfree(intids); > return 0; > } >