diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2014-02-19 01:07:27 -0500 |
---|---|---|
committer | Joerg Roedel <joro@8bytes.org> | 2014-03-04 11:51:01 -0500 |
commit | e85bb5d4d1d5ef55cf4fbb4da5dda67d2bbacc5c (patch) | |
tree | 62c55a6b27f820677c758ace5533bd7cf095db7a /drivers/iommu/intel-iommu.c | |
parent | 745f2586e78efc5c226a60cfc8e7fbd735b1c856 (diff) |
iommu/vt-d: Free resources if failed to create domain for PCIe endpoint
Enhance function get_domain_for_dev() to release allocated resources
if failed to create domain for PCIe endpoint, otherwise the allocated
resources will get lost.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: Joerg Roedel <joro@8bytes.org>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 67b114e784bc..503cc739d4b1 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -2015,7 +2015,7 @@ static int dmar_insert_dev_info(int segment, int bus, int devfn, | |||
2015 | /* domain is initialized */ | 2015 | /* domain is initialized */ |
2016 | static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | 2016 | static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) |
2017 | { | 2017 | { |
2018 | struct dmar_domain *domain; | 2018 | struct dmar_domain *domain, *free = NULL; |
2019 | struct intel_iommu *iommu; | 2019 | struct intel_iommu *iommu; |
2020 | struct dmar_drhd_unit *drhd; | 2020 | struct dmar_drhd_unit *drhd; |
2021 | struct pci_dev *dev_tmp; | 2021 | struct pci_dev *dev_tmp; |
@@ -2062,17 +2062,16 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
2062 | free_domain_mem(domain); | 2062 | free_domain_mem(domain); |
2063 | goto error; | 2063 | goto error; |
2064 | } | 2064 | } |
2065 | if (domain_init(domain, gaw)) { | 2065 | free = domain; |
2066 | domain_exit(domain); | 2066 | if (domain_init(domain, gaw)) |
2067 | goto error; | 2067 | goto error; |
2068 | } | ||
2069 | 2068 | ||
2070 | /* register pcie-to-pci device */ | 2069 | /* register pcie-to-pci device */ |
2071 | if (dev_tmp) { | 2070 | if (dev_tmp) { |
2072 | if (dmar_insert_dev_info(segment, bus, devfn, NULL, &domain)) { | 2071 | if (dmar_insert_dev_info(segment, bus, devfn, NULL, &domain)) |
2073 | domain_exit(domain); | ||
2074 | goto error; | 2072 | goto error; |
2075 | } | 2073 | else |
2074 | free = NULL; | ||
2076 | } | 2075 | } |
2077 | 2076 | ||
2078 | found_domain: | 2077 | found_domain: |
@@ -2080,6 +2079,8 @@ found_domain: | |||
2080 | pdev, &domain) == 0) | 2079 | pdev, &domain) == 0) |
2081 | return domain; | 2080 | return domain; |
2082 | error: | 2081 | error: |
2082 | if (free) | ||
2083 | domain_exit(free); | ||
2083 | /* recheck it here, maybe others set it */ | 2084 | /* recheck it here, maybe others set it */ |
2084 | return find_domain(pdev); | 2085 | return find_domain(pdev); |
2085 | } | 2086 | } |