On Fri, 2014-03-21 at 17:19 +0000, David Woodhouse wrote:
> Signed-off-by: David Woodhouse <[email protected]>
> ---
>  drivers/iommu/intel-iommu.c | 75 
> ++++++++++++++++++++++-----------------------
>  1 file changed, 36 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 741fb1d..05c5214 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -2207,52 +2207,51 @@ static struct dmar_domain 
> *dmar_insert_dev_info(struct intel_iommu *iommu,
>  }
>  
>  /* domain is initialized */
> -static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
> +static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
>  {
>       struct dmar_domain *domain, *free = NULL;
>       struct intel_iommu *iommu = NULL;
>       struct device_domain_info *info;
> -     struct dmar_drhd_unit *drhd;
> -     struct pci_dev *dev_tmp;
> +     struct pci_dev *dev_tmp = NULL;
>       unsigned long flags;
> -     int bus = 0, devfn = 0;
> -     int segment;
> +     u8 bus, devfn, bridge_bus, bridge_devfn;
>  
> -     domain = find_domain(&pdev->dev);
> +     domain = find_domain(dev);
>       if (domain)
>               return domain;
>  
> -     segment = pci_domain_nr(pdev->bus);
> +     if (dev_is_pci(dev)) {
> +             struct pci_dev *pdev = to_pci_dev(dev);
> +             u16 segment;
>  
> -     dev_tmp = pci_find_upstream_pcie_bridge(pdev);
> -     if (dev_tmp) {
> -             if (pci_is_pcie(dev_tmp)) {
> -                     bus = dev_tmp->subordinate->number;
> -                     devfn = 0;
> -             } else {
> -                     bus = dev_tmp->bus->number;
> -                     devfn = dev_tmp->devfn;
> -             }
> -             spin_lock_irqsave(&device_domain_lock, flags);
> -             info = dmar_search_domain_by_dev_info(segment, bus, devfn);
> -             if (info) {
> -                     iommu = info->iommu;
> -                     domain = info->domain;
> +             segment = pci_domain_nr(pdev->bus);
> +             dev_tmp = pci_find_upstream_pcie_bridge(pdev);
> +             if (dev_tmp) {
> +                     if (pci_is_pcie(dev_tmp)) {
> +                             bridge_bus = dev_tmp->subordinate->number;
> +                             bridge_devfn = 0;
> +                     } else {
> +                             bridge_bus = dev_tmp->bus->number;
> +                             bridge_devfn = dev_tmp->devfn;
> +                     }
> +                     spin_lock_irqsave(&device_domain_lock, flags);
> +                     info = dmar_search_domain_by_dev_info(segment, bus, 
> devfn);


bus and devfn are uninitialized here, CID 1197747 & 1197746.  Thanks,

Alex


> +                     if (info) {
> +                             iommu = info->iommu;
> +                             domain = info->domain;
> +                     }
> +                     spin_unlock_irqrestore(&device_domain_lock, flags);
> +                     /* pcie-pci bridge already has a domain, uses it */
> +                     if (info)
> +                             goto found_domain;
>               }
> -             spin_unlock_irqrestore(&device_domain_lock, flags);
> -             if (info)
> -                     goto found_domain;
>       }
>  
> -     drhd = dmar_find_matched_drhd_unit(pdev);
> -     if (!drhd) {
> -             printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
> -                     pci_name(pdev));
> -             return NULL;
> -     }
> -     iommu = drhd->iommu;
> +     iommu = device_to_iommu(dev, &bus, &devfn);
> +     if (!iommu)
> +             goto error;
>  
> -     /* Allocate and intialize new domain for the device */
> +     /* Allocate and initialize new domain for the device */
>       domain = alloc_domain(false);
>       if (!domain)
>               goto error;
> @@ -2266,15 +2265,14 @@ static struct dmar_domain *get_domain_for_dev(struct 
> pci_dev *pdev, int gaw)
>  
>       /* register pcie-to-pci device */
>       if (dev_tmp) {
> -             domain = dmar_insert_dev_info(iommu, bus, devfn, NULL,
> -                                           domain);
> +             domain = dmar_insert_dev_info(iommu, bridge_bus, bridge_devfn,
> +                                           NULL, domain);
>               if (!domain)
>                       goto error;
>       }
>  
>  found_domain:
> -     domain = dmar_insert_dev_info(iommu, pdev->bus->number,
> -                                   pdev->devfn, &pdev->dev, domain);
> +     domain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
>  error:
>       if (free != domain)
>               domain_exit(free);
> @@ -2320,7 +2318,7 @@ static int iommu_prepare_identity_map(struct pci_dev 
> *pdev,
>       struct dmar_domain *domain;
>       int ret;
>  
> -     domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
> +     domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
>       if (!domain)
>               return -ENOMEM;
>  
> @@ -2864,8 +2862,7 @@ static struct dmar_domain 
> *__get_valid_domain_for_dev(struct pci_dev *pdev)
>       struct dmar_domain *domain;
>       int ret;
>  
> -     domain = get_domain_for_dev(pdev,
> -                     DEFAULT_DOMAIN_ADDRESS_WIDTH);
> +     domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
>       if (!domain) {
>               printk(KERN_ERR
>                       "Allocating domain for %s failed", pci_name(pdev));



_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to