@@ -1606,7 +1606,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
16061606 int translation = CONTEXT_TT_MULTI_LEVEL ;
16071607 struct dma_pte * pgd = domain -> pgd ;
16081608 struct context_entry * context ;
1609- int agaw , ret ;
1609+ int ret ;
16101610
16111611 pr_debug ("Set context mapping for %02x:%02x.%d\n" ,
16121612 bus , PCI_SLOT (devfn ), PCI_FUNC (devfn ));
@@ -1623,27 +1623,15 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
16231623
16241624 copied_context_tear_down (iommu , context , bus , devfn );
16251625 context_clear_entry (context );
1626-
16271626 context_set_domain_id (context , did );
16281627
1629- /*
1630- * Skip top levels of page tables for iommu which has
1631- * less agaw than default. Unnecessary for PT mode.
1632- */
1633- for (agaw = domain -> agaw ; agaw > iommu -> agaw ; agaw -- ) {
1634- ret = - ENOMEM ;
1635- pgd = phys_to_virt (dma_pte_addr (pgd ));
1636- if (!dma_pte_present (pgd ))
1637- goto out_unlock ;
1638- }
1639-
16401628 if (info && info -> ats_supported )
16411629 translation = CONTEXT_TT_DEV_IOTLB ;
16421630 else
16431631 translation = CONTEXT_TT_MULTI_LEVEL ;
16441632
16451633 context_set_address_root (context , virt_to_phys (pgd ));
1646- context_set_address_width (context , agaw );
1634+ context_set_address_width (context , domain -> agaw );
16471635 context_set_translation_type (context , translation );
16481636 context_set_fault_enable (context );
16491637 context_set_present (context );
@@ -1876,20 +1864,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
18761864 u32 pasid )
18771865{
18781866 struct dma_pte * pgd = domain -> pgd ;
1879- int agaw , level ;
1880- int flags = 0 ;
1867+ int level , flags = 0 ;
18811868
1882- /*
1883- * Skip top levels of page tables for iommu which has
1884- * less agaw than default. Unnecessary for PT mode.
1885- */
1886- for (agaw = domain -> agaw ; agaw > iommu -> agaw ; agaw -- ) {
1887- pgd = phys_to_virt (dma_pte_addr (pgd ));
1888- if (!dma_pte_present (pgd ))
1889- return - ENOMEM ;
1890- }
1891-
1892- level = agaw_to_level (agaw );
1869+ level = agaw_to_level (domain -> agaw );
18931870 if (level != 4 && level != 5 )
18941871 return - EINVAL ;
18951872
@@ -3492,42 +3469,41 @@ static void intel_iommu_domain_free(struct iommu_domain *domain)
34923469 domain_exit (dmar_domain );
34933470}
34943471
3495- int prepare_domain_attach_device (struct iommu_domain * domain ,
3496- struct device * dev )
3472+ int paging_domain_compatible (struct iommu_domain * domain , struct device * dev )
34973473{
34983474 struct device_domain_info * info = dev_iommu_priv_get (dev );
34993475 struct dmar_domain * dmar_domain = to_dmar_domain (domain );
35003476 struct intel_iommu * iommu = info -> iommu ;
35013477 int addr_width ;
35023478
3479+ if (WARN_ON_ONCE (!(domain -> type & __IOMMU_DOMAIN_PAGING )))
3480+ return - EPERM ;
3481+
35033482 if (dmar_domain -> force_snooping && !ecap_sc_support (iommu -> ecap ))
35043483 return - EINVAL ;
35053484
35063485 if (domain -> dirty_ops && !ssads_supported (iommu ))
35073486 return - EINVAL ;
35083487
3488+ if (dmar_domain -> iommu_coherency !=
3489+ iommu_paging_structure_coherency (iommu ))
3490+ return - EINVAL ;
3491+
3492+ if (dmar_domain -> iommu_superpage !=
3493+ iommu_superpage_capability (iommu , dmar_domain -> use_first_level ))
3494+ return - EINVAL ;
3495+
3496+ if (dmar_domain -> use_first_level &&
3497+ (!sm_supported (iommu ) || !ecap_flts (iommu -> ecap )))
3498+ return - EINVAL ;
3499+
35093500 /* check if this iommu agaw is sufficient for max mapped address */
35103501 addr_width = agaw_to_width (iommu -> agaw );
35113502 if (addr_width > cap_mgaw (iommu -> cap ))
35123503 addr_width = cap_mgaw (iommu -> cap );
35133504
3514- if (dmar_domain -> max_addr > ( 1LL << addr_width ) )
3505+ if (dmar_domain -> gaw > addr_width || dmar_domain -> agaw > iommu -> agaw )
35153506 return - EINVAL ;
3516- dmar_domain -> gaw = addr_width ;
3517-
3518- /*
3519- * Knock out extra levels of page tables if necessary
3520- */
3521- while (iommu -> agaw < dmar_domain -> agaw ) {
3522- struct dma_pte * pte ;
3523-
3524- pte = dmar_domain -> pgd ;
3525- if (dma_pte_present (pte )) {
3526- dmar_domain -> pgd = phys_to_virt (dma_pte_addr (pte ));
3527- iommu_free_page (pte );
3528- }
3529- dmar_domain -> agaw -- ;
3530- }
35313507
35323508 if (sm_supported (iommu ) && !dev_is_real_dma_subdevice (dev ) &&
35333509 context_copied (iommu , info -> bus , info -> devfn ))
@@ -3543,7 +3519,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
35433519
35443520 device_block_translation (dev );
35453521
3546- ret = prepare_domain_attach_device (domain , dev );
3522+ ret = paging_domain_compatible (domain , dev );
35473523 if (ret )
35483524 return ret ;
35493525
@@ -4214,7 +4190,7 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
42144190 if (context_copied (iommu , info -> bus , info -> devfn ))
42154191 return - EBUSY ;
42164192
4217- ret = prepare_domain_attach_device (domain , dev );
4193+ ret = paging_domain_compatible (domain , dev );
42184194 if (ret )
42194195 return ret ;
42204196
0 commit comments