@@ -56,7 +56,13 @@ type arch_domainconfig =
| ARM of xen_arm_arch_domainconfig
| X86 of xen_x86_arch_domainconfig
-type domain_create_flag = CDF_HVM | CDF_HAP
+type domain_create_flag =
+ | CDF_HVM
+ | CDF_HAP
+ | CDF_S3_INTEGRITY
+ | CDF_OOS_OFF
+ | CDF_XS_DOMAIN
+ | CDF_IOMMU
type domctl_create_config =
{
@@ -49,7 +49,13 @@ type arch_domainconfig =
| ARM of xen_arm_arch_domainconfig
| X86 of xen_x86_arch_domainconfig
-type domain_create_flag = CDF_HVM | CDF_HAP
+type domain_create_flag =
+ | CDF_HVM
+ | CDF_HAP
+ | CDF_S3_INTEGRITY
+ | CDF_OOS_OFF
+ | CDF_XS_DOMAIN
+ | CDF_IOMMU
type domctl_create_config = {
ssidref: int32;
@@ -961,6 +961,9 @@ void __init start_xen(unsigned long boot_phys_offset,
dom0_cfg.arch.tee_type = tee_get_type();
dom0_cfg.max_vcpus = dom0_max_vcpus();
+ if ( iommu_enabled )
+ dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
+
dom0 = domain_create(0, &dom0_cfg, true);
if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
panic("Error creating domain 0\n");
@@ -1733,6 +1733,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
}
dom0_cfg.max_vcpus = dom0_max_vcpus();
+ if ( iommu_enabled )
+ dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
+
/* Create initial domain 0. */
dom0 = domain_create(get_initial_domain_id(), &dom0_cfg, !pv_shim);
if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) )
@@ -301,7 +301,8 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config)
XEN_DOMCTL_CDF_hap |
XEN_DOMCTL_CDF_s3_integrity |
XEN_DOMCTL_CDF_oos_off |
- XEN_DOMCTL_CDF_xs_domain) )
+ XEN_DOMCTL_CDF_xs_domain |
+ XEN_DOMCTL_CDF_iommu) )
{
dprintk(XENLOG_INFO, "Unknown CDF flags %#x\n", config->flags);
return -EINVAL;
@@ -328,6 +329,12 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config)
config->flags |= XEN_DOMCTL_CDF_oos_off;
}
+ if ( (config->flags & XEN_DOMCTL_CDF_iommu) && !iommu_enabled )
+ {
+ dprintk(XENLOG_INFO, "IOMMU is not enabled\n");
+ return -EINVAL;
+ }
+
return arch_sanitise_domain_config(config);
}
@@ -515,6 +515,19 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
rover = dom;
}
+ /*
+ * For now, make sure the createdomain IOMMU flag is set if the
+ * IOMMU is enabled. When the flag comes under toolstack control
+ * this can go away.
+ */
+ if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_iommu )
+ {
+ ASSERT_UNREACHABLE();
+ return -EINVAL;
+ }
+ if ( iommu_enabled )
+ op->u.createdomain.flags |= XEN_DOMCTL_CDF_iommu;
+
d = domain_create(dom, &op->u.createdomain, false);
if ( IS_ERR(d) )
{
@@ -119,6 +119,9 @@ int iommu_release_dt_devices(struct domain *d)
struct dt_device_node *dev, *_dev;
int rc;
+ if ( !is_iommu_enabled(d) )
+ return 0;
+
list_for_each_entry_safe(dev, _dev, &hd->dt_devices, domain_list)
{
rc = iommu_deassign_dt_device(d, dev);
@@ -151,13 +151,13 @@ int iommu_domain_init(struct domain *d)
struct domain_iommu *hd = dom_iommu(d);
int ret = 0;
+ if ( !is_iommu_enabled(d) )
+ return 0;
+
ret = arch_iommu_domain_init(d);
if ( ret )
return ret;
- if ( !iommu_enabled )
- return 0;
-
hd->platform_ops = iommu_get_ops();
return hd->platform_ops->init(d);
}
@@ -64,6 +64,10 @@ struct xen_domctl_createdomain {
/* Is this a xenstore domain? */
#define _XEN_DOMCTL_CDF_xs_domain 4
#define XEN_DOMCTL_CDF_xs_domain (1U<<_XEN_DOMCTL_CDF_xs_domain)
+ /* Should this domain be permitted to use the IOMMU? */
+#define _XEN_DOMCTL_CDF_iommu 5
+#define XEN_DOMCTL_CDF_iommu (1U<<_XEN_DOMCTL_CDF_iommu)
+
uint32_t flags;
/*
@@ -983,6 +983,11 @@ static inline bool is_xenstore_domain(const struct domain *d)
return d->options & XEN_DOMCTL_CDF_xs_domain;
}
+static inline bool is_iommu_enabled(const struct domain *d)
+{
+ return evaluate_nospec(d->options & XEN_DOMCTL_CDF_iommu);
+}
+
extern bool sched_smt_power_savings;
extern enum cpufreq_controller {