Function iommu_do_dt_domctl() is the main entry for all device-tree-subset
iommu-related domctl-op, and shall be wrapped with CONFIG_MGMT_HYPERCALLS.
Tracking its calling chain, the following functions shall all be wrapped
with CONFIG_MGMT_HYPERCALLS:
- make PCI_PASSTHROUGH depend on MGMT_HYPERCALLS
- iommu_do_dt_domctl
- xsm_assign_dtdevice
- xsm_deassign_dtdevice
- iommu_deassign_dt_device
- arm_smmu_reassign_dev
- arm_smmu_deassign_dev
- arm_smmu_detach_dev
- arm_smmu_domain_remove_master
- ipmmu_reassign_device
- ipmmu_deassign_device
- ipmmu_detach_device
- iommu_remove_dt_device
- iommu_dt_device_is_assigned_locked
- dt_find_node_by_gpath
Otherwise all the functions will become unreachable when MGMT_HYPERCALLS=n,
and hence violating Misra rule 2.1
Move codes closer to avoid scattering #ifdef
Signed-off-by: Penny Zheng <[email protected]>
---
v3 -> v4
- split into PCI related subset and DT subset
- Move codes closer to avoid scattering #ifdef
---
xen/arch/arm/Kconfig | 2 +-
xen/common/device-tree/device-tree.c | 2 +
xen/drivers/passthrough/arm/ipmmu-vmsa.c | 26 +++---
xen/drivers/passthrough/arm/smmu-v3.c | 4 +
xen/drivers/passthrough/arm/smmu.c | 55 ++++++------
xen/drivers/passthrough/device_tree.c | 108 ++++++++++++-----------
xen/include/xsm/dummy.h | 6 +-
xen/include/xsm/xsm.h | 12 +--
xen/xsm/dummy.c | 6 +-
xen/xsm/flask/hooks.c | 12 +--
10 files changed, 126 insertions(+), 107 deletions(-)
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index cf6af68299..5a5d7810c8 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -270,7 +270,7 @@ source "arch/arm/firmware/Kconfig"
config PCI_PASSTHROUGH
bool "PCI passthrough" if EXPERT
- depends on ARM_64 && HAS_PASSTHROUGH
+ depends on ARM_64 && HAS_PASSTHROUGH && MGMT_HYPERCALLS
help
This option enables PCI device passthrough
diff --git a/xen/common/device-tree/device-tree.c
b/xen/common/device-tree/device-tree.c
index 0b5375f151..70bd8e7da5 100644
--- a/xen/common/device-tree/device-tree.c
+++ b/xen/common/device-tree/device-tree.c
@@ -371,6 +371,7 @@ struct dt_device_node *dt_find_node_by_path_from(struct
dt_device_node *from,
return np;
}
+#ifdef CONFIG_MGMT_HYPERCALLS
int dt_find_node_by_gpath(XEN_GUEST_HANDLE(char) u_path, uint32_t u_plen,
struct dt_device_node **node)
{
@@ -386,6 +387,7 @@ int dt_find_node_by_gpath(XEN_GUEST_HANDLE(char) u_path,
uint32_t u_plen,
return (*node == NULL) ? -ESRCH : 0;
}
+#endif /* CONFIG_MGMT_HYPERCALLS */
struct dt_device_node *dt_find_node_by_alias(const char *alias)
{
diff --git a/xen/drivers/passthrough/arm/ipmmu-vmsa.c
b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
index ea9fa9ddf3..b1fc14bc32 100644
--- a/xen/drivers/passthrough/arm/ipmmu-vmsa.c
+++ b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
@@ -739,16 +739,6 @@ static int ipmmu_attach_device(struct ipmmu_vmsa_domain
*domain,
return 0;
}
-static void ipmmu_detach_device(struct ipmmu_vmsa_domain *domain,
- struct device *dev)
-{
- struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- unsigned int i;
-
- for ( i = 0; i < fwspec->num_ids; ++i )
- ipmmu_utlb_disable(domain, fwspec->ids[i]);
-}
-
static int ipmmu_init_platform_device(struct device *dev,
const struct dt_phandle_args *args)
{
@@ -1138,7 +1128,9 @@ static void ipmmu_free_root_domain(struct
ipmmu_vmsa_domain *domain)
xfree(domain);
}
+#ifdef CONFIG_MGMT_HYPERCALLS
static int ipmmu_deassign_device(struct domain *d, struct device *dev);
+#endif
static int ipmmu_assign_device(struct domain *d, u8 devfn, struct device *dev,
uint32_t flag)
@@ -1254,6 +1246,17 @@ out:
return ret;
}
+#ifdef CONFIG_MGMT_HYPERCALLS
+static void ipmmu_detach_device(struct ipmmu_vmsa_domain *domain,
+ struct device *dev)
+{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ unsigned int i;
+
+ for ( i = 0; i < fwspec->num_ids; ++i )
+ ipmmu_utlb_disable(domain, fwspec->ids[i]);
+}
+
static int ipmmu_deassign_device(struct domain *d, struct device *dev)
{
struct ipmmu_vmsa_xen_domain *xen_domain = dom_iommu(d)->arch.priv;
@@ -1309,6 +1312,7 @@ static int ipmmu_reassign_device(struct domain *s, struct
domain *t,
return 0;
}
+#endif /* CONFIG_MGMT_HYPERCALLS */
static int ipmmu_dt_xlate(struct device *dev,
const struct dt_phandle_args *spec)
@@ -1487,7 +1491,9 @@ static const struct iommu_ops ipmmu_iommu_ops =
.teardown = ipmmu_iommu_domain_teardown,
.iotlb_flush = ipmmu_iotlb_flush,
.assign_device = ipmmu_assign_device,
+#ifdef CONFIG_MGMT_HYPERCALLS
.reassign_device = ipmmu_reassign_device,
+#endif
.map_page = arm_iommu_map_page,
.unmap_page = arm_iommu_unmap_page,
.dt_xlate = ipmmu_dt_xlate,
diff --git a/xen/drivers/passthrough/arm/smmu-v3.c
b/xen/drivers/passthrough/arm/smmu-v3.c
index bf153227db..22def57b03 100644
--- a/xen/drivers/passthrough/arm/smmu-v3.c
+++ b/xen/drivers/passthrough/arm/smmu-v3.c
@@ -2759,6 +2759,7 @@ out:
return ret;
}
+#ifdef CONFIG_MGMT_HYPERCALLS
static int arm_smmu_deassign_dev(struct domain *d, uint8_t devfn, struct
device *dev)
{
struct iommu_domain *io_domain = arm_smmu_get_domain(d, dev);
@@ -2826,6 +2827,7 @@ static int arm_smmu_reassign_dev(struct domain *s, struct
domain *t,
return 0;
}
+#endif /* CONFIG_MGMT_HYPERCALLS */
static int arm_smmu_iommu_xen_domain_init(struct domain *d)
{
@@ -2862,7 +2864,9 @@ static const struct iommu_ops arm_smmu_iommu_ops = {
.teardown = arm_smmu_iommu_xen_domain_teardown,
.iotlb_flush = arm_smmu_iotlb_flush,
.assign_device = arm_smmu_assign_dev,
+#ifdef CONFIG_MGMT_HYPERCALLS
.reassign_device = arm_smmu_reassign_dev,
+#endif
.map_page = arm_iommu_map_page,
.unmap_page = arm_iommu_unmap_page,
.dt_xlate = arm_smmu_dt_xlate,
diff --git a/xen/drivers/passthrough/arm/smmu.c
b/xen/drivers/passthrough/arm/smmu.c
index 22d306d0cb..a75ec08633 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -894,8 +894,10 @@ static int register_smmu_master(struct arm_smmu_device
*smmu,
/* Forward declaration */
static int arm_smmu_assign_dev(struct domain *d, u8 devfn,
struct device *dev, u32 flag);
+#ifdef CONFIG_MGMT_HYPERCALLS
static int arm_smmu_deassign_dev(struct domain *d, uint8_t devfn,
struct device *dev);
+#endif
/*
* The driver which supports generic IOMMU DT bindings must have this
@@ -1699,21 +1701,6 @@ static int arm_smmu_domain_add_master(struct
arm_smmu_domain *smmu_domain,
return 0;
}
-static void arm_smmu_domain_remove_master(
- const struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_master_cfg *cfg)
-{
- uint32_t i, idx;
- struct arm_smmu_device *smmu = smmu_domain->smmu;
- struct arm_smmu_s2cr *s2cr = smmu->s2crs;
- const struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg);
-
- for_each_cfg_sme(cfg, i, idx, fwspec->num_ids) {
- s2cr[idx] = s2cr_init_val;
- arm_smmu_write_s2cr(smmu, idx);
- }
-}
-
static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
int ret;
@@ -1761,16 +1748,6 @@ static int arm_smmu_attach_dev(struct iommu_domain
*domain, struct device *dev)
return arm_smmu_domain_add_master(smmu_domain, cfg);
}
-static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device
*dev)
-{
- struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_master_cfg *cfg = find_smmu_master_cfg(dev);
-
- if (cfg)
- arm_smmu_domain_remove_master(smmu_domain, cfg);
-
-}
-
#if 0 /*
* Xen: The page table is shared with the processor, therefore
* helpers to implement separate is not necessary.
@@ -2849,6 +2826,31 @@ out:
return ret;
}
+#ifdef CONFIG_MGMT_HYPERCALLS
+static void arm_smmu_domain_remove_master(
+ const struct arm_smmu_domain *smmu_domain,
+ struct arm_smmu_master_cfg *cfg)
+{
+ uint32_t i, idx;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_s2cr *s2cr = smmu->s2crs;
+ const struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg);
+
+ for_each_cfg_sme(cfg, i, idx, fwspec->num_ids) {
+ s2cr[idx] = s2cr_init_val;
+ arm_smmu_write_s2cr(smmu, idx);
+ }
+}
+
+static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device
*dev)
+{
+ struct arm_smmu_domain *smmu_domain = domain->priv;
+ struct arm_smmu_master_cfg *cfg = find_smmu_master_cfg(dev);
+
+ if (cfg)
+ arm_smmu_domain_remove_master(smmu_domain, cfg);
+
+}
static int arm_smmu_deassign_dev(struct domain *d, uint8_t devfn,
struct device *dev)
{
@@ -2918,6 +2920,7 @@ static int arm_smmu_reassign_dev(struct domain *s, struct
domain *t,
return 0;
}
+#endif /* CONFIG_MGMT_HYPERCALLS */
static int arm_smmu_iommu_domain_init(struct domain *d)
{
@@ -2956,7 +2959,9 @@ static const struct iommu_ops arm_smmu_iommu_ops = {
.teardown = arm_smmu_iommu_domain_teardown,
.iotlb_flush = arm_smmu_iotlb_flush,
.assign_device = arm_smmu_assign_dev,
+#ifdef CONFIG_MGMT_HYPERCALLS
.reassign_device = arm_smmu_reassign_dev,
+#endif
.map_page = arm_iommu_map_page,
.unmap_page = arm_iommu_unmap_page,
.dt_xlate = arm_smmu_dt_xlate_generic,
diff --git a/xen/drivers/passthrough/device_tree.c
b/xen/drivers/passthrough/device_tree.c
index 015ffa15d4..72c38355eb 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -59,6 +59,14 @@ fail:
return rc;
}
+int iommu_dt_domain_init(struct domain *d)
+{
+ INIT_LIST_HEAD(&dom_iommu(d)->dt_devices);
+
+ return 0;
+}
+
+#ifdef CONFIG_MGMT_HYPERCALLS
int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
{
const struct domain_iommu *hd = dom_iommu(d);
@@ -101,14 +109,6 @@ static bool iommu_dt_device_is_assigned_locked(const
struct dt_device_node *dev)
return assigned;
}
-int iommu_dt_domain_init(struct domain *d)
-{
- INIT_LIST_HEAD(&dom_iommu(d)->dt_devices);
-
- return 0;
-}
-
-#ifdef CONFIG_MGMT_HYPERCALLS
int iommu_release_dt_devices(struct domain *d)
{
const struct domain_iommu *hd = dom_iommu(d);
@@ -212,51 +212,6 @@ int iommu_add_dt_pci_sideband_ids(struct pci_dev *pdev)
}
#endif /* CONFIG_HAS_PCI */
-int iommu_remove_dt_device(struct dt_device_node *np)
-{
- const struct iommu_ops *ops = iommu_get_ops();
- struct device *dev = dt_to_dev(np);
- int rc;
-
- ASSERT(rw_is_locked(&dt_host_lock));
-
- if ( !iommu_enabled )
- return 1;
-
- if ( !ops )
- return -EOPNOTSUPP;
-
- spin_lock(&dtdevs_lock);
-
- if ( iommu_dt_device_is_assigned_locked(np) )
- {
- rc = -EBUSY;
- goto fail;
- }
-
- if ( !ops->remove_device )
- {
- rc = -EOPNOTSUPP;
- goto fail;
- }
-
- /*
- * De-register the device from the IOMMU driver.
- * The driver is responsible for removing is_protected flag.
- */
- rc = ops->remove_device(0, dev);
-
- if ( !rc )
- {
- ASSERT(!dt_device_is_protected(np));
- iommu_fwspec_free(dev);
- }
-
- fail:
- spin_unlock(&dtdevs_lock);
- return rc;
-}
-
int iommu_add_dt_device(struct dt_device_node *np)
{
const struct iommu_ops *ops = iommu_get_ops();
@@ -320,6 +275,52 @@ int iommu_add_dt_device(struct dt_device_node *np)
return rc;
}
+#ifdef CONFIG_MGMT_HYPERCALLS
+int iommu_remove_dt_device(struct dt_device_node *np)
+{
+ const struct iommu_ops *ops = iommu_get_ops();
+ struct device *dev = dt_to_dev(np);
+ int rc;
+
+ ASSERT(rw_is_locked(&dt_host_lock));
+
+ if ( !iommu_enabled )
+ return 1;
+
+ if ( !ops )
+ return -EOPNOTSUPP;
+
+ spin_lock(&dtdevs_lock);
+
+ if ( iommu_dt_device_is_assigned_locked(np) )
+ {
+ rc = -EBUSY;
+ goto fail;
+ }
+
+ if ( !ops->remove_device )
+ {
+ rc = -EOPNOTSUPP;
+ goto fail;
+ }
+
+ /*
+ * De-register the device from the IOMMU driver.
+ * The driver is responsible for removing is_protected flag.
+ */
+ rc = ops->remove_device(0, dev);
+
+ if ( !rc )
+ {
+ ASSERT(!dt_device_is_protected(np));
+ iommu_fwspec_free(dev);
+ }
+
+ fail:
+ spin_unlock(&dtdevs_lock);
+ return rc;
+}
+
int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
{
@@ -431,3 +432,4 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct
domain *d,
return ret;
}
+#endif /* CONFIG_MGMT_HYPERCALLS */
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 83972d36b7..fba0de9d4b 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -431,9 +431,8 @@ static XSM_INLINE int cf_check xsm_deassign_device(
}
#endif /* CONFIG_HAS_PCI */
-#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
-#if defined(CONFIG_HAS_PASSTHROUGH) &&
defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
static XSM_INLINE int cf_check xsm_assign_dtdevice(
XSM_DEFAULT_ARG struct domain *d, const char *dtpath)
{
@@ -448,7 +447,8 @@ static XSM_INLINE int cf_check xsm_deassign_dtdevice(
return xsm_default_action(action, current->domain, d);
}
-#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
+#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
static XSM_INLINE int cf_check xsm_resource_plug_core(XSM_DEFAULT_VOID)
{
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index f2e92645ef..3bef1ec8ad 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -129,12 +129,12 @@ struct xsm_ops {
int (*assign_device)(struct domain *d, uint32_t machine_bdf);
int (*deassign_device)(struct domain *d, uint32_t machine_bdf);
#endif /* CONFIG_HAS_PCI */
-#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
-#if defined(CONFIG_HAS_PASSTHROUGH) &&
defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
int (*assign_dtdevice)(struct domain *d, const char *dtpath);
int (*deassign_dtdevice)(struct domain *d, const char *dtpath);
-#endif
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
+#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
int (*resource_plug_core)(void);
int (*resource_unplug_core)(void);
@@ -545,9 +545,8 @@ static inline int xsm_deassign_device(
return alternative_call(xsm_ops.deassign_device, d, machine_bdf);
}
#endif /* CONFIG_HAS_PCI */
-#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
-#if defined(CONFIG_HAS_PASSTHROUGH) &&
defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
static inline int xsm_assign_dtdevice(
xsm_default_t def, struct domain *d, const char *dtpath)
{
@@ -560,7 +559,8 @@ static inline int xsm_deassign_dtdevice(
return alternative_call(xsm_ops.deassign_dtdevice, d, dtpath);
}
-#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
+#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
static inline int xsm_resource_plug_pci(xsm_default_t def, uint32_t
machine_bdf)
{
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 0026a0963b..f624e90992 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -86,12 +86,12 @@ static const struct xsm_ops __initconst_cf_clobber
dummy_ops = {
.assign_device = xsm_assign_device,
.deassign_device = xsm_deassign_device,
#endif /* CONFIG_HAS_PCI */
-#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
-#if defined(CONFIG_HAS_PASSTHROUGH) &&
defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
.assign_dtdevice = xsm_assign_dtdevice,
.deassign_dtdevice = xsm_deassign_dtdevice,
-#endif
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
+#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
.resource_plug_core = xsm_resource_plug_core,
.resource_unplug_core = xsm_resource_unplug_core,
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 805a9a528e..4e67bc214a 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1461,9 +1461,8 @@ static int cf_check flask_deassign_device(
return avc_current_has_perm(rsid, SECCLASS_RESOURCE,
RESOURCE__REMOVE_DEVICE, NULL);
}
#endif /* CONFIG_HAS_PCI */
-#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
-#if defined(CONFIG_HAS_PASSTHROUGH) &&
defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
static int flask_test_assign_dtdevice(const char *dtpath)
{
uint32_t rsid;
@@ -1524,7 +1523,8 @@ static int cf_check flask_deassign_dtdevice(
return avc_current_has_perm(rsid, SECCLASS_RESOURCE,
RESOURCE__REMOVE_DEVICE,
NULL);
}
-#endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE_DISCOVERY */
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
+#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
static int cf_check flask_platform_op(uint32_t op)
{
@@ -1995,12 +1995,12 @@ static const struct xsm_ops __initconst_cf_clobber
flask_ops = {
.assign_device = flask_assign_device,
.deassign_device = flask_deassign_device,
#endif /* CONFIG_HAS_PCI */
-#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
-#if defined(CONFIG_HAS_PASSTHROUGH) &&
defined(CONFIG_HAS_DEVICE_TREE_DISCOVERY)
+#ifdef CONFIG_HAS_DEVICE_TREE_DISCOVERY
.assign_dtdevice = flask_assign_dtdevice,
.deassign_dtdevice = flask_deassign_dtdevice,
-#endif
+#endif /* CONFIG_HAS_DEVICE_TREE_DISCOVERY */
+#endif /* HAS_PASSTHROUGH && MGMT_HYPERCALLS */
.platform_op = flask_platform_op,
#ifdef CONFIG_X86
--
2.34.1