Commit 0b9d9753 authored by David Woodhouse's avatar David Woodhouse

iommu/vt-d: Handle RMRRs for non-PCI devices

Should hopefully never happen (RMRRs are an abomination) but while we're
busy eliminating all the PCI assumptions, we might as well do it.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 146922ec
...@@ -2311,14 +2311,14 @@ static int iommu_domain_identity_map(struct dmar_domain *domain, ...@@ -2311,14 +2311,14 @@ static int iommu_domain_identity_map(struct dmar_domain *domain,
DMA_PTE_READ|DMA_PTE_WRITE); DMA_PTE_READ|DMA_PTE_WRITE);
} }
static int iommu_prepare_identity_map(struct pci_dev *pdev, static int iommu_prepare_identity_map(struct device *dev,
unsigned long long start, unsigned long long start,
unsigned long long end) unsigned long long end)
{ {
struct dmar_domain *domain; struct dmar_domain *domain;
int ret; int ret;
domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH); domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
if (!domain) if (!domain)
return -ENOMEM; return -ENOMEM;
...@@ -2328,13 +2328,13 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, ...@@ -2328,13 +2328,13 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
up to start with in si_domain */ up to start with in si_domain */
if (domain == si_domain && hw_pass_through) { if (domain == si_domain && hw_pass_through) {
printk("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n", printk("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
pci_name(pdev), start, end); dev_name(dev), start, end);
return 0; return 0;
} }
printk(KERN_INFO printk(KERN_INFO
"IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n", "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
pci_name(pdev), start, end); dev_name(dev), start, end);
if (end < start) { if (end < start) {
WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n" WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
...@@ -2362,7 +2362,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, ...@@ -2362,7 +2362,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
goto error; goto error;
/* context entry init */ /* context entry init */
ret = domain_context_mapping(domain, &pdev->dev, CONTEXT_TT_MULTI_LEVEL); ret = domain_context_mapping(domain, dev, CONTEXT_TT_MULTI_LEVEL);
if (ret) if (ret)
goto error; goto error;
...@@ -2374,11 +2374,11 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev, ...@@ -2374,11 +2374,11 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
} }
static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
struct pci_dev *pdev) struct device *dev)
{ {
if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
return 0; return 0;
return iommu_prepare_identity_map(pdev, rmrr->base_address, return iommu_prepare_identity_map(dev, rmrr->base_address,
rmrr->end_address); rmrr->end_address);
} }
...@@ -2393,7 +2393,7 @@ static inline void iommu_prepare_isa(void) ...@@ -2393,7 +2393,7 @@ static inline void iommu_prepare_isa(void)
return; return;
printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1); ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
if (ret) if (ret)
printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
...@@ -2495,7 +2495,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, ...@@ -2495,7 +2495,7 @@ static int domain_add_dev_info(struct dmar_domain *domain,
return 0; return 0;
} }
static bool device_has_rmrr(struct pci_dev *dev) static bool device_has_rmrr(struct device *dev)
{ {
struct dmar_rmrr_unit *rmrr; struct dmar_rmrr_unit *rmrr;
struct device *tmp; struct device *tmp;
...@@ -2509,7 +2509,7 @@ static bool device_has_rmrr(struct pci_dev *dev) ...@@ -2509,7 +2509,7 @@ static bool device_has_rmrr(struct pci_dev *dev)
*/ */
for_each_active_dev_scope(rmrr->devices, for_each_active_dev_scope(rmrr->devices,
rmrr->devices_cnt, i, tmp) rmrr->devices_cnt, i, tmp)
if (tmp == &dev->dev) { if (tmp == dev) {
rcu_read_unlock(); rcu_read_unlock();
return true; return true;
} }
...@@ -2529,7 +2529,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) ...@@ -2529,7 +2529,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
* from this process due to their usage of RMRRs that are known * from this process due to their usage of RMRRs that are known
* to not be needed after BIOS hand-off to OS. * to not be needed after BIOS hand-off to OS.
*/ */
if (device_has_rmrr(pdev) && if (device_has_rmrr(&pdev->dev) &&
(pdev->class >> 8) != PCI_CLASS_SERIAL_USB) (pdev->class >> 8) != PCI_CLASS_SERIAL_USB)
return 0; return 0;
...@@ -2766,9 +2766,7 @@ static int __init init_dmars(void) ...@@ -2766,9 +2766,7 @@ static int __init init_dmars(void)
/* some BIOS lists non-exist devices in DMAR table. */ /* some BIOS lists non-exist devices in DMAR table. */
for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt, for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
i, dev) { i, dev) {
if (!dev_is_pci(dev)) ret = iommu_prepare_rmrr_dev(rmrr, dev);
continue;
ret = iommu_prepare_rmrr_dev(rmrr, to_pci_dev(dev));
if (ret) if (ret)
printk(KERN_ERR printk(KERN_ERR
"IOMMU: mapping reserved region failed\n"); "IOMMU: mapping reserved region failed\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment