[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 04/17] xen: Introduce XEN_DOMCTL_CDF_not_hypercall_target


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jason Andryuk <jason.andryuk@xxxxxxx>
  • Date: Wed, 16 Jul 2025 17:14:51 -0400
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ykb3PuSX5SAI+R8wxC7PVzFq5Z1MUVmxV7kUfgrRp3A=; b=xIPTjzkwo/V9xjJ7GWlJZynOcq9F9yLTtT35wh7TexcD+ywI5Ik3sKOQXbfF22OFMc+jLMp6GjjgHMHM0zkVK4f07trpI/9Dg7G2xfs8ME/3g7uhf9GE2Ci8tdsIJZBH7EpxEPVBoNNZnRG0u4H4eSpeZy21037LJ9Cn1krvzm3DxD4bI71hGKvduzy0xZ4ozkKGP4eri42JkitZLpeL+HRXOq98OynpIcy8EOkq0fcCnVPUNNav/3qpig0cqJ3l1y0b8VLJDYXLimr3vj3ot0f+HI1cYpIFoC+rRpNtgaCXO7Hn95I2PhMeBE6zO17hsP47Dz/ITRFXu3PhW8D2HQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=huGqY/1epyL8NEzdTlWX4aNcPjt94KOqAitBgHt7HIOnPl9Bxq3MASS+hjTMH82Mq3dnCM1PNaUypClE2Dty0FbepMXkq69ROykRq+Hdkhhf+AczeVO6DIqj9F39Eok24wLqrBPaGtq/MwsHqkmPf95D3WU66RGiyJW9cH/ItYGDHEkyTiIVLpfWw2k2s1HG00z6MiR5zItXtjojOfCQwl0V+1USSvsHGjhgSG+4oIcT2JynvXSy3BBACSHGs5xri6W0jxBJ+PzEgX1kRBJ0vf8fz12Xs/eUDGcI7rZJochkj4bRF0FiNbDfGZEkAUrIPX7STPhzs0NFhXKG8wsO/w==
  • Cc: Jason Andryuk <jason.andryuk@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, "Volodymyr Babchuk" <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, "Jan Beulich" <jbeulich@xxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Christian Lindig <christian.lindig@xxxxxxxxxx>, "David Scott" <dave@xxxxxxxxxx>, "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Wed, 16 Jul 2025 21:22:31 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Add a new create domain flag  to indicate if a domain can be the target
of hypercalls.  By default all domains can be targetted - subject to any
other permission checks.

This property is useful in a safety environment to isolate domains for
freedom from interference.

Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
DOMAIN_CAPS_NOT_HYPERCALL_TARGET duplicates the hypercall-untargetable
DT property, so it could be removed.  Leaving it here for now to at
least illustrate the alternate approach.
---
 docs/misc/arm/device-tree/booting.txt   |  6 ++++++
 tools/ocaml/libs/xc/xenctrl.ml          |  1 +
 tools/ocaml/libs/xc/xenctrl.mli         |  1 +
 xen/arch/arm/domain.c                   |  3 ++-
 xen/common/device-tree/dom0less-build.c |  6 ++++++
 xen/common/domain.c                     |  2 +-
 xen/include/public/bootfdt.h            | 10 ++++++++--
 xen/include/public/domctl.h             |  4 +++-
 xen/include/xen/sched.h                 | 12 ++++++++++++
 xen/include/xsm/dummy.h                 |  4 ++++
 10 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/docs/misc/arm/device-tree/booting.txt 
b/docs/misc/arm/device-tree/booting.txt
index 07acc7ba64..963dd81912 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -307,6 +307,12 @@ with the following properties:
     passed through. This option is the default if this property is missing
     and the user does not provide the device partial device tree for the 
domain.
 
+- hypercall-untargetable
+
+    Optional.  An empty property to specify the domain cannot be the target
+    of hypercalls.  This protects a domain for freedom of interference from
+    other domains.
+
 Under the "xen,domain" compatible node, one or more sub-nodes are present
 for the DomU kernel and ramdisk.
 
diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
index f5835e7d95..00c29199dc 100644
--- a/tools/ocaml/libs/xc/xenctrl.ml
+++ b/tools/ocaml/libs/xc/xenctrl.ml
@@ -72,6 +72,7 @@ type domain_create_flag =
   | CDF_VPMU
   | CDF_TRAP_UNMAPPED_ACCESSES
   | CDF_DEVICE_MODEL
+  | CDF_NOT_HYPERCALL_TARGET
 
 type domain_create_iommu_opts =
   | IOMMU_NO_SHAREPT
diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli
index b9471a56a8..daf6686f4d 100644
--- a/tools/ocaml/libs/xc/xenctrl.mli
+++ b/tools/ocaml/libs/xc/xenctrl.mli
@@ -65,6 +65,7 @@ type domain_create_flag =
   | CDF_VPMU
   | CDF_TRAP_UNMAPPED_ACCESSES
   | CDF_DEVICE_MODEL
+  | CDF_NOT_HYPERCALL_TARGET
 
 type domain_create_iommu_opts =
   | IOMMU_NO_SHAREPT
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 57eecbd250..5f6358096f 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -614,7 +614,8 @@ int arch_sanitise_domain_config(struct 
xen_domctl_createdomain *config)
     unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu |
                                    XEN_DOMCTL_CDF_xs_domain |
                                    XEN_DOMCTL_CDF_trap_unmapped_accesses |
