]> xenbits.xensource.com Git - xen.git/commitdiff
VT-d: limit page table population in domain_pgd_maddr()
authorJan Beulich <jbeulich@suse.com>
Fri, 22 Apr 2022 12:53:13 +0000 (14:53 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 22 Apr 2022 12:53:13 +0000 (14:53 +0200)
I have to admit that I never understood why domain_pgd_maddr() wants to
populate all page table levels for DFN 0. I can only assume that despite
the comment there what is needed is population just down to the smallest
possible nr_pt_levels that the loop later in the function may need to
run to. Hence what is needed is the minimum of all possible
iommu->nr_pt_levels, to then be passed into addr_to_dma_page_maddr()
instead of literal 1.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
xen/drivers/passthrough/vtd/iommu.c

index 4400f56459048b388737fcb3f5268a05ebd0f408..f68d960d75d0ffa15ecc9b73fbf374035f281e0c 100644 (file)
@@ -61,6 +61,7 @@ bool __read_mostly iommu_snoop = true;
 #endif
 
 static unsigned int __read_mostly nr_iommus;
+static unsigned int __ro_after_init min_pt_levels = UINT_MAX;
 
 static struct tasklet vtd_fault_tasklet;
 
@@ -439,8 +440,11 @@ static paddr_t domain_pgd_maddr(struct domain *d, paddr_t pgd_maddr,
     {
         if ( !hd->arch.vtd.pgd_maddr )
         {
-            /* Ensure we have pagetables allocated down to leaf PTE. */
-            addr_to_dma_page_maddr(d, 0, 1, NULL, true);
+            /*
+             * Ensure we have pagetables allocated down to the smallest
+             * level the loop below may need to run to.
+             */
+            addr_to_dma_page_maddr(d, 0, min_pt_levels, NULL, true);
 
             if ( !hd->arch.vtd.pgd_maddr )
                 return 0;
@@ -1349,6 +1353,8 @@ int __init iommu_alloc(struct acpi_drhd_unit *drhd)
         goto free;
     }
     iommu->nr_pt_levels = agaw_to_level(agaw);
+    if ( min_pt_levels > iommu->nr_pt_levels )
+        min_pt_levels = iommu->nr_pt_levels;
 
     if ( !ecap_coherent(iommu->ecap) )
         iommu_non_coherent = true;