]> xenbits.xensource.com Git - people/tklengyel/xen.git/commitdiff
IOMMU: have vendor code announce supported page sizes
authorJan Beulich <jbeulich@suse.com>
Fri, 22 Apr 2022 12:54:16 +0000 (14:54 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 22 Apr 2022 12:54:16 +0000 (14:54 +0200)
Generic code will use this information to determine what order values
can legitimately be passed to the ->{,un}map_page() hooks. For now all
ops structures simply get to announce 4k mappings (as base page size),
and there is (and always has been) an assumption that this matches the
CPU's MMU base page size (eventually we will want to permit IOMMUs with
a base page size smaller than the CPU MMU's).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Rahul Singh <rahul.singh@arm.com>
xen/drivers/passthrough/amd/pci_amd_iommu.c
xen/drivers/passthrough/arm/ipmmu-vmsa.c
xen/drivers/passthrough/arm/smmu-v3.c
xen/drivers/passthrough/arm/smmu.c
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/iommu.h

index 3430e39a295455d57447393e24e18b2287470554..8cbbd7c6c9bf3b3256609a10d21d8e47ac572640 100644 (file)
@@ -746,6 +746,7 @@ static void cf_check amd_dump_page_tables(struct domain *d)
 }
 
 static const struct iommu_ops __initconst_cf_clobber _iommu_ops = {
+    .page_sizes = PAGE_SIZE_4K,
     .init = amd_iommu_domain_init,
     .hwdom_init = amd_iommu_hwdom_init,
     .quarantine_init = amd_iommu_quarantine_init,
index d2572bcd304ee8d829eae925a74205daf7b24abb..5a7b332bccc001d05cabfea022af434841ef5189 100644 (file)
@@ -1355,6 +1355,7 @@ static void ipmmu_iommu_domain_teardown(struct domain *d)
 
 static const struct iommu_ops ipmmu_iommu_ops =
 {
+    .page_sizes      = PAGE_SIZE_4K,
     .init            = ipmmu_iommu_domain_init,
     .hwdom_init      = arch_iommu_hwdom_init,
     .teardown        = ipmmu_iommu_domain_teardown,
index 71b022fe7fd6419ad144f7e0dc716ae864a0a466..2822ffe05f9f6571dad16444196076c776326377 100644 (file)
@@ -3411,7 +3411,8 @@ static void arm_smmu_iommu_xen_domain_teardown(struct domain *d)
 }
 
 static const struct iommu_ops arm_smmu_iommu_ops = {
-       .init           = arm_smmu_iommu_xen_domain_init,
+       .page_sizes             = PAGE_SIZE_4K,
+       .init                   = arm_smmu_iommu_xen_domain_init,
        .hwdom_init             = arch_iommu_hwdom_init,
        .teardown               = arm_smmu_iommu_xen_domain_teardown,
        .iotlb_flush            = arm_smmu_iotlb_flush,
index b186c28dffe978c4f275c7d375d9a3302c4fea08..5cacb2dd99a58342f4f77f21c0b3ab2d9981596f 100644 (file)
@@ -2858,6 +2858,7 @@ static void arm_smmu_iommu_domain_teardown(struct domain *d)
 }
 
 static const struct iommu_ops arm_smmu_iommu_ops = {
+    .page_sizes = PAGE_SIZE_4K,
     .init = arm_smmu_iommu_domain_init,
     .hwdom_init = arch_iommu_hwdom_init,
     .add_device = arm_smmu_dt_add_device_generic,
index 73a7da71cdbb2ad624e66f739e91fbed106d5307..1109a865321f051f23289b182b0ed739ff33c299 100644 (file)
@@ -494,7 +494,17 @@ int __init iommu_setup(void)
 
     if ( iommu_enable )
     {
+        const struct iommu_ops *ops = NULL;
+
         rc = iommu_hardware_setup();
+        if ( !rc )
+            ops = iommu_get_ops();
+        if ( ops && (ops->page_sizes & -ops->page_sizes) != PAGE_SIZE )
+        {
+            printk(XENLOG_ERR "IOMMU: page size mask %lx unsupported\n",
+                   ops->page_sizes);
+            rc = ops->page_sizes ? -EPERM : -ENODATA;
+        }
         iommu_enabled = (rc == 0);
     }
 
index f68d960d75d0ffa15ecc9b73fbf374035f281e0c..cff37c0c3129b11d7408115a2012a0de1f91bae5 100644 (file)
@@ -3127,6 +3127,7 @@ static int cf_check intel_iommu_quarantine_init(struct pci_dev *pdev,
 }
 
 static const struct iommu_ops __initconst_cf_clobber vtd_ops = {
+    .page_sizes = PAGE_SIZE_4K,
     .init = intel_iommu_domain_init,
     .hwdom_init = intel_iommu_hwdom_init,
     .quarantine_init = intel_iommu_quarantine_init,
index 3a83981464da1b0864c9ce68e2d08a187c501005..f7e8d5f28720c14ceac6431d983abd2145fa78d0 100644 (file)
@@ -231,6 +231,7 @@ struct page_info;
 typedef int iommu_grdm_t(xen_pfn_t start, xen_ulong_t nr, u32 id, void *ctxt);
 
 struct iommu_ops {
+    unsigned long page_sizes;
     int (*init)(struct domain *d);
     void (*hwdom_init)(struct domain *d);
     int (*quarantine_init)(device_t *dev, bool scratch_page);