|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.18] domctl: handle XEN_DOMCTL_io{mem,port}_permission without acquiring domctl lock
commit c76ed41837259c481945fcf153136f7f3128ff0b
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jun 4 21:41:59 2026 +0100
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Thu Jun 4 22:29:01 2026 +0100
domctl: handle XEN_DOMCTL_io{mem,port}_permission without acquiring domctl
lock
With dedicated locking added, the domctl lock isn't required here anymore.
As the I/O port handling is in arch-specific code (x86 only), no code is
being moved, but the 2nd invocation of arch_do_domctl() is re-used. Move
the re-purposed dedicated XSM checks as early as possible.
This is part of XSA-492.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Acked-by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
(cherry picked from commit 9f54e10bf3ab02c8d5dc3253d85c9b3258d1fc88)
---
xen/arch/x86/domctl.c | 13 ++++++++----
xen/common/domctl.c | 54 ++++++++++++++++++++++++++-----------------------
xen/include/xsm/dummy.h | 6 ++++--
xen/xsm/flask/hooks.c | 4 ++--
4 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 91f407af98..cc956a354c 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -225,12 +225,17 @@ long arch_do_domctl(
unsigned int np = domctl->u.ioport_permission.nr_ports;
int allow = domctl->u.ioport_permission.allow_access;
+ ret = -EINVAL;
+ if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
+ break;
+
+ ret = xsm_ioport_permission(XSM_PRIV, d, fp, fp + np - 1, allow);
+ if ( ret )
+ break;
+
iocaps_double_lock(d, true);
- if ( (fp + np) <= fp || (fp + np) > MAX_IOPORTS )
- ret = -EINVAL;
- else if ( !ioports_access_permitted(currd, fp, fp + np - 1) ||
- xsm_ioport_permission(XSM_HOOK, d, fp, fp + np - 1, allow) )
+ if ( !ioports_access_permitted(currd, fp, fp + np - 1) )
ret = -EPERM;
else if ( allow )
ret = ioports_permit_access(d, fp, fp + np - 1);
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 08a844fe25..1072d78f35 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -362,6 +362,34 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
goto domctl_out_unlock_domonly;
+ case XEN_DOMCTL_iomem_permission:
+ {
+ unsigned long mfn = op->u.iomem_permission.first_mfn;
+ unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
+ bool allow = op->u.iomem_permission.allow_access;
+
+ ret = -EINVAL;
+ if ( (mfn + nr_mfns - 1) < mfn ) /* Wrap? */
+ goto domctl_out_unlock_domonly;
+
+ ret = xsm_iomem_permission(XSM_PRIV, d, mfn, mfn + nr_mfns - 1, allow);
+ if ( ret )
+ goto domctl_out_unlock_domonly;
+
+ iocaps_double_lock(d, true);
+
+ if ( !iomem_access_permitted(current->domain,
+ mfn, mfn + nr_mfns - 1) )
+ ret = -EPERM;
+ else if ( allow )
+ ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
+ else
+ ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
+
+ iocaps_double_unlock(d, true);
+ goto domctl_out_unlock_domonly;
+ }
+
case XEN_DOMCTL_memory_mapping:
{
unsigned long gfn = op->u.memory_mapping.first_gfn;
@@ -422,6 +450,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
goto domctl_out_unlock_domonly;
}
+ case XEN_DOMCTL_ioport_permission:
case XEN_DOMCTL_ioport_mapping:
case XEN_DOMCTL_bind_pt_irq:
case XEN_DOMCTL_unbind_pt_irq:
@@ -779,31 +808,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t)
u_domctl)
break;
}
- case XEN_DOMCTL_iomem_permission:
- {
- unsigned long mfn = op->u.iomem_permission.first_mfn;
- unsigned long nr_mfns = op->u.iomem_permission.nr_mfns;
- int allow = op->u.iomem_permission.allow_access;
-
- ret = -EINVAL;
- if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */
- break;
-
- iocaps_double_lock(d, true);
-
- if ( !iomem_access_permitted(current->domain,
- mfn, mfn + nr_mfns - 1) ||
- xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) )
- ret = -EPERM;
- else if ( allow )
- ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
- else
- ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
-
- iocaps_double_unlock(d, true);
- break;
- }
-
case XEN_DOMCTL_settimeoffset:
domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
break;
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 7fc106c536..9a65f31c51 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -169,7 +169,9 @@ static XSM_INLINE int cf_check xsm_domctl(
{
case XEN_DOMCTL_bind_pt_irq:
case XEN_DOMCTL_getdomaininfo:
+ case XEN_DOMCTL_iomem_permission:
case XEN_DOMCTL_ioport_mapping:
+ case XEN_DOMCTL_ioport_permission:
case XEN_DOMCTL_memory_mapping:
case XEN_DOMCTL_unbind_pt_irq:
ASSERT_UNREACHABLE();
@@ -566,7 +568,7 @@ static XSM_INLINE int cf_check xsm_irq_permission(
static XSM_INLINE int cf_check xsm_iomem_permission(
XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow)
{
- XSM_ASSERT_ACTION(XSM_HOOK);
+ XSM_ASSERT_ACTION(XSM_PRIV);
return xsm_default_action(action, current->domain, d);
}
@@ -762,7 +764,7 @@ static XSM_INLINE int cf_check xsm_priv_mapping(
static XSM_INLINE int cf_check xsm_ioport_permission(
XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
{
- XSM_ASSERT_ACTION(XSM_HOOK);
+ XSM_ASSERT_ACTION(XSM_PRIV);
return xsm_default_action(action, current->domain, d);
}
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 87dee85ea6..949a4a4878 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -681,7 +681,9 @@ static int cf_check flask_domctl(struct domain *d, unsigned
int cmd,
/* These have individual XSM hooks and don't make it here. */
case XEN_DOMCTL_bind_pt_irq:
case XEN_DOMCTL_getdomaininfo:
+ case XEN_DOMCTL_iomem_permission:
case XEN_DOMCTL_ioport_mapping:
+ case XEN_DOMCTL_ioport_permission:
case XEN_DOMCTL_memory_mapping:
case XEN_DOMCTL_unbind_pt_irq:
ASSERT_UNREACHABLE();
@@ -690,14 +692,12 @@ static int cf_check flask_domctl(struct domain *d,
unsigned int cmd,
/* These have individual XSM hooks (common/domctl.c) */
case XEN_DOMCTL_scheduler_op:
case XEN_DOMCTL_irq_permission:
- case XEN_DOMCTL_iomem_permission:
case XEN_DOMCTL_set_target:
case XEN_DOMCTL_vm_event_op:
#ifdef CONFIG_X86
/* These have individual XSM hooks (arch/x86/domctl.c) */
case XEN_DOMCTL_shadow_op:
- case XEN_DOMCTL_ioport_permission:
#endif
#ifdef CONFIG_HAS_PASSTHROUGH
/*
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.18
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |