diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in
index b98d161398..ddf82cb3bc 100644
--- a/docs/man/xl.cfg.5.pod.in
+++ b/docs/man/xl.cfg.5.pod.in
@@ -1614,6 +1614,15 @@ This feature is a B<technology preview>.
 
 =back
 
+=over 4
+
+=item B<force_assign_without_iommu=BOOLEAN>
+
+If set, Xen allows to assign a devices even if it is not behind an IOMMU.
+This renders your platform *unsafe* if the device is DMA-capable.
+
+=back
+
 =back
 
 =head2 Paravirtualised (PV) Guest Specific Options
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index b746ff1081..664933bbb8 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -1091,6 +1091,11 @@ if err := x.DmRestrict.fromC(&xc.dm_restrict);err != nil {
 return fmt.Errorf("converting field DmRestrict: %v", err)
 }
 x.Tee = TeeType(xc.tee)
+
+if err := x.ForceAssignWithoutIommu.fromC(&xc.force_assign_without_iommu);err != nil {
+return fmt.Errorf("converting field ForceAssignWithoutIommu: %v", err)
+}
+
 x.Type = DomainType(xc._type)
 switch x.Type{
 case DomainTypeHvm:
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
index b1e84d5258..2f7a088c3b 100644
--- a/tools/golang/xenlight/types.gen.go
+++ b/tools/golang/xenlight/types.gen.go
@@ -512,6 +512,7 @@ NestedHvm Defbool
 Apic Defbool
 DmRestrict Defbool
 Tee TeeType
+ForceAssignWithoutIommu Defbool
 Type DomainType
 TypeUnion DomainBuildInfoTypeUnion
 ArchArm struct {
diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
index eef1de0939..c5090e2b32 100644
--- a/tools/libs/light/libxl_arm.c
+++ b/tools/libs/light/libxl_arm.c
@@ -101,6 +101,9 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
         return ERROR_FAIL;
     }
 
+    if (libxl_defbool_val(d_config->b_info.force_assign_without_iommu))
+        config->iommu_opts |= XEN_DOMCTL_IOMMU_force_iommu;
+
     return 0;
 }
 
diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl
index 2a42da2f7d..1080966c33 100644
--- a/tools/libs/light/libxl_types.idl
+++ b/tools/libs/light/libxl_types.idl
@@ -564,6 +564,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
     ("apic",             libxl_defbool),
     ("dm_restrict",      libxl_defbool),
     ("tee",              libxl_tee_type),
+    ("force_assign_without_iommu", libxl_defbool),
     ("u", KeyedUnion(None, libxl_domain_type, "type",
                 [("hvm", Struct(None, [("firmware",         string),
                                        ("bios",             libxl_bios_type),
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 117fcdcb2b..67fa96d949 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -2747,6 +2747,9 @@ skip_usbdev:
         }
     }
 
+    xlu_cfg_get_defbool(config, "force_assign_without_iommu",
+                        &b_info->force_assign_without_iommu, 0);
+
     parse_vkb_list(config, d_config);
 
     xlu_cfg_get_defbool(config, "xend_suspend_evtchn_compat",
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 093bb4403f..f1f19bf711 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -512,7 +512,7 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config)
 
     if ( iommu )
     {
-        if ( config->iommu_opts & ~XEN_DOMCTL_IOMMU_no_sharept )
+        if ( config->iommu_opts >> XEN_DOMCTL_IOMMU_MAX )
         {
             dprintk(XENLOG_INFO, "Unknown IOMMU options %#x\n",
                     config->iommu_opts);
diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c
index 98f2aa0dad..103608dec1 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -198,6 +198,7 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
 {
     int ret;
     struct dt_device_node *dev;
+    struct domain_iommu *hd = dom_iommu(d);
 
     switch ( domctl->cmd )
     {
@@ -238,6 +239,16 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
             return -EINVAL;
 
         ret = iommu_add_dt_device(dev);
+
+        /*
+         * iommu_add_dt_device returns 1 if iommu is disabled or device don't
+         * have iommus property
+         */
+        if ( (ret == 1) && (hd->force_assign_iommu) ) {
+            ret = -ENOSYS;
+            break;
+        }
+
         if ( ret < 0 )
         {
             printk(XENLOG_G_ERR "Failed to add %s to the IOMMU\n",
@@ -275,10 +286,14 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
 
         ret = iommu_deassign_dt_device(d, dev);
 
-        if ( ret )
-            printk(XENLOG_G_ERR "XEN_DOMCTL_assign_dt_device: assign \"%s\""
+        if ( ret ) {
+            if ( hd->force_assign_iommu )
+                ret = -ENOSYS;
+            else
+                printk(XENLOG_G_ERR "XEN_DOMCTL_assign_dt_device: assign \"%s\""
                    " to dom%u failed (%d)\n",
                    dt_node_full_name(dev), d->domain_id, ret);
+        }
         break;
 
     default:
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 6334370109..216a9058c0 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -193,6 +193,8 @@ int iommu_domain_init(struct domain *d, unsigned int opts)
     hd->node = NUMA_NO_NODE;
 #endif
 
+    hd->force_assign_iommu = opts & XEN_DOMCTL_IOMMU_force_iommu;
+
     ret = arch_iommu_domain_init(d);
     if ( ret )
         return ret;
@@ -534,6 +536,7 @@ int iommu_do_domctl(
 {
     int ret = -ENODEV;
 
+
     if ( !is_iommu_enabled(d) )
         return -EOPNOTSUPP;
 
@@ -542,7 +545,7 @@ int iommu_do_domctl(
 #endif
 
 #ifdef CONFIG_HAS_DEVICE_TREE
-    if ( ret == -ENODEV )
+    if ( ret == -ENOSYS )
         ret = iommu_do_dt_domctl(domctl, d, u_domctl);
 #endif
 
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index b85e6170b0..bf5f8c5b6b 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -81,8 +81,11 @@ struct xen_domctl_createdomain {
 #define _XEN_DOMCTL_IOMMU_no_sharept  0
 #define XEN_DOMCTL_IOMMU_no_sharept   (1U << _XEN_DOMCTL_IOMMU_no_sharept)
 
+#define _XEN_DOMCTL_IOMMU_force_iommu 1
+#define XEN_DOMCTL_IOMMU_force_iommu  (1U << _XEN_DOMCTL_IOMMU_force_iommu)
+
 /* Max XEN_DOMCTL_IOMMU_* constant.  Used for ABI checking. */
-#define XEN_DOMCTL_IOMMU_MAX XEN_DOMCTL_IOMMU_no_sharept
+#define XEN_DOMCTL_IOMMU_MAX XEN_DOMCTL_IOMMU_force_iommu
 
     uint32_t iommu_opts;
 
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 6b2cdffa4a..a9cf2334af 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -330,6 +330,9 @@ struct domain_iommu {
      * necessarily imply this is true.
      */
     bool need_sync;
+
+    /* Do not return error if the device without iommu is assigned */
+    bool force_assign_iommu;
 };
 
 #define dom_iommu(d)              (&(d)->iommu)
