diff mbox series

[XEN,RFC,v6,11/11] iommu: Introduce no-dma feature

Message ID 998adb8e82b0b4610d800b12b89d47e6341e565a.1739785339.git.teddy.astie@vates.tech (mailing list archive)
State New
Headers show
Series IOMMU subsystem redesign and PV-IOMMU interface | expand

Commit Message

Teddy Astie Feb. 17, 2025, 10:18 a.m. UTC
This feature exposed through `dom0-iommu=no-dma` prevents the devices
of default context to have access to domain's memory.
This basically enforces DMA protection by default. The domain will
need to prepare a specific IOMMU context to do DMA.

This feature needs the guest to provide a PV-IOMMU driver.

Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
---
 xen/common/pv-iommu.c               |  3 +++
 xen/drivers/passthrough/iommu.c     | 10 ++++++++++
 xen/drivers/passthrough/x86/iommu.c |  4 ++++
 xen/include/xen/iommu.h             |  3 +++
 4 files changed, 20 insertions(+)
diff mbox series

Patch

diff --git a/xen/common/pv-iommu.c b/xen/common/pv-iommu.c
index a1315bf582..9c7d04b4c7 100644
--- a/xen/common/pv-iommu.c
+++ b/xen/common/pv-iommu.c
@@ -99,6 +99,9 @@  static long capabilities_op(struct pv_iommu_capabilities *cap, struct domain *d)
     cap->max_pasid = 0; /* TODO */
     cap->cap_flags = 0;
 
+    if ( !dom_iommu(d)->no_dma )
+        cap->cap_flags |= IOMMUCAP_default_identity;
+
     cap->pgsize_mask = PAGE_SIZE_4K;
 
     return 0;
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index c26a2160f9..59a4c64915 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -55,6 +55,7 @@  static bool __hwdom_initdata iommu_hwdom_none;
 bool __hwdom_initdata iommu_hwdom_strict;
 bool __read_mostly iommu_hwdom_passthrough;
 bool __hwdom_initdata iommu_hwdom_inclusive;
+bool __read_mostly iommu_hwdom_no_dma = false;
 int8_t __hwdom_initdata iommu_hwdom_reserved = -1;
 
 #ifndef iommu_hap_pt_share
@@ -172,6 +173,8 @@  static int __init cf_check parse_dom0_iommu_param(const char *s)
             iommu_hwdom_reserved = val;
         else if ( !cmdline_strcmp(s, "none") )
             iommu_hwdom_none = true;
+        else if ( (val = parse_boolean("dma", s, ss)) >= 0 )
+            iommu_hwdom_no_dma = !val;
         else
             rc = -EINVAL;
 
@@ -329,6 +332,13 @@  int iommu_domain_init(struct domain *d, unsigned int opts)
     if ( !is_hardware_domain(d) || iommu_hwdom_strict )
         hd->need_sync = !iommu_use_hap_pt(d);
 
+    if ( hd->no_dma )
+    {
+        /* No-DMA mode is exclusive with HAP and sync_pt. */
+        hd->hap_pt_share = false;
+        hd->need_sync = false;
+    }
+
     ASSERT(!(hd->need_sync && hd->hap_pt_share));
 
     hd->allow_pv_iommu = true;
diff --git a/xen/drivers/passthrough/x86/iommu.c b/xen/drivers/passthrough/x86/iommu.c
index 79efc6ad47..174c218b9b 100644
--- a/xen/drivers/passthrough/x86/iommu.c
+++ b/xen/drivers/passthrough/x86/iommu.c
@@ -529,6 +529,10 @@  void __hwdom_init arch_iommu_hwdom_init(struct domain *d)
     if ( iommu_hwdom_reserved == -1 )
         iommu_hwdom_reserved = 1;
 
+    if ( iommu_hwdom_no_dma )
+        /* Skip special mappings with no-dma mode */
+        return;
+
     if ( iommu_hwdom_inclusive )
     {
         printk(XENLOG_WARNING
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index e115642b86..fb38c1be86 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -106,6 +106,7 @@  extern bool iommu_debug;
 extern bool amd_iommu_perdev_intremap;
 
 extern bool iommu_hwdom_strict, iommu_hwdom_passthrough, iommu_hwdom_inclusive;
+extern bool iommu_hwdom_no_dma;
 extern int8_t iommu_hwdom_reserved;
 
 extern unsigned int iommu_dev_iotlb_timeout;
@@ -411,6 +412,8 @@  struct domain_iommu {
     /* SAF-2-safe enum constant in arithmetic operation */
     DECLARE_BITMAP(features, IOMMU_FEAT_count);
 
+    /* Do the IOMMU block all DMA on default context (implies !has_pt_share) ? */
+    bool no_dma;
 
     /* Is the domain allowed to use PV-IOMMU ? */
     bool allow_pv_iommu;