}
}
-static int __hwdom_init amd_iommu_setup_hwdom_device(
- u8 devfn, struct pci_dev *pdev)
-{
- int bdf = PCI_BDF2(pdev->bus, pdev->devfn);
- struct amd_iommu *iommu = find_iommu_for_device(pdev->seg, bdf);
-
- if ( unlikely(!iommu) )
- {
- /* Filter the bridge devices */
- if ( pdev->type == DEV_TYPE_PCI_HOST_BRIDGE )
- {
- AMD_IOMMU_DEBUG("Skipping host bridge %04x:%02x:%02x.%u\n",
- pdev->seg, PCI_BUS(bdf), PCI_SLOT(bdf),
- PCI_FUNC(bdf));
- return 0;
- }
-
- AMD_IOMMU_DEBUG("No iommu for device %04x:%02x:%02x.%u\n",
- pdev->seg, pdev->bus,
- PCI_SLOT(devfn), PCI_FUNC(devfn));
- return -ENODEV;
- }
-
- amd_iommu_setup_domain_device(pdev->domain, iommu, devfn, pdev);
- return 0;
-}
-
int __init amd_iov_detect(void)
{
INIT_LIST_HEAD(&amd_iommu_head);
return 0;
}
+static int amd_iommu_add_device(u8 devfn, struct pci_dev *pdev);
+
static void __hwdom_init amd_iommu_hwdom_init(struct domain *d)
{
unsigned long i;
IOMMU_MMIO_REGION_LENGTH - 1)) )
BUG();
- setup_hwdom_pci_devices(d, amd_iommu_setup_hwdom_device);
+ setup_hwdom_pci_devices(d, amd_iommu_add_device);
}
void amd_iommu_disable_domain_device(struct domain *domain,
{
struct amd_iommu *iommu;
u16 bdf;
+
if ( !pdev->domain )
return -EINVAL;
bdf = PCI_BDF2(pdev->bus, pdev->devfn);
iommu = find_iommu_for_device(pdev->seg, bdf);
- if ( !iommu )
+ if ( unlikely(!iommu) )
{
- AMD_IOMMU_DEBUG("Fail to find iommu."
- " %04x:%02x:%02x.%u cannot be assigned to dom%d\n",
+ /* Filter bridge devices. */
+ if ( pdev->type == DEV_TYPE_PCI_HOST_BRIDGE &&
+ is_hardware_domain(pdev->domain) )
+ {
+ AMD_IOMMU_DEBUG("Skipping host bridge %04x:%02x:%02x.%u\n",
+ pdev->seg, pdev->bus, PCI_SLOT(devfn),
+ PCI_FUNC(devfn));
+ return 0;
+ }
+
+ AMD_IOMMU_DEBUG("No iommu for %04x:%02x:%02x.%u; cannot be handed to d%d\n",
pdev->seg, pdev->bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
pdev->domain->domain_id);
return -ENODEV;