-                                   XEN_DOMCTL_CDF_device_model);
+                                   XEN_DOMCTL_CDF_device_model |
+                                   XEN_DOMCTL_CDF_not_hypercall_target);
     unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl);
 
     if ( (config->flags & ~flags_optional) != flags_required )
diff --git a/xen/common/device-tree/dom0less-build.c 
b/xen/common/device-tree/dom0less-build.c
index bb52291dfb..22af043aa5 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -886,6 +886,9 @@ void __init create_domUs(void)
 
             if ( val & DOMAIN_CAPS_DEVICE_MODEL )
                 d_cfg.flags |= XEN_DOMCTL_CDF_device_model;
+
+            if ( val & DOMAIN_CAPS_NOT_HYPERCALL_TARGET )
+                d_cfg.flags |= XEN_DOMCTL_CDF_not_hypercall_target;
         }
 
         if ( dt_find_property(node, "xen,static-mem", NULL) )
@@ -896,6 +899,9 @@ void __init create_domUs(void)
             flags |= CDF_staticmem;
         }
 
+        if ( dt_property_read_bool(node, "hypercall-untargetable") )
+            d_cfg.flags |= XEN_DOMCTL_CDF_not_hypercall_target;
+
         if ( dt_property_read_bool(node, "direct-map") )
         {
             if ( !(flags & CDF_staticmem) )
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 42c590b8d7..c347de4335 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -723,7 +723,7 @@ static int sanitise_domain_config(struct 
xen_domctl_createdomain *config)
            XEN_DOMCTL_CDF_xs_domain | XEN_DOMCTL_CDF_iommu |
            XEN_DOMCTL_CDF_nested_virt | XEN_DOMCTL_CDF_vpmu |
            XEN_DOMCTL_CDF_trap_unmapped_accesses |
-           XEN_DOMCTL_CDF_device_model) )
+           XEN_DOMCTL_CDF_device_model | XEN_DOMCTL_CDF_not_hypercall_target) )
     {
         dprintk(XENLOG_INFO, "Unknown CDF flags %#x\n", config->flags);
         return -EINVAL;
diff --git a/xen/include/public/bootfdt.h b/xen/include/public/bootfdt.h
index c6b5afc76a..1eba1cc487 100644
--- a/xen/include/public/bootfdt.h
+++ b/xen/include/public/bootfdt.h
@@ -32,8 +32,14 @@
  * Hardware domain for running QEMU.
  */
 #define DOMAIN_CAPS_DEVICE_MODEL (1U << 3)
+/*
+ * Domain cannot be the target of hypercalls.  This provides the domain
+ * freedom from interference from other domains.
+ */
+#define DOMAIN_CAPS_NOT_HYPERCALL_TARGET (1U << 4)
 
-#define DOMAIN_CAPS_MASK     (DOMAIN_CAPS_CONTROL  | DOMAIN_CAPS_HARDWARE | \
-                              DOMAIN_CAPS_XENSTORE | DOMAIN_CAPS_DEVICE_MODEL )
+#define DOMAIN_CAPS_MASK    (DOMAIN_CAPS_CONTROL  | DOMAIN_CAPS_HARDWARE | \
+                             DOMAIN_CAPS_XENSTORE | DOMAIN_CAPS_DEVICE_MODEL | 
\
+                             DOMAIN_CAPS_NOT_HYPERCALL_TARGET)
 
 #endif /* __XEN_PUBLIC_BOOTFDT_H__ */
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 88a294c5be..f1f6f96bc2 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -70,9 +70,11 @@ struct xen_domctl_createdomain {
 #define XEN_DOMCTL_CDF_trap_unmapped_accesses  (1U << 8)
 /* Allow domain to provide device model for multiple other domains */
 #define XEN_DOMCTL_CDF_device_model   (1U << 9)
+/* Domain cannot be the target of hypercalls */
+#define XEN_DOMCTL_CDF_not_hypercall_target   (1U << 10)
 
 /* Max XEN_DOMCTL_CDF_* constant.  Used for ABI checking. */
-#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_device_model
+#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_not_hypercall_target
 
     uint32_t flags;
 
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 9863603d93..8a32f9a1b6 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -1157,6 +1157,18 @@ static always_inline bool is_dm_domain(const struct 
domain *d)
     return evaluate_nospec(d->options & XEN_DOMCTL_CDF_device_model);
 }
 
+/*
+ * Return whether this domain can be the target of hypercalls from other
+ * domains.
+ */
+static always_inline bool is_hypercall_target(const struct domain *d)
+{
+    if ( IS_ENABLED(CONFIG_PV_SHIM_EXCLUSIVE) )
+        return true;
+
+    return evaluate_nospec(!(d->options & 
XEN_DOMCTL_CDF_not_hypercall_target));
+}
+
 #define VM_ASSIST(d, t) (test_bit(VMASST_TYPE_ ## t, &(d)->vm_assist))
 
 static always_inline bool is_pv_domain(const struct domain *d)
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 0b341efd18..f2205575ed 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -91,12 +91,16 @@ static always_inline int xsm_default_action(
             return 0;
         fallthrough;
     case XSM_DM_PRIV:
+        if ( target && !is_hypercall_target(target) )
+            return -EPERM;
         if ( is_dm_domain(src) )
             return 0;
         if ( target && evaluate_nospec(src->target == target) )
             return 0;
         fallthrough;
     case XSM_PRIV:
+        if ( target && !is_hypercall_target(target) )
+            return -EPERM;
         if ( is_control_domain(src) )
             return 0;
         return -EPERM;
-- 
2.50.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.