Re: [PATCH v2 1/5] KVM: arm64: vgic-v3: Undo assignment on iodev registration failure

[email protected]
Newsgroups org.kernel.vger.kvm,dev.linux.lists.kvmarm
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Incomplete rollback in `vgic_register_all_redist_iodevs` fails to clear `base_addr`, permanently breaking rolled-back vCPUs on retry.
--

--- Patch [1]: [PATCH v2 1/5] KVM: arm64: vgic-v3: Undo assignment on iodev registration failure ---
commit 1ddcb102c04536e66942920259e184122195f9ff
Author: Karl Mehltretter <[email protected]>

KVM: arm64: vgic-v3: Undo assignment on iodev registration failure

This commit introduces vgic_unassign_redist_iodev() to clear rdreg and base_addr
when kvm_io_bus_register_dev() fails during redistributor iodev registration.
This prevents reusing a slot that remains assigned to a vCPU and fixes the
state leak for the current failing vCPU.

> diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> index 5913a20d83019..c75caadbd1d3c 100644
> --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> @@ -766,6 +766,18 @@ unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev)
[ ... ]
> @@ -818,16 +830,17 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
[ ... ]
>  	ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, rd_base,
>  				      2 * SZ_64K, &rd_dev->dev);
>  	if (ret)
> -		return ret;
> +		vgic_unassign_redist_iodev(vcpu);

[Severity: High]
This is a pre-existing issue, but does the rollback loop in
vgic_register_all_redist_iodevs() also need to use this new unassign helper?

If vgic_register_redist_iodev() fails, the rollback loop in
vgic_register_all_redist_iodevs() handles previously processed vCPUs by calling
vgic_unregister_redist_iodev():

arch/arm64/kvm/vgic/vgic-mmio-v3.c:vgic_register_all_redist_iodevs() {
    ...
	if (ret) {
		/* The current c failed, so iterate over the previous ones. */
		int i;

		for (i = 0; i < c; i++) {
			vcpu = kvm_get_vcpu(kvm, i);
			vgic_unregister_redist_iodev(vcpu);
		}
	}
    ...
}

Because vgic_unregister_redist_iodev() only unregisters the bus device, it
does not clear base_addr or reset rdreg. These rolled-back vCPUs remain
assigned but are removed from the MMIO bus.

If userspace retries the ioctl, vgic_register_redist_iodev() will see that
base_addr is no longer VGIC_ADDR_UNDEF and skip registration.

Will this leave the guest permanently missing MMIO mappings for those
earlier vCPUs, breaking guest execution?

>  
> -	/* Protected by slots_lock */
> -	rdreg->free_index++;
> -	return 0;
> +	return ret;
>  
>  out_unlock:
>  	mutex_unlock(&kvm->arch.config_lock);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.