@@ -425,9 +425,12 @@ static LIST_HEAD(unmaps_to_do);
425425static int timer_on ;
426426static long list_size ;
427427
428+ static void domain_exit (struct dmar_domain * domain );
428429static void domain_remove_dev_info (struct dmar_domain * domain );
429430static void domain_remove_one_dev_info (struct dmar_domain * domain ,
430431 struct pci_dev * pdev );
432+ static void iommu_detach_dependent_devices (struct intel_iommu * iommu ,
433+ struct pci_dev * pdev );
431434
432435#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
433436int dmar_disabled = 0 ;
@@ -1286,10 +1289,6 @@ static int iommu_init_domains(struct intel_iommu *iommu)
12861289 return 0 ;
12871290}
12881291
1289-
1290- static void domain_exit (struct dmar_domain * domain );
1291- static void vm_domain_exit (struct dmar_domain * domain );
1292-
12931292static void free_dmar_iommu (struct intel_iommu * iommu )
12941293{
12951294 struct dmar_domain * domain ;
@@ -1304,12 +1303,8 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
13041303 spin_lock_irqsave (& domain -> iommu_lock , flags );
13051304 count = -- domain -> iommu_count ;
13061305 spin_unlock_irqrestore (& domain -> iommu_lock , flags );
1307- if (count == 0 ) {
1308- if (domain -> flags & DOMAIN_FLAG_VIRTUAL_MACHINE )
1309- vm_domain_exit (domain );
1310- else
1311- domain_exit (domain );
1312- }
1306+ if (count == 0 )
1307+ domain_exit (domain );
13131308 }
13141309 }
13151310
@@ -1327,17 +1322,26 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
13271322 free_context_table (iommu );
13281323}
13291324
1330- static struct dmar_domain * alloc_domain (void )
1325+ static struct dmar_domain * alloc_domain (bool vm )
13311326{
1327+ /* domain id for virtual machine, it won't be set in context */
1328+ static atomic_t vm_domid = ATOMIC_INIT (0 );
13321329 struct dmar_domain * domain ;
13331330
13341331 domain = alloc_domain_mem ();
13351332 if (!domain )
13361333 return NULL ;
13371334
13381335 domain -> nid = -1 ;
1336+ domain -> iommu_count = 0 ;
13391337 memset (domain -> iommu_bmp , 0 , sizeof (domain -> iommu_bmp ));
13401338 domain -> flags = 0 ;
1339+ spin_lock_init (& domain -> iommu_lock );
1340+ INIT_LIST_HEAD (& domain -> devices );
1341+ if (vm ) {
1342+ domain -> id = atomic_inc_return (& vm_domid );
1343+ domain -> flags = DOMAIN_FLAG_VIRTUAL_MACHINE ;
1344+ }
13411345
13421346 return domain ;
13431347}
@@ -1374,22 +1378,16 @@ static void iommu_detach_domain(struct dmar_domain *domain,
13741378{
13751379 unsigned long flags ;
13761380 int num , ndomains ;
1377- int found = 0 ;
13781381
13791382 spin_lock_irqsave (& iommu -> lock , flags );
13801383 ndomains = cap_ndoms (iommu -> cap );
13811384 for_each_set_bit (num , iommu -> domain_ids , ndomains ) {
13821385 if (iommu -> domains [num ] == domain ) {
1383- found = 1 ;
1386+ clear_bit (num , iommu -> domain_ids );
1387+ iommu -> domains [num ] = NULL ;
13841388 break ;
13851389 }
13861390 }
1387-
1388- if (found ) {
1389- clear_bit (num , iommu -> domain_ids );
1390- clear_bit (iommu -> seq_id , domain -> iommu_bmp );
1391- iommu -> domains [num ] = NULL ;
1392- }
13931391 spin_unlock_irqrestore (& iommu -> lock , flags );
13941392}
13951393
@@ -1461,8 +1459,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
14611459 unsigned long sagaw ;
14621460
14631461 init_iova_domain (& domain -> iovad , DMA_32BIT_PFN );
1464- spin_lock_init (& domain -> iommu_lock );
1465-
14661462 domain_reserve_special_ranges (domain );
14671463
14681464 /* calculate AGAW */
@@ -1481,7 +1477,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
14811477 return - ENODEV ;
14821478 }
14831479 domain -> agaw = agaw ;
1484- INIT_LIST_HEAD (& domain -> devices );
14851480
14861481 if (ecap_coherent (iommu -> ecap ))
14871482 domain -> iommu_coherency = 1 ;
@@ -1518,7 +1513,9 @@ static void domain_exit(struct dmar_domain *domain)
15181513 if (!intel_iommu_strict )
15191514 flush_unmaps_timeout (0 );
15201515
1516+ /* remove associated devices */
15211517 domain_remove_dev_info (domain );
1518+
15221519 /* destroy iovas */
15231520 put_iova_domain (& domain -> iovad );
15241521
@@ -1528,8 +1525,10 @@ static void domain_exit(struct dmar_domain *domain)
15281525 /* free page tables */
15291526 dma_pte_free_pagetable (domain , 0 , DOMAIN_MAX_PFN (domain -> gaw ));
15301527
1528+ /* clear attached or cached domains */
15311529 for_each_active_iommu (iommu , drhd )
1532- if (test_bit (iommu -> seq_id , domain -> iommu_bmp ))
1530+ if (domain -> flags & DOMAIN_FLAG_VIRTUAL_MACHINE ||
1531+ test_bit (iommu -> seq_id , domain -> iommu_bmp ))
15331532 iommu_detach_domain (domain , iommu );
15341533
15351534 free_domain_mem (domain );
@@ -1921,7 +1920,7 @@ static inline void unlink_domain_info(struct device_domain_info *info)
19211920static void domain_remove_dev_info (struct dmar_domain * domain )
19221921{
19231922 struct device_domain_info * info ;
1924- unsigned long flags ;
1923+ unsigned long flags , flags2 ;
19251924 struct intel_iommu * iommu ;
19261925
19271926 spin_lock_irqsave (& device_domain_lock , flags );
@@ -1934,8 +1933,22 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
19341933 iommu_disable_dev_iotlb (info );
19351934 iommu = device_to_iommu (info -> segment , info -> bus , info -> devfn );
19361935 iommu_detach_dev (iommu , info -> bus , info -> devfn );
1937- free_devinfo_mem (info );
19381936
1937+ if (domain -> flags & DOMAIN_FLAG_VIRTUAL_MACHINE ) {
1938+ iommu_detach_dependent_devices (iommu , info -> dev );
1939+ /* clear this iommu in iommu_bmp, update iommu count
1940+ * and capabilities
1941+ */
1942+ spin_lock_irqsave (& domain -> iommu_lock , flags2 );
1943+ if (test_and_clear_bit (iommu -> seq_id ,
1944+ domain -> iommu_bmp )) {
1945+ domain -> iommu_count -- ;
1946+ domain_update_iommu_cap (domain );
1947+ }
1948+ spin_unlock_irqrestore (& domain -> iommu_lock , flags2 );
1949+ }
1950+
1951+ free_devinfo_mem (info );
19391952 spin_lock_irqsave (& device_domain_lock , flags );
19401953 }
19411954 spin_unlock_irqrestore (& device_domain_lock , flags );
@@ -2055,7 +2068,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
20552068 iommu = drhd -> iommu ;
20562069
20572070 /* Allocate and intialize new domain for the device */
2058- domain = alloc_domain ();
2071+ domain = alloc_domain (false );
20592072 if (!domain )
20602073 goto error ;
20612074 if (iommu_attach_domain (domain , iommu )) {
@@ -2220,10 +2233,12 @@ static int __init si_domain_init(int hw)
22202233 struct intel_iommu * iommu ;
22212234 int nid , ret = 0 ;
22222235
2223- si_domain = alloc_domain ();
2236+ si_domain = alloc_domain (false );
22242237 if (!si_domain )
22252238 return - EFAULT ;
22262239
2240+ si_domain -> flags = DOMAIN_FLAG_STATIC_IDENTITY ;
2241+
22272242 for_each_active_iommu (iommu , drhd ) {
22282243 ret = iommu_attach_domain (si_domain , iommu );
22292244 if (ret ) {
@@ -2237,7 +2252,6 @@ static int __init si_domain_init(int hw)
22372252 return - EFAULT ;
22382253 }
22392254
2240- si_domain -> flags = DOMAIN_FLAG_STATIC_IDENTITY ;
22412255 pr_debug ("IOMMU: identity mapping domain is domain %d\n" ,
22422256 si_domain -> id );
22432257
@@ -3810,77 +3824,18 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
38103824 }
38113825}
38123826
3813- static void vm_domain_remove_all_dev_info (struct dmar_domain * domain )
3814- {
3815- struct device_domain_info * info ;
3816- struct intel_iommu * iommu ;
3817- unsigned long flags1 , flags2 ;
3818-
3819- spin_lock_irqsave (& device_domain_lock , flags1 );
3820- while (!list_empty (& domain -> devices )) {
3821- info = list_entry (domain -> devices .next ,
3822- struct device_domain_info , link );
3823- unlink_domain_info (info );
3824- spin_unlock_irqrestore (& device_domain_lock , flags1 );
3825-
3826- iommu_disable_dev_iotlb (info );
3827- iommu = device_to_iommu (info -> segment , info -> bus , info -> devfn );
3828- iommu_detach_dev (iommu , info -> bus , info -> devfn );
3829- iommu_detach_dependent_devices (iommu , info -> dev );
3830-
3831- /* clear this iommu in iommu_bmp, update iommu count
3832- * and capabilities
3833- */
3834- spin_lock_irqsave (& domain -> iommu_lock , flags2 );
3835- if (test_and_clear_bit (iommu -> seq_id ,
3836- domain -> iommu_bmp )) {
3837- domain -> iommu_count -- ;
3838- domain_update_iommu_cap (domain );
3839- }
3840- spin_unlock_irqrestore (& domain -> iommu_lock , flags2 );
3841-
3842- free_devinfo_mem (info );
3843- spin_lock_irqsave (& device_domain_lock , flags1 );
3844- }
3845- spin_unlock_irqrestore (& device_domain_lock , flags1 );
3846- }
3847-
3848- /* domain id for virtual machine, it won't be set in context */
3849- static atomic_t vm_domid = ATOMIC_INIT (0 );
3850-
3851- static struct dmar_domain * iommu_alloc_vm_domain (void )
3852- {
3853- struct dmar_domain * domain ;
3854-
3855- domain = alloc_domain_mem ();
3856- if (!domain )
3857- return NULL ;
3858-
3859- domain -> id = atomic_inc_return (& vm_domid );
3860- domain -> nid = -1 ;
3861- memset (domain -> iommu_bmp , 0 , sizeof (domain -> iommu_bmp ));
3862- domain -> flags = DOMAIN_FLAG_VIRTUAL_MACHINE ;
3863-
3864- return domain ;
3865- }
3866-
38673827static int md_domain_init (struct dmar_domain * domain , int guest_width )
38683828{
38693829 int adjust_width ;
38703830
38713831 init_iova_domain (& domain -> iovad , DMA_32BIT_PFN );
3872- spin_lock_init (& domain -> iommu_lock );
3873-
38743832 domain_reserve_special_ranges (domain );
38753833
38763834 /* calculate AGAW */
38773835 domain -> gaw = guest_width ;
38783836 adjust_width = guestwidth_to_adjustwidth (guest_width );
38793837 domain -> agaw = width_to_agaw (adjust_width );
38803838
3881- INIT_LIST_HEAD (& domain -> devices );
3882-
3883- domain -> iommu_count = 0 ;
38843839 domain -> iommu_coherency = 0 ;
38853840 domain -> iommu_snooping = 0 ;
38863841 domain -> iommu_superpage = 0 ;
@@ -3895,53 +3850,11 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
38953850 return 0 ;
38963851}
38973852
3898- static void iommu_free_vm_domain (struct dmar_domain * domain )
3899- {
3900- unsigned long flags ;
3901- struct dmar_drhd_unit * drhd ;
3902- struct intel_iommu * iommu ;
3903- unsigned long i ;
3904- unsigned long ndomains ;
3905-
3906- for_each_active_iommu (iommu , drhd ) {
3907- ndomains = cap_ndoms (iommu -> cap );
3908- for_each_set_bit (i , iommu -> domain_ids , ndomains ) {
3909- if (iommu -> domains [i ] == domain ) {
3910- spin_lock_irqsave (& iommu -> lock , flags );
3911- clear_bit (i , iommu -> domain_ids );
3912- iommu -> domains [i ] = NULL ;
3913- spin_unlock_irqrestore (& iommu -> lock , flags );
3914- break ;
3915- }
3916- }
3917- }
3918- }
3919-
3920- static void vm_domain_exit (struct dmar_domain * domain )
3921- {
3922- /* Domain 0 is reserved, so dont process it */
3923- if (!domain )
3924- return ;
3925-
3926- vm_domain_remove_all_dev_info (domain );
3927- /* destroy iovas */
3928- put_iova_domain (& domain -> iovad );
3929-
3930- /* clear ptes */
3931- dma_pte_clear_range (domain , 0 , DOMAIN_MAX_PFN (domain -> gaw ));
3932-
3933- /* free page tables */
3934- dma_pte_free_pagetable (domain , 0 , DOMAIN_MAX_PFN (domain -> gaw ));
3935-
3936- iommu_free_vm_domain (domain );
3937- free_domain_mem (domain );
3938- }
3939-
39403853static int intel_iommu_domain_init (struct iommu_domain * domain )
39413854{
39423855 struct dmar_domain * dmar_domain ;
39433856
3944- dmar_domain = iommu_alloc_vm_domain ( );
3857+ dmar_domain = alloc_domain (true );
39453858 if (!dmar_domain ) {
39463859 printk (KERN_ERR
39473860 "intel_iommu_domain_init: dmar_domain == NULL\n" );
@@ -3950,7 +3863,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain)
39503863 if (md_domain_init (dmar_domain , DEFAULT_DOMAIN_ADDRESS_WIDTH )) {
39513864 printk (KERN_ERR
39523865 "intel_iommu_domain_init() failed\n" );
3953- vm_domain_exit (dmar_domain );
3866+ domain_exit (dmar_domain );
39543867 return - ENOMEM ;
39553868 }
39563869 domain_update_iommu_cap (dmar_domain );
@@ -3968,7 +3881,7 @@ static void intel_iommu_domain_destroy(struct iommu_domain *domain)
39683881 struct dmar_domain * dmar_domain = domain -> priv ;
39693882
39703883 domain -> priv = NULL ;
3971- vm_domain_exit (dmar_domain );
3884+ domain_exit (dmar_domain );
39723885}
39733886
39743887static int intel_iommu_attach_device (struct iommu_domain * domain ,
0 commit comments