aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/amd_iommu.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index ef9b309e8e09..2f7c0b3a448b 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1683,4 +1683,39 @@ static void amd_iommu_detach_device(struct iommu_domain *dom,
1683 iommu_completion_wait(iommu); 1683 iommu_completion_wait(iommu);
1684} 1684}
1685 1685
1686static int amd_iommu_attach_device(struct iommu_domain *dom,
1687 struct device *dev)
1688{
1689 struct protection_domain *domain = dom->priv;
1690 struct protection_domain *old_domain;
1691 struct amd_iommu *iommu;
1692 struct pci_dev *pdev;
1693 u16 devid;
1694
1695 if (dev->bus != &pci_bus_type)
1696 return -EINVAL;
1697
1698 pdev = to_pci_dev(dev);
1699
1700 devid = calc_devid(pdev->bus->number, pdev->devfn);
1701
1702 if (devid >= amd_iommu_last_bdf ||
1703 devid != amd_iommu_alias_table[devid])
1704 return -EINVAL;
1705
1706 iommu = amd_iommu_rlookup_table[devid];
1707 if (!iommu)
1708 return -EINVAL;
1709
1710 old_domain = domain_for_device(devid);
1711 if (old_domain)
1712 return -EBUSY;
1713
1714 attach_device(iommu, domain, devid);
1715
1716 iommu_completion_wait(iommu);
1717
1718 return 0;
1719}
1720
1686#endif 1721#endif