aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2017-10-26 11:23:09 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2017-11-06 10:23:18 -0500
commit36d6961c2b481614e8d37495896436d9322df052 (patch)
tree61c3425dd03217fc6887bd6fb8a2f0684ab98c69
parent2f609a03391f24ac31f12f27790194ac49dff832 (diff)
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 <marc.zyngier@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--virt/kvm/arm/vgic/vgic-its.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index d46256c07ba5..1732e08a4375 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -1431,7 +1431,7 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
1431 unsigned long val) 1431 unsigned long val)
1432{ 1432{
1433 const struct vgic_its_abi *abi = vgic_its_get_abi(its); 1433 const struct vgic_its_abi *abi = vgic_its_get_abi(its);
1434 u64 entry_size, device_type; 1434 u64 entry_size, table_type;
1435 u64 reg, *regptr, clearbits = 0; 1435 u64 reg, *regptr, clearbits = 0;
1436 1436
1437 /* When GITS_CTLR.Enable is 1, we ignore write accesses. */ 1437 /* When GITS_CTLR.Enable is 1, we ignore write accesses. */
@@ -1442,12 +1442,12 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
1442 case 0: 1442 case 0:
1443 regptr = &its->baser_device_table; 1443 regptr = &its->baser_device_table;
1444 entry_size = abi->dte_esz; 1444 entry_size = abi->dte_esz;
1445 device_type = GITS_BASER_TYPE_DEVICE; 1445 table_type = GITS_BASER_TYPE_DEVICE;
1446 break; 1446 break;
1447 case 1: 1447 case 1:
1448 regptr = &its->baser_coll_table; 1448 regptr = &its->baser_coll_table;
1449 entry_size = abi->cte_esz; 1449 entry_size = abi->cte_esz;
1450 device_type = GITS_BASER_TYPE_COLLECTION; 1450 table_type = GITS_BASER_TYPE_COLLECTION;
1451 clearbits = GITS_BASER_INDIRECT; 1451 clearbits = GITS_BASER_INDIRECT;
1452 break; 1452 break;
1453 default: 1453 default:
@@ -1459,10 +1459,24 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
1459 reg &= ~clearbits; 1459 reg &= ~clearbits;
1460 1460
1461 reg |= (entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT; 1461 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;
1463 reg = vgic_sanitise_its_baser(reg); 1463 reg = vgic_sanitise_its_baser(reg);
1464 1464
1465 *regptr = reg; 1465 *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 }
1466} 1480}
1467 1481
1468static unsigned long vgic_mmio_read_its_ctlr(struct kvm *vcpu, 1482static unsigned long vgic_mmio_read_its_ctlr(struct kvm *vcpu,