[PATCH v2 20/26] xen/domctl: wrap iommu-related domctl op with CONFIG_MGMT_HYPERCALLS

Penny Zheng posted 26 patches 3 days, 22 hours ago
[PATCH v2 20/26] xen/domctl: wrap iommu-related domctl op with CONFIG_MGMT_HYPERCALLS
Posted by Penny Zheng 3 days, 22 hours ago
Function iommu_do_domctl() is the main entry for all 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:
- iommu_do_pci_domctl
  - iommu_get_device_group
    - amd_iommu_group_id/intel_iommu_group_id
  - device_assigned
  - assign_device
    - intel_iommu_assign_device/amd_iommu_assign_device
  - deassign_device
    - reassign_device_ownership/reassign_device
- iommu_do_dt_domctl
  - iommu_deassign_dt_device
    - arm_smmu_reassign_dev/arm_smmu_reassign_dev
    - ipmmu_reassign_dev
      - ipmmu_deassign_dev
        - ipmmu_detach_dev
  - dt_find_node_by_gpath
Wrap XEN_DOMCTL_assign_device{test_assign_device,deassign_device,
get_device_group}-case transiently with CONFIG_MGMT_HYPERCALLS,
and it will be removed when introducing CONFIG_MGMT_HYPERCALLS on the whole
domctl.c in the last.

Signed-off-by: Penny Zheng <Penny.Zheng@amd.com>
---
v1 -> v2:
- adapt to changes of "unify DOMCTL to MGMT_HYPERCALLS"
- wrap XEN_DOMCTL_assign_device{test_assign_device,deassign_device,
 get_device_group}-case transiently
---
 xen/common/device-tree/device-tree.c        | 2 ++
 xen/common/domctl.c                         | 2 ++
 xen/drivers/passthrough/amd/pci_amd_iommu.c | 8 ++++++++
 xen/drivers/passthrough/arm/ipmmu-vmsa.c    | 6 ++++++
 xen/drivers/passthrough/arm/smmu-v3.c       | 4 ++++
 xen/drivers/passthrough/arm/smmu.c          | 4 ++++
 xen/drivers/passthrough/device_tree.c       | 4 ++++
 xen/drivers/passthrough/iommu.c             | 2 ++
 xen/drivers/passthrough/pci.c               | 6 +++++-
 xen/drivers/passthrough/vtd/iommu.c         | 6 ++++++
 10 files changed, 43 insertions(+), 1 deletion(-)

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/common/domctl.c b/xen/common/domctl.c
index 736ad52265..d36885aeea 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -840,12 +840,14 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             copyback = 1;
         break;
 
+#ifdef CONFIG_MGMT_HYPERCALLS
     case XEN_DOMCTL_assign_device:
     case XEN_DOMCTL_test_assign_device:
     case XEN_DOMCTL_deassign_device:
     case XEN_DOMCTL_get_device_group:
         ret = iommu_do_domctl(op, d, u_domctl);
         break;
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
     case XEN_DOMCTL_get_paging_mempool_size:
         ret = arch_get_paging_mempool_size(d, &op->u.paging_mempool.size);
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index 3a14770855..5786bf0c59 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -461,6 +461,7 @@ static void amd_iommu_disable_domain_device(const struct domain *domain,
         spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static int cf_check reassign_device(
     struct domain *source, struct domain *target, u8 devfn,
     struct pci_dev *pdev)
@@ -550,6 +551,7 @@ static int cf_check amd_iommu_assign_device(
 
     return rc;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 static void cf_check amd_iommu_clear_root_pgtable(struct domain *d)
 {
@@ -698,12 +700,14 @@ static int cf_check amd_iommu_remove_device(u8 devfn, struct pci_dev *pdev)
     return 0;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static int cf_check amd_iommu_group_id(u16 seg, u8 bus, u8 devfn)
 {
     unsigned int bdf = PCI_BDF(bus, devfn);
 
     return (bdf < ivrs_bdf_entries) ? get_dma_requestor_id(seg, bdf) : bdf;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 #include <asm/io_apic.h>
 
@@ -772,14 +776,18 @@ static const struct iommu_ops __initconst_cf_clobber _iommu_ops = {
     .quarantine_init = amd_iommu_quarantine_init,
     .add_device = amd_iommu_add_device,
     .remove_device = amd_iommu_remove_device,
+#ifdef CONFIG_MGMT_HYPERCALLS
     .assign_device  = amd_iommu_assign_device,
+#endif
     .teardown = amd_iommu_domain_destroy,
     .clear_root_pgtable = amd_iommu_clear_root_pgtable,
     .map_page = amd_iommu_map_page,
     .unmap_page = amd_iommu_unmap_page,
     .iotlb_flush = amd_iommu_flush_iotlb_pages,
+#ifdef CONFIG_MGMT_HYPERCALLS
     .reassign_device = reassign_device,
     .get_device_group_id = amd_iommu_group_id,
+#endif
     .enable_x2apic = iov_enable_xt,
     .update_ire_from_apic = amd_iommu_ioapic_update_ire,
     .update_ire_from_msi = amd_iommu_msi_msg_update_ire,
diff --git a/xen/drivers/passthrough/arm/ipmmu-vmsa.c b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
index ea9fa9ddf3..ec85b2fbdd 100644
--- a/xen/drivers/passthrough/arm/ipmmu-vmsa.c
+++ b/xen/drivers/passthrough/arm/ipmmu-vmsa.c
@@ -739,6 +739,7 @@ static int ipmmu_attach_device(struct ipmmu_vmsa_domain *domain,
     return 0;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static void ipmmu_detach_device(struct ipmmu_vmsa_domain *domain,
                                 struct device *dev)
 {
@@ -748,6 +749,7 @@ static void ipmmu_detach_device(struct ipmmu_vmsa_domain *domain,
     for ( i = 0; i < fwspec->num_ids; ++i )
         ipmmu_utlb_disable(domain, fwspec->ids[i]);
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 static int ipmmu_init_platform_device(struct device *dev,
                                       const struct dt_phandle_args *args)
@@ -1254,6 +1256,7 @@ out:
     return ret;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 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..49cd37ff57 100644
--- a/xen/drivers/passthrough/arm/smmu-v3.c
+++ b/xen/drivers/passthrough/arm/smmu-v3.c
@@ -2799,6 +2799,7 @@ static int arm_smmu_deassign_dev(struct domain *d, uint8_t devfn, struct device
 	return 0;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
 				u8 devfn,  struct device *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..b7f01fbf89 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -2891,6 +2891,7 @@ static int arm_smmu_deassign_dev(struct domain *d, uint8_t devfn,
 	return 0;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static int arm_smmu_reassign_dev(struct domain *s, struct domain *t,
 				 u8 devfn,  struct device *dev)
 {
@@ -2918,6 +2919,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 +2958,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..5c2122ba9f 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -59,6 +59,7 @@ fail:
     return rc;
 }
 
+#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);
@@ -86,6 +87,7 @@ fail:
 
     return rc;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 static bool iommu_dt_device_is_assigned_locked(const struct dt_device_node *dev)
 {
@@ -320,6 +322,7 @@ int iommu_add_dt_device(struct dt_device_node *np)
     return rc;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
                        XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
 {
@@ -431,3 +434,4 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
 
     return ret;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index c9425d6971..8812e38174 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -625,6 +625,7 @@ void iommu_resume(void)
         iommu_vcall(iommu_get_ops(), resume);
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 int iommu_do_domctl(
     struct xen_domctl *domctl, struct domain *d,
     XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
@@ -645,6 +646,7 @@ int iommu_do_domctl(
 
     return ret;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 void iommu_crash_shutdown(void)
 {
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index cd855108c2..aa07a7e748 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -877,6 +877,7 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
     return ret;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 /* Caller should hold the pcidevs_lock */
 static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus,
                            uint8_t devfn)
@@ -945,7 +946,6 @@ static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus,
     return ret;
 }
 
-#ifdef CONFIG_MGMT_HYPERCALLS
 int pci_release_devices(struct domain *d)
 {
     int combined_ret;
@@ -1483,6 +1483,7 @@ static int iommu_remove_device(struct pci_dev *pdev)
     return iommu_call(hd->platform_ops, remove_device, devfn, pci_to_dev(pdev));
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static int device_assigned(u16 seg, u8 bus, u8 devfn)
 {
     struct pci_dev *pdev;
@@ -1646,6 +1647,7 @@ static int iommu_get_device_group(
 
     return i;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev)
 {
@@ -1671,6 +1673,7 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, struct pci_dev *pdev)
     pcidevs_unlock();
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 int iommu_do_pci_domctl(
     struct xen_domctl *domctl, struct domain *d,
     XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
@@ -1804,6 +1807,7 @@ int iommu_do_pci_domctl(
 
     return ret;
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 struct segment_iter {
     int (*handler)(struct pci_dev *pdev, void *arg);
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index b4105163cc..8913dd4d5f 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -2731,6 +2731,7 @@ static int __init cf_check vtd_setup(void)
     return ret;
 }
 
+#ifdef CONFIG_MGMT_HYPERCALLS
 static int cf_check reassign_device_ownership(
     struct domain *source,
     struct domain *target,
@@ -2926,6 +2927,7 @@ static int cf_check intel_iommu_group_id(u16 seg, u8 bus, u8 devfn)
 
     return PCI_BDF(bus, devfn);
 }
+#endif /* CONFIG_MGMT_HYPERCALLS */
 
 static int __must_check cf_check vtd_suspend(void)
 {
@@ -3234,14 +3236,18 @@ static const struct iommu_ops __initconst_cf_clobber vtd_ops = {
     .add_device = intel_iommu_add_device,
     .enable_device = intel_iommu_enable_device,
     .remove_device = intel_iommu_remove_device,
+#ifdef CONFIG_MGMT_HYPERCALLS
     .assign_device  = intel_iommu_assign_device,
+#endif
     .teardown = iommu_domain_teardown,
     .clear_root_pgtable = iommu_clear_root_pgtable,
     .map_page = intel_iommu_map_page,
     .unmap_page = intel_iommu_unmap_page,
     .lookup_page = intel_iommu_lookup_page,
+#ifdef CONFIG_MGMT_HYPERCALLS
     .reassign_device = reassign_device_ownership,
     .get_device_group_id = intel_iommu_group_id,
+#endif
     .enable_x2apic = intel_iommu_enable_eim,
     .disable_x2apic = intel_iommu_disable_eim,
     .update_ire_from_apic = io_apic_write_remap_rte,
-- 
2.34.1
Re: [PATCH v2 20/26] xen/domctl: wrap iommu-related domctl op with CONFIG_MGMT_HYPERCALLS
Posted by Jan Beulich 2 days, 18 hours ago
On 10.09.2025 09:38, Penny Zheng wrote:
> Function iommu_do_domctl() is the main entry for all 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:
> - iommu_do_pci_domctl
>   - iommu_get_device_group
>     - amd_iommu_group_id/intel_iommu_group_id
>   - device_assigned
>   - assign_device
>     - intel_iommu_assign_device/amd_iommu_assign_device
>   - deassign_device
>     - reassign_device_ownership/reassign_device
> - iommu_do_dt_domctl
>   - iommu_deassign_dt_device
>     - arm_smmu_reassign_dev/arm_smmu_reassign_dev
>     - ipmmu_reassign_dev
>       - ipmmu_deassign_dev
>         - ipmmu_detach_dev
>   - dt_find_node_by_gpath
> Wrap XEN_DOMCTL_assign_device{test_assign_device,deassign_device,
> get_device_group}-case transiently with CONFIG_MGMT_HYPERCALLS,
> and it will be removed when introducing CONFIG_MGMT_HYPERCALLS on the whole
> domctl.c in the last.
> 
> Signed-off-by: Penny Zheng <Penny.Zheng@amd.com>

Apart from all of the above another aspect becomes apparent here: Some code is
called at boot time only once management hypercalls are compiled out. Such
code should then move to .init.text, so we may need to gain something like
__init_or_mgmt. Imo that would want dealing with right here, but I can imagine
opinions to differ on this.

Furthermore, while looking around, I noticed that there's dt_overlay_sysctl(),
entirely unguarded despite the earlier sysctl series. Yet if that work (and
Misra checking) assumed OVERLAY_DTB=n, then there's iommu_remove_dt_device()
which is only used when OVERLAY_DTB=y.

Jan
Re: [PATCH v2 20/26] xen/domctl: wrap iommu-related domctl op with CONFIG_MGMT_HYPERCALLS
Posted by Stefano Stabellini 3 days, 3 hours ago
On Wed, 10 Sep 2025, Penny Zheng wrote:
> Function iommu_do_domctl() is the main entry for all 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:
> - iommu_do_pci_domctl
>   - iommu_get_device_group
>     - amd_iommu_group_id/intel_iommu_group_id
>   - device_assigned
>   - assign_device
>     - intel_iommu_assign_device/amd_iommu_assign_device
>   - deassign_device
>     - reassign_device_ownership/reassign_device
> - iommu_do_dt_domctl
>   - iommu_deassign_dt_device
>     - arm_smmu_reassign_dev/arm_smmu_reassign_dev
>     - ipmmu_reassign_dev
>       - ipmmu_deassign_dev
>         - ipmmu_detach_dev
>   - dt_find_node_by_gpath
> Wrap XEN_DOMCTL_assign_device{test_assign_device,deassign_device,
> get_device_group}-case transiently with CONFIG_MGMT_HYPERCALLS,
> and it will be removed when introducing CONFIG_MGMT_HYPERCALLS on the whole
> domctl.c in the last.
> 
> Signed-off-by: Penny Zheng <Penny.Zheng@amd.com>

drivers/passthrough/arm/smmu.c:2852:12: error: ‘arm_smmu_deassign_dev’ defined but not used [-Werror=unused-function]
 2852 | static int arm_smmu_deassign_dev(struct domain *d, uint8_t devfn,
      |            ^~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors