mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
VT-d: split domid map cleanup check into a function
This logic will want invoking from elsewhere.
No functional change intended.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
master commit: 9fdc10abe9
master date: 2021-11-24 11:06:20 +0100
This commit is contained in:
1 parent
d0d0af67ee
commit
fa45f6b556
1 file changed
+48
-43
@@ -157,6 +157,51 @@ static void cleanup_domid_map(struct domain *domain, struct vtd_iommu *iommu)
|
||||
}
|
||||
}
|
||||
|
||||
static bool any_pdev_behind_iommu(const struct domain *d,
|
||||
const struct pci_dev *exclude,
|
||||
const struct vtd_iommu *iommu)
|
||||
{
|
||||
const struct pci_dev *pdev;
|
||||
|
||||
for_each_pdev ( d, pdev )
|
||||
{
|
||||
const struct acpi_drhd_unit *drhd;
|
||||
|
||||
if ( pdev == exclude )
|
||||
continue;
|
||||
|
||||
drhd = acpi_find_matched_drhd_unit(pdev);
|
||||
if ( drhd && drhd->iommu == iommu )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no other devices under the same iommu owned by this domain,
|
||||
* clear iommu in iommu_bitmap and clear domain_id in domid_bitmap.
|
||||
*/
|
||||
static void check_cleanup_domid_map(struct domain *d,
|
||||
const struct pci_dev *exclude,
|
||||
struct vtd_iommu *iommu)
|
||||
{
|
||||
bool found = any_pdev_behind_iommu(d, exclude, iommu);
|
||||
|
||||
/*
|
||||
* Hidden devices are associated with DomXEN but usable by the hardware
|
||||
* domain. Hence they need considering here as well.
|
||||
*/
|
||||
if ( !found && is_hardware_domain(d) )
|
||||
found = any_pdev_behind_iommu(dom_xen, exclude, iommu);
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
clear_bit(iommu->index, &dom_iommu(d)->arch.vtd.iommu_bitmap);
|
||||
cleanup_domid_map(d, iommu);
|
||||
}
|
||||
}
|
||||
|
||||
static void sync_cache(const void *addr, unsigned int size)
|
||||
{
|
||||
static unsigned long clflush_size = 0;
|
||||
@@ -1674,27 +1719,6 @@ int domain_context_unmap_one(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool any_pdev_behind_iommu(const struct domain *d,
|
||||
const struct pci_dev *exclude,
|
||||
const struct vtd_iommu *iommu)
|
||||
{
|
||||
const struct pci_dev *pdev;
|
||||
|
||||
for_each_pdev ( d, pdev )
|
||||
{
|
||||
const struct acpi_drhd_unit *drhd;
|
||||
|
||||
if ( pdev == exclude )
|
||||
continue;
|
||||
|
||||
drhd = acpi_find_matched_drhd_unit(pdev);
|
||||
if ( drhd && drhd->iommu == iommu )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int domain_context_unmap(struct domain *domain, u8 devfn,
|
||||
struct pci_dev *pdev)
|
||||
{
|
||||
@@ -1703,7 +1727,6 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
|
||||
int ret;
|
||||
uint16_t seg = pdev->seg;
|
||||
uint8_t bus = pdev->bus, tmp_bus, tmp_devfn, secbus;
|
||||
bool found;
|
||||
|
||||
switch ( pdev->type )
|
||||
{
|
||||
@@ -1779,28 +1802,10 @@ static int domain_context_unmap(struct domain *domain, u8 devfn,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( ret || QUARANTINE_SKIP(domain) || pdev->devfn != devfn )
|
||||
return ret;
|
||||
if ( !ret && !QUARANTINE_SKIP(domain) && pdev->devfn == devfn )
|
||||
check_cleanup_domid_map(domain, pdev, iommu);
|
||||
|
||||
/*
|
||||
* If no other devices under the same iommu owned by this domain,
|
||||
* clear iommu in iommu_bitmap and clear domain_id in domid_bitmap.
|
||||
*/
|
||||
found = any_pdev_behind_iommu(domain, pdev, iommu);
|
||||
/*
|
||||
* Hidden devices are associated with DomXEN but usable by the hardware
|
||||
* domain. Hence they need considering here as well.
|
||||
*/
|
||||
if ( !found && is_hardware_domain(domain) )
|
||||
found = any_pdev_behind_iommu(dom_xen, pdev, iommu);
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
clear_bit(iommu->index, dom_iommu(domain)->arch.vtd.iommu_bitmap);
|
||||
cleanup_domid_map(domain, iommu);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iommu_clear_root_pgtable(struct domain *d)
|
||||
|
||||