diff options
author | Eric Auger <eric.auger@redhat.com> | 2017-10-26 11:23:09 -0400 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2017-11-06 10:23:18 -0500 |
commit | 36d6961c2b481614e8d37495896436d9322df052 (patch) | |
tree | 61c3425dd03217fc6887bd6fb8a2f0684ab98c69 | |
parent | 2f609a03391f24ac31f12f27790194ac49dff832 (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.c | 22 |
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 | ||
1468 | static unsigned long vgic_mmio_read_its_ctlr(struct kvm *vcpu, | 1482 | static unsigned long vgic_mmio_read_its_ctlr(struct kvm *vcpu, |