Skip to content

Commit c09c8ab

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: vgic-its: Scope translation cache invalidations to an ITS
As the current LPI translation cache is global, the corresponding invalidation helpers are also globally-scoped. In anticipation of constructing a translation cache per ITS, add a helper for scoped cache invalidations. We still need to support global invalidations when LPIs are toggled on a redistributor, as a property of the translation cache is that all stored LPIs are known to be delieverable. Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20240422200158.2606761-8-oliver.upton@linux.dev Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 30a0ce9 commit c09c8ab

3 files changed

Lines changed: 36 additions & 14 deletions

File tree

arch/arm64/kvm/vgic/vgic-its.c

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "vgic.h"
2424
#include "vgic-mmio.h"
2525

26+
static struct kvm_device_ops kvm_arm_vgic_its_ops;
27+
2628
static int vgic_its_save_tables_v0(struct vgic_its *its);
2729
static int vgic_its_restore_tables_v0(struct vgic_its *its);
2830
static int vgic_its_commit_v0(struct vgic_its *its);
@@ -616,8 +618,9 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
616618
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
617619
}
618620

619-
void vgic_its_invalidate_cache(struct kvm *kvm)
621+
static void vgic_its_invalidate_cache(struct vgic_its *its)
620622
{
623+
struct kvm *kvm = its->dev->kvm;
621624
struct vgic_dist *dist = &kvm->arch.vgic;
622625
struct vgic_translation_cache_entry *cte;
623626
unsigned long flags;
@@ -639,6 +642,24 @@ void vgic_its_invalidate_cache(struct kvm *kvm)
639642
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
640643
}
641644

645+
void vgic_its_invalidate_all_caches(struct kvm *kvm)
646+
{
647+
struct kvm_device *dev;
648+
struct vgic_its *its;
649+
650+
rcu_read_lock();
651+
652+
list_for_each_entry_rcu(dev, &kvm->devices, vm_node) {
653+
if (dev->ops != &kvm_arm_vgic_its_ops)
654+
continue;
655+
656+
its = dev->private;
657+
vgic_its_invalidate_cache(its);
658+
}
659+
660+
rcu_read_unlock();
661+
}
662+
642663
int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
643664
u32 devid, u32 eventid, struct vgic_irq **irq)
644665
{
@@ -826,7 +847,7 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
826847
* don't bother here since we clear the ITTE anyway and the
827848
* pending state is a property of the ITTE struct.
828849
*/
829-
vgic_its_invalidate_cache(kvm);
850+
vgic_its_invalidate_cache(its);
830851

831852
its_free_ite(kvm, ite);
832853
return 0;
@@ -863,7 +884,7 @@ static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its,
863884
ite->collection = collection;
864885
vcpu = collection_to_vcpu(kvm, collection);
865886

866-
vgic_its_invalidate_cache(kvm);
887+
vgic_its_invalidate_cache(its);
867888

868889
return update_affinity(ite->irq, vcpu);
869890
}
@@ -1110,7 +1131,8 @@ static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its,
11101131
}
11111132

11121133
/* Requires the its_lock to be held. */
1113-
static void vgic_its_free_device(struct kvm *kvm, struct its_device *device)
1134+
static void vgic_its_free_device(struct kvm *kvm, struct vgic_its *its,
1135+
struct its_device *device)
11141136
{
11151137
struct its_ite *ite, *temp;
11161138

@@ -1122,7 +1144,7 @@ static void vgic_its_free_device(struct kvm *kvm, struct its_device *device)
11221144
list_for_each_entry_safe(ite, temp, &device->itt_head, ite_list)
11231145
its_free_ite(kvm, ite);
11241146

1125-
vgic_its_invalidate_cache(kvm);
1147+
vgic_its_invalidate_cache(its);
11261148

11271149
list_del(&device->dev_list);
11281150
kfree(device);
@@ -1134,7 +1156,7 @@ static void vgic_its_free_device_list(struct kvm *kvm, struct vgic_its *its)
11341156
struct its_device *cur, *temp;
11351157

11361158
list_for_each_entry_safe(cur, temp, &its->device_list, dev_list)
1137-
vgic_its_free_device(kvm, cur);
1159+
vgic_its_free_device(kvm, its, cur);
11381160
}
11391161

11401162
/* its lock must be held */
@@ -1193,7 +1215,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
11931215
* by removing the mapping and re-establishing it.
11941216
*/
11951217
if (device)
1196-
vgic_its_free_device(kvm, device);
1218+
vgic_its_free_device(kvm, its, device);
11971219

11981220
/*
11991221
* The spec does not say whether unmapping a not-mapped device
@@ -1224,7 +1246,7 @@ static int vgic_its_cmd_handle_mapc(struct kvm *kvm, struct vgic_its *its,
12241246

12251247
if (!valid) {
12261248
vgic_its_free_collection(its, coll_id);
1227-
vgic_its_invalidate_cache(kvm);
1249+
vgic_its_invalidate_cache(its);
12281250
} else {
12291251
struct kvm_vcpu *vcpu;
12301252

@@ -1395,7 +1417,7 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
13951417
vgic_put_irq(kvm, irq);
13961418
}
13971419

1398-
vgic_its_invalidate_cache(kvm);
1420+
vgic_its_invalidate_cache(its);
13991421

14001422
return 0;
14011423
}
@@ -1747,7 +1769,7 @@ static void vgic_mmio_write_its_ctlr(struct kvm *kvm, struct vgic_its *its,
17471769

17481770
its->enabled = !!(val & GITS_CTLR_ENABLE);
17491771
if (!its->enabled)
1750-
vgic_its_invalidate_cache(kvm);
1772+
vgic_its_invalidate_cache(its);
17511773

17521774
/*
17531775
* Try to process any pending commands. This function bails out early
@@ -1880,7 +1902,7 @@ void vgic_lpi_translation_cache_destroy(struct kvm *kvm)
18801902
struct vgic_dist *dist = &kvm->arch.vgic;
18811903
struct vgic_translation_cache_entry *cte, *tmp;
18821904

1883-
vgic_its_invalidate_cache(kvm);
1905+
vgic_its_invalidate_all_caches(kvm);
18841906

18851907
list_for_each_entry_safe(cte, tmp,
18861908
&dist->lpi_translation_cache, entry) {
@@ -2372,7 +2394,7 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id,
23722394

23732395
ret = vgic_its_restore_itt(its, dev);
23742396
if (ret) {
2375-
vgic_its_free_device(its->dev->kvm, dev);
2397+
vgic_its_free_device(its->dev->kvm, its, dev);
23762398
return ret;
23772399
}
23782400

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu,
277277
return;
278278

279279
vgic_flush_pending_lpis(vcpu);
280-
vgic_its_invalidate_cache(vcpu->kvm);
280+
vgic_its_invalidate_all_caches(vcpu->kvm);
281281
atomic_set_release(&vgic_cpu->ctlr, 0);
282282
} else {
283283
ctlr = atomic_cmpxchg_acquire(&vgic_cpu->ctlr, 0,

arch/arm64/kvm/vgic/vgic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi);
337337
int vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi);
338338
void vgic_lpi_translation_cache_init(struct kvm *kvm);
339339
void vgic_lpi_translation_cache_destroy(struct kvm *kvm);
340-
void vgic_its_invalidate_cache(struct kvm *kvm);
340+
void vgic_its_invalidate_all_caches(struct kvm *kvm);
341341

342342
/* GICv4.1 MMIO interface */
343343
int vgic_its_inv_lpi(struct kvm *kvm, struct vgic_irq *irq);

0 commit comments

Comments
 (0)