From 9609fecb5b97c3063873f892e2b6bbe868ce8bb6 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 4 Jun 2026 21:42:55 +0100 Subject: [PATCH] domctl: handle XEN_DOMCTL_get_device_group without acquiring domctl lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iommu_get_device_group() uses its own locking. Thus, with caller side locking irrelevant, it can as well be called with the domctl lock not held. Move the handling not only ahead of acquiring the lock, but also ahead of the XSM check, leveraging that the sub-op has its own hook. This is part of XSA-492. Signed-off-by: Jan Beulich Acked-by: Daniel P. Smith Reviewed-by: Roger Pau Monné (cherry picked from commit 471b377747cb5eb0ea7c1ca48ac9d38027a9aa13) --- xen/common/domctl.c | 5 ++++- xen/drivers/passthrough/pci.c | 4 ++-- xen/include/xsm/dummy.h | 3 ++- xen/xsm/flask/hooks.c | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/xen/common/domctl.c b/xen/common/domctl.c index c4dd88c353..f0dd5b595e 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -527,6 +527,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) /* Other sub-ops handled further down. */ break; + case XEN_DOMCTL_get_device_group: + ret = iommu_do_domctl(op, d, u_domctl); + goto domctl_out_unlock_domonly; + case XEN_DOMCTL_ioport_permission: case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_bind_pt_irq: @@ -949,7 +953,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) 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; diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index cfe2934a6e..1131950078 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -1513,7 +1513,7 @@ static int iommu_get_device_group( if ( (pdev->seg != seg) || ((b == bus) && (df == devfn)) ) continue; - if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (b << 8) | df) ) + if ( xsm_get_device_group(XSM_PRIV, (seg << 16) | (b << 8) | df) ) continue; sdev_id = iommu_call(ops, get_device_group_id, seg, b, df); @@ -1583,7 +1583,7 @@ int iommu_do_pci_domctl( u32 max_sdevs; XEN_GUEST_HANDLE_64(uint32) sdevs; - ret = xsm_get_device_group(XSM_HOOK, domctl->u.get_device_group.machine_sbdf); + ret = xsm_get_device_group(XSM_PRIV, domctl->u.get_device_group.machine_sbdf); if ( ret ) break; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index f532e01c48..3fb36887d6 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -162,6 +162,7 @@ static XSM_INLINE int cf_check xsm_domctl( { case XEN_DOMCTL_bind_pt_irq: case XEN_DOMCTL_getdomaininfo: + case XEN_DOMCTL_get_device_group: case XEN_DOMCTL_iomem_permission: case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_ioport_permission: @@ -399,7 +400,7 @@ static XSM_INLINE int cf_check xsm_get_vnumainfo( static XSM_INLINE int cf_check xsm_get_device_group( XSM_DEFAULT_ARG uint32_t machine_bdf) { - XSM_ASSERT_ACTION(XSM_HOOK); + XSM_ASSERT_ACTION(XSM_PRIV); return xsm_default_action(action, current->domain, NULL); } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 742a439bd6..33d6df7ff9 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -682,6 +682,7 @@ static int cf_check flask_domctl(struct domain *d, struct xen_domctl *op) /* These have individual XSM hooks and don't make it here. */ case XEN_DOMCTL_bind_pt_irq: case XEN_DOMCTL_getdomaininfo: + case XEN_DOMCTL_get_device_group: case XEN_DOMCTL_iomem_permission: case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_ioport_permission: @@ -699,7 +700,6 @@ static int cf_check flask_domctl(struct domain *d, struct xen_domctl *op) * These have individual XSM hooks * (drivers/passthrough/{pci,device_tree.c) */ - case XEN_DOMCTL_get_device_group: case XEN_DOMCTL_test_assign_device: case XEN_DOMCTL_assign_device: case XEN_DOMCTL_deassign_device: