From: Jan Beulich Date: Fri, 18 Feb 2022 13:19:42 +0000 (+0100) Subject: IOMMU/PCI: propagate get_device_group_id() failure X-Git-Tag: archive/raspbian/4.17.0-1+rpi1^2~33^2~1014 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=8518f96f13fb0ac2dd9791014bfb0d1b01f34e4c;p=xen.git IOMMU/PCI: propagate get_device_group_id() failure The VT-d hook can indicate an error, which shouldn't be ignored. Convert the hook's return value to a proper error code, and let that bubble up. Signed-off-by: Jan Beulich Reviewed-by: Paul Durrant Reviewed-by: Kevin Tian --- diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index e8b09d77d8..70b6684981 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1532,6 +1532,8 @@ static int iommu_get_device_group( return 0; group_id = iommu_call(ops, get_device_group_id, seg, bus, devfn); + if ( group_id < 0 ) + return group_id; pcidevs_lock(); for_each_pdev( d, pdev ) @@ -1546,6 +1548,12 @@ static int iommu_get_device_group( continue; sdev_id = iommu_call(ops, get_device_group_id, seg, b, df); + if ( sdev_id < 0 ) + { + pcidevs_unlock(); + return sdev_id; + } + if ( (sdev_id == group_id) && (i < max_sdevs) ) { bdf = (b << 16) | (df << 8); @@ -1553,7 +1561,7 @@ static int iommu_get_device_group( if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) ) { pcidevs_unlock(); - return -1; + return -EFAULT; } i++; } @@ -1621,8 +1629,7 @@ int iommu_do_pci_domctl( ret = iommu_get_device_group(d, seg, bus, devfn, sdevs, max_sdevs); if ( ret < 0 ) { - dprintk(XENLOG_ERR, "iommu_get_device_group() failed!\n"); - ret = -EFAULT; + dprintk(XENLOG_ERR, "iommu_get_device_group() failed: %d\n", ret); domctl->u.get_device_group.num_sdevs = 0; } else diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c index 566b0e2a7e..0fc818fd27 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -2564,10 +2564,11 @@ static int intel_iommu_assign_device( static int intel_iommu_group_id(u16 seg, u8 bus, u8 devfn) { u8 secbus; + if ( find_upstream_bridge(seg, &bus, &devfn, &secbus) < 0 ) - return -1; - else - return PCI_BDF2(bus, devfn); + return -ENODEV; + + return PCI_BDF2(bus, devfn); } static int __must_check vtd_suspend(void)