Skip to content

Commit 36d6961

Browse files
eaugerchazy
authored andcommitted
KVM: arm/arm64: vgic-its: Free caches when GITS_BASER Valid bit is cleared
When the GITS_BASER<n>.Valid gets cleared, the data structures in guest RAM are not valid anymore. The device, collection and LPI lists stored in the in-kernel ITS represent the same information in some form of cache. So let's void the cache. Reviewed-by: Marc Zyngier <[email protected]> Reviewed-by: Christoffer Dall <[email protected]> Signed-off-by: Eric Auger <[email protected]> Signed-off-by: Christoffer Dall <[email protected]>
1 parent 2f609a0 commit 36d6961

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

virt/kvm/arm/vgic/vgic-its.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
14311431
unsigned long val)
14321432
{
14331433
const struct vgic_its_abi *abi = vgic_its_get_abi(its);
1434-
u64 entry_size, device_type;
1434+
u64 entry_size, table_type;
14351435
u64 reg, *regptr, clearbits = 0;
14361436

14371437
/* When GITS_CTLR.Enable is 1, we ignore write accesses. */
@@ -1442,12 +1442,12 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
14421442
case 0:
14431443
regptr = &its->baser_device_table;
14441444
entry_size = abi->dte_esz;
1445-
device_type = GITS_BASER_TYPE_DEVICE;
1445+
table_type = GITS_BASER_TYPE_DEVICE;
14461446
break;
14471447
case 1:
14481448
regptr = &its->baser_coll_table;
14491449
entry_size = abi->cte_esz;
1450-
device_type = GITS_BASER_TYPE_COLLECTION;
1450+
table_type = GITS_BASER_TYPE_COLLECTION;
14511451
clearbits = GITS_BASER_INDIRECT;
14521452
break;
14531453
default:
@@ -1459,10 +1459,24 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
14591459
reg &= ~clearbits;
14601460

14611461
reg |= (entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT;
1462-
reg |= device_type << GITS_BASER_TYPE_SHIFT;
1462+
reg |= table_type << GITS_BASER_TYPE_SHIFT;
14631463
reg = vgic_sanitise_its_baser(reg);
14641464

14651465
*regptr = reg;
1466+
1467+
if (!(reg & GITS_BASER_VALID)) {
1468+
/* Take the its_lock to prevent a race with a save/restore */
1469+
mutex_lock(&its->its_lock);
1470+
switch (table_type) {
1471+
case GITS_BASER_TYPE_DEVICE:
1472+
vgic_its_free_device_list(kvm, its);
1473+
break;
1474+
case GITS_BASER_TYPE_COLLECTION:
1475+
vgic_its_free_collection_list(kvm, its);
1476+
break;
1477+
}
1478+
mutex_unlock(&its->its_lock);
1479+
}
14661480
}
14671481

14681482
static unsigned long vgic_mmio_read_its_ctlr(struct kvm *vcpu,

0 commit comments

Comments
 (0)