Commit e9649129 authored by Kunkun Jiang's avatar Kunkun Jiang Committed by Oliver Upton
Browse files

KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device



vgic_its_save_device_tables will traverse its->device_list to
save DTE for each device. vgic_its_restore_device_tables will
traverse each entry of device table and check if it is valid.
Restore if valid.

But when MAPD unmaps a device, it does not invalidate the
corresponding DTE. In the scenario of continuous saves
and restores, there may be a situation where a device's DTE
is not saved but is restored. This is unreasonable and may
cause restore to fail. This patch clears the corresponding
DTE when MAPD unmaps a device.

Cc: stable@vger.kernel.org
Fixes: 57a9a117 ("KVM: arm64: vgic-its: Device table save/restore")
Co-developed-by: default avatarShusen Li <lishusen2@huawei.com>
Signed-off-by: default avatarShusen Li <lishusen2@huawei.com>
Signed-off-by: default avatarKunkun Jiang <jiangkunkun@huawei.com>
[Jing: Update with entry write helper]
Signed-off-by: default avatarJing Zhang <jingzhangos@google.com>
Link: https://lore.kernel.org/r/20241107214137.428439-5-jingzhangos@google.com


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 7fe28d7e
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1139,9 +1139,11 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
	bool valid = its_cmd_get_validbit(its_cmd);
	u8 num_eventid_bits = its_cmd_get_size(its_cmd);
	gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd);
	int dte_esz = vgic_its_get_abi(its)->dte_esz;
	struct its_device *device;
	gpa_t gpa;

	if (!vgic_its_check_id(its, its->baser_device_table, device_id, NULL))
	if (!vgic_its_check_id(its, its->baser_device_table, device_id, &gpa))
		return E_ITS_MAPD_DEVICE_OOR;

	if (valid && num_eventid_bits > VITS_TYPER_IDBITS)
@@ -1162,7 +1164,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
	 * is an error, so we are done in any case.
	 */
	if (!valid)
		return 0;
		return vgic_its_write_entry_lock(its, gpa, 0, dte_esz);

	device = vgic_its_alloc_device(its, device_id, itt_addr,
				       num_eventid_bits);