@@ -1841,85 +1841,68 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
18411841 return 0 ;
18421842}
18431843
1844+ struct domain_context_mapping_data {
1845+ struct dmar_domain * domain ;
1846+ struct intel_iommu * iommu ;
1847+ int translation ;
1848+ };
1849+
1850+ static int domain_context_mapping_cb (struct pci_dev * pdev ,
1851+ u16 alias , void * opaque )
1852+ {
1853+ struct domain_context_mapping_data * data = opaque ;
1854+
1855+ return domain_context_mapping_one (data -> domain , data -> iommu ,
1856+ PCI_BUS_NUM (alias ), alias & 0xff ,
1857+ data -> translation );
1858+ }
1859+
18441860static int
18451861domain_context_mapping (struct dmar_domain * domain , struct device * dev ,
18461862 int translation )
18471863{
1848- int ret ;
1849- struct pci_dev * pdev , * tmp , * parent ;
18501864 struct intel_iommu * iommu ;
18511865 u8 bus , devfn ;
1866+ struct domain_context_mapping_data data ;
18521867
18531868 iommu = device_to_iommu (dev , & bus , & devfn );
18541869 if (!iommu )
18551870 return - ENODEV ;
18561871
1857- ret = domain_context_mapping_one (domain , iommu , bus , devfn ,
1858- translation );
1859- if (ret || !dev_is_pci (dev ))
1860- return ret ;
1861-
1862- /* dependent device mapping */
1863- pdev = to_pci_dev (dev );
1864- tmp = pci_find_upstream_pcie_bridge (pdev );
1865- if (!tmp )
1866- return 0 ;
1867- /* Secondary interface's bus number and devfn 0 */
1868- parent = pdev -> bus -> self ;
1869- while (parent != tmp ) {
1870- ret = domain_context_mapping_one (domain , iommu ,
1871- parent -> bus -> number ,
1872- parent -> devfn , translation );
1873- if (ret )
1874- return ret ;
1875- parent = parent -> bus -> self ;
1876- }
1877- if (pci_is_pcie (tmp )) /* this is a PCIe-to-PCI bridge */
1878- return domain_context_mapping_one (domain , iommu ,
1879- tmp -> subordinate -> number , 0 ,
1880- translation );
1881- else /* this is a legacy PCI bridge */
1882- return domain_context_mapping_one (domain , iommu ,
1883- tmp -> bus -> number ,
1884- tmp -> devfn ,
1872+ if (!dev_is_pci (dev ))
1873+ return domain_context_mapping_one (domain , iommu , bus , devfn ,
18851874 translation );
1875+
1876+ data .domain = domain ;
1877+ data .iommu = iommu ;
1878+ data .translation = translation ;
1879+
1880+ return pci_for_each_dma_alias (to_pci_dev (dev ),
1881+ & domain_context_mapping_cb , & data );
1882+ }
1883+
1884+ static int domain_context_mapped_cb (struct pci_dev * pdev ,
1885+ u16 alias , void * opaque )
1886+ {
1887+ struct intel_iommu * iommu = opaque ;
1888+
1889+ return !device_context_mapped (iommu , PCI_BUS_NUM (alias ), alias & 0xff );
18861890}
18871891
18881892static int domain_context_mapped (struct device * dev )
18891893{
1890- int ret ;
1891- struct pci_dev * pdev , * tmp , * parent ;
18921894 struct intel_iommu * iommu ;
18931895 u8 bus , devfn ;
18941896
18951897 iommu = device_to_iommu (dev , & bus , & devfn );
18961898 if (!iommu )
18971899 return - ENODEV ;
18981900
1899- ret = device_context_mapped (iommu , bus , devfn );
1900- if (!ret || !dev_is_pci (dev ))
1901- return ret ;
1901+ if (!dev_is_pci (dev ))
1902+ return device_context_mapped (iommu , bus , devfn );
19021903
1903- /* dependent device mapping */
1904- pdev = to_pci_dev (dev );
1905- tmp = pci_find_upstream_pcie_bridge (pdev );
1906- if (!tmp )
1907- return ret ;
1908- /* Secondary interface's bus number and devfn 0 */
1909- parent = pdev -> bus -> self ;
1910- while (parent != tmp ) {
1911- ret = device_context_mapped (iommu , parent -> bus -> number ,
1912- parent -> devfn );
1913- if (!ret )
1914- return ret ;
1915- parent = parent -> bus -> self ;
1916- }
1917- if (pci_is_pcie (tmp ))
1918- return device_context_mapped (iommu , tmp -> subordinate -> number ,
1919- 0 );
1920- else
1921- return device_context_mapped (iommu , tmp -> bus -> number ,
1922- tmp -> devfn );
1904+ return !pci_for_each_dma_alias (to_pci_dev (dev ),
1905+ domain_context_mapped_cb , iommu );
19231906}
19241907
19251908/* Returns a number of VTD pages, but aligned to MM page size */
@@ -2208,79 +2191,86 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
22082191 return domain ;
22092192}
22102193
2194+ static int get_last_alias (struct pci_dev * pdev , u16 alias , void * opaque )
2195+ {
2196+ * (u16 * )opaque = alias ;
2197+ return 0 ;
2198+ }
2199+
22112200/* domain is initialized */
22122201static struct dmar_domain * get_domain_for_dev (struct device * dev , int gaw )
22132202{
2214- struct dmar_domain * domain , * free = NULL ;
2215- struct intel_iommu * iommu = NULL ;
2203+ struct dmar_domain * domain , * tmp ;
2204+ struct intel_iommu * iommu ;
22162205 struct device_domain_info * info ;
2217- struct pci_dev * dev_tmp = NULL ;
2206+ u16 dma_alias ;
22182207 unsigned long flags ;
2219- u8 bus , devfn , bridge_bus , bridge_devfn ;
2208+ u8 bus , devfn ;
22202209
22212210 domain = find_domain (dev );
22222211 if (domain )
22232212 return domain ;
22242213
2214+ iommu = device_to_iommu (dev , & bus , & devfn );
2215+ if (!iommu )
2216+ return NULL ;
2217+
22252218 if (dev_is_pci (dev )) {
22262219 struct pci_dev * pdev = to_pci_dev (dev );
2227- u16 segment ;
22282220
2229- segment = pci_domain_nr (pdev -> bus );
2230- dev_tmp = pci_find_upstream_pcie_bridge (pdev );
2231- if (dev_tmp ) {
2232- if (pci_is_pcie (dev_tmp )) {
2233- bridge_bus = dev_tmp -> subordinate -> number ;
2234- bridge_devfn = 0 ;
2235- } else {
2236- bridge_bus = dev_tmp -> bus -> number ;
2237- bridge_devfn = dev_tmp -> devfn ;
2238- }
2239- spin_lock_irqsave (& device_domain_lock , flags );
2240- info = dmar_search_domain_by_dev_info (segment ,
2241- bridge_bus ,
2242- bridge_devfn );
2243- if (info ) {
2244- iommu = info -> iommu ;
2245- domain = info -> domain ;
2246- }
2247- spin_unlock_irqrestore (& device_domain_lock , flags );
2248- /* pcie-pci bridge already has a domain, uses it */
2249- if (info )
2250- goto found_domain ;
2221+ pci_for_each_dma_alias (pdev , get_last_alias , & dma_alias );
2222+
2223+ spin_lock_irqsave (& device_domain_lock , flags );
2224+ info = dmar_search_domain_by_dev_info (pci_domain_nr (pdev -> bus ),
2225+ PCI_BUS_NUM (dma_alias ),
2226+ dma_alias & 0xff );
2227+ if (info ) {
2228+ iommu = info -> iommu ;
2229+ domain = info -> domain ;
22512230 }
2252- }
2231+ spin_unlock_irqrestore ( & device_domain_lock , flags );
22532232
2254- iommu = device_to_iommu (dev , & bus , & devfn );
2255- if (!iommu )
2256- goto error ;
2233+ /* DMA alias already has a domain, uses it */
2234+ if (info )
2235+ goto found_domain ;
2236+ }
22572237
22582238 /* Allocate and initialize new domain for the device */
22592239 domain = alloc_domain (false);
22602240 if (!domain )
2261- goto error ;
2241+ return NULL ;
2242+
22622243 if (iommu_attach_domain (domain , iommu )) {
22632244 free_domain_mem (domain );
2264- domain = NULL ;
2265- goto error ;
2245+ return NULL ;
22662246 }
2267- free = domain ;
2268- if (domain_init (domain , gaw ))
2269- goto error ;
22702247
2271- /* register pcie-to-pci device */
2272- if (dev_tmp ) {
2273- domain = dmar_insert_dev_info (iommu , bridge_bus , bridge_devfn ,
2274- NULL , domain );
2248+ if (domain_init (domain , gaw )) {
2249+ domain_exit (domain );
2250+ return NULL ;
2251+ }
2252+
2253+ /* register PCI DMA alias device */
2254+ if (dev_is_pci (dev )) {
2255+ tmp = dmar_insert_dev_info (iommu , PCI_BUS_NUM (dma_alias ),
2256+ dma_alias & 0xff , NULL , domain );
2257+
2258+ if (!tmp || tmp != domain ) {
2259+ domain_exit (domain );
2260+ domain = tmp ;
2261+ }
2262+
22752263 if (!domain )
2276- goto error ;
2264+ return NULL ;
22772265 }
22782266
22792267found_domain :
2280- domain = dmar_insert_dev_info (iommu , bus , devfn , dev , domain );
2281- error :
2282- if (free != domain )
2283- domain_exit (free );
2268+ tmp = dmar_insert_dev_info (iommu , bus , devfn , dev , domain );
2269+
2270+ if (!tmp || tmp != domain ) {
2271+ domain_exit (domain );
2272+ domain = tmp ;
2273+ }
22842274
22852275 return domain ;
22862276}
@@ -4043,33 +4033,27 @@ int __init intel_iommu_init(void)
40434033 return ret ;
40444034}
40454035
4036+ static int iommu_detach_dev_cb (struct pci_dev * pdev , u16 alias , void * opaque )
4037+ {
4038+ struct intel_iommu * iommu = opaque ;
4039+
4040+ iommu_detach_dev (iommu , PCI_BUS_NUM (alias ), alias & 0xff );
4041+ return 0 ;
4042+ }
4043+
4044+ /*
4045+ * NB - intel-iommu lacks any sort of reference counting for the users of
4046+ * dependent devices. If multiple endpoints have intersecting dependent
4047+ * devices, unbinding the driver from any one of them will possibly leave
4048+ * the others unable to operate.
4049+ */
40464050static void iommu_detach_dependent_devices (struct intel_iommu * iommu ,
40474051 struct device * dev )
40484052{
4049- struct pci_dev * tmp , * parent , * pdev ;
4050-
40514053 if (!iommu || !dev || !dev_is_pci (dev ))
40524054 return ;
40534055
4054- pdev = to_pci_dev (dev );
4055-
4056- /* dependent device detach */
4057- tmp = pci_find_upstream_pcie_bridge (pdev );
4058- /* Secondary interface's bus number and devfn 0 */
4059- if (tmp ) {
4060- parent = pdev -> bus -> self ;
4061- while (parent != tmp ) {
4062- iommu_detach_dev (iommu , parent -> bus -> number ,
4063- parent -> devfn );
4064- parent = parent -> bus -> self ;
4065- }
4066- if (pci_is_pcie (tmp )) /* this is a PCIe-to-PCI bridge */
4067- iommu_detach_dev (iommu ,
4068- tmp -> subordinate -> number , 0 );
4069- else /* this is a legacy PCI bridge */
4070- iommu_detach_dev (iommu , tmp -> bus -> number ,
4071- tmp -> devfn );
4072- }
4056+ pci_for_each_dma_alias (to_pci_dev (dev ), & iommu_detach_dev_cb , iommu );
40734057}
40744058
40754059static void domain_remove_one_dev_info (struct dmar_domain * domain ,
0 commit comments