* [PATCH v17 1/4] xen/domain: unify domain ID allocation
2025-08-29 23:21 [PATCH v17 0/4] xen/domain: domain ID allocation dmukhin
@ 2025-08-29 23:21 ` dmukhin
2025-08-29 23:21 ` [PATCH v17 2/4] tools/include: move xc_bitops.h to xen-tools/bitops.h dmukhin
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: dmukhin @ 2025-08-29 23:21 UTC (permalink / raw)
To: xen-devel
Cc: andrew.cooper3, anthony.perard, jbeulich, julien, michal.orzel,
roger.pau, sstabellini, dmukhin, Julien Grall, Alejandro Vallejo
From: Denis Mukhin <dmukhin@ford.com>
Currently, there are two different domain ID allocation implementations:
1) Sequential IDs allocation in dom0less Arm code based on max_init_domid;
2) Sequential IDs allocation in XEN_DOMCTL_createdomain; does not use
max_init_domid (both Arm and x86).
The domain ID allocation covers dom0 or late hwdom, predefined domains,
post-boot domains, excluding Xen system domains (domid >=
DOMID_FIRST_RESERVED).
It makes sense to have a common helper code for such task across architectures
(Arm and x86) and between dom0less / toolstack domU allocation.
Note, fixing dependency on max_init_domid is out of scope of this patch.
Wrap the domain ID allocation as an arch-independent function domid_alloc() in
new common/domid.c based on the bitmap.
Allocation algorithm:
- If an explicit domain ID is provided, verify its availability and use it if
ID is not used;
- If DOMID_INVALID is provided, search the range [1..DOMID_FIRST_RESERVED-1],
starting from the last used ID.
Implementation guarantees that two consecutive calls will never return the
same ID. ID#0 is reserved for the first boot domain (currently, dom0) and
excluded from the allocation range.
Remove is_free_domid() helper as it is not needed now.
No functional change intended.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
---
Changes since v16:
- n/a
- kept existing R-bs
---
xen/arch/arm/domain_build.c | 7 +-
xen/arch/x86/setup.c | 7 +-
xen/common/Makefile | 1 +
xen/common/device-tree/dom0less-build.c | 15 ++--
xen/common/domain.c | 2 +
xen/common/domctl.c | 43 ++---------
xen/common/domid.c | 95 +++++++++++++++++++++++++
xen/include/xen/domain.h | 3 +
8 files changed, 126 insertions(+), 47 deletions(-)
create mode 100644 xen/common/domid.c
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index a9e4153e3cf9..aca35b8961d6 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -2050,6 +2050,7 @@ void __init create_dom0(void)
.grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version),
};
unsigned int flags = CDF_privileged | CDF_hardware;
+ domid_t domid;
int rc;
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
@@ -2074,7 +2075,11 @@ void __init create_dom0(void)
if ( !llc_coloring_enabled )
flags |= CDF_directmap;
- dom0 = domain_create(0, &dom0_cfg, flags);
+ domid = domid_alloc(0);
+ if ( domid == DOMID_INVALID )
+ panic("Error allocating domain ID 0\n");
+
+ dom0 = domain_create(domid, &dom0_cfg, flags);
if ( IS_ERR(dom0) )
panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 6c81841426a4..78e24b78c5a6 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1038,8 +1038,11 @@ static struct domain *__init create_dom0(struct boot_info *bi)
if ( iommu_enabled )
dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
- /* Create initial domain. Not d0 for pvshim. */
- bd->domid = get_initial_domain_id();
+ /* Allocate initial domain ID. Not d0 for pvshim. */
+ bd->domid = domid_alloc(get_initial_domain_id());
+ if ( bd->domid == DOMID_INVALID )
+ panic("Error allocating domain ID %u\n", get_initial_domain_id());
+
d = domain_create(bd->domid, &dom0_cfg,
pv_shim ? 0 : CDF_privileged | CDF_hardware);
if ( IS_ERR(d) )
diff --git a/xen/common/Makefile b/xen/common/Makefile
index c316957fcb36..0c7d0f5d46e1 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -11,6 +11,7 @@ obj-$(filter-out $(CONFIG_X86),$(CONFIG_ACPI)) += device.o
obj-$(CONFIG_DEVICE_TREE_PARSE) += device-tree/
obj-$(CONFIG_IOREQ_SERVER) += dm.o
obj-y += domain.o
+obj-y += domid.o
obj-y += event_2l.o
obj-y += event_channel.o
obj-$(CONFIG_EVTCHN_FIFO) += event_fifo.o
diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
index badc227031eb..8ef5ae9c0912 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -834,6 +834,7 @@ void __init create_domUs(void)
{
struct kernel_info ki = KERNEL_INFO_INIT;
int rc = parse_dom0less_node(node, &ki.bd);
+ domid_t domid;
if ( rc == -ENOENT )
continue;
@@ -843,13 +844,13 @@ void __init create_domUs(void)
if ( (max_init_domid + 1) >= DOMID_FIRST_RESERVED )
panic("No more domain IDs available\n");
- /*
- * The variable max_init_domid is initialized with zero, so here it's
- * very important to use the pre-increment operator to call
- * domain_create() with a domid > 0. (domid == 0 is reserved for Dom0)
- */
- ki.bd.d = domain_create(++max_init_domid,
- &ki.bd.create_cfg, ki.bd.create_flags);
+ domid = domid_alloc(DOMID_INVALID);
+ if ( domid == DOMID_INVALID )
+ panic("Error allocating ID for domain %s\n", dt_node_name(node));
+
+ max_init_domid = max(max_init_domid, domid);
+
+ ki.bd.d = domain_create(domid, &ki.bd.create_cfg, ki.bd.create_flags);
if ( IS_ERR(ki.bd.d) )
panic("Error creating domain %s (rc = %ld)\n",
dt_node_name(node), PTR_ERR(ki.bd.d));
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 104e917f07e3..775c33928585 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -692,6 +692,8 @@ static void _domain_destroy(struct domain *d)
lock_profile_deregister_struct(LOCKPROF_TYPE_PERDOM, d);
+ domid_free(d->domain_id);
+
free_domain_struct(d);
}
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index f2a7caaf853c..71e712c1f316 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -51,20 +51,6 @@ static int xenctl_bitmap_to_nodemask(nodemask_t *nodemask,
MAX_NUMNODES);
}
-static inline int is_free_domid(domid_t dom)
-{
- struct domain *d;
-
- if ( dom >= DOMID_FIRST_RESERVED )
- return 0;
-
- if ( (d = rcu_lock_domain_by_id(dom)) == NULL )
- return 1;
-
- rcu_unlock_domain(d);
- return 0;
-}
-
void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info)
{
struct vcpu *v;
@@ -423,36 +409,19 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
case XEN_DOMCTL_createdomain:
{
- domid_t dom;
- static domid_t rover = 0;
+ /* NB: ID#0 is reserved, find the first suitable ID instead. */
+ domid_t domid = domid_alloc(op->domain ?: DOMID_INVALID);
- dom = op->domain;
- if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
+ if ( domid == DOMID_INVALID )
{
ret = -EEXIST;
- if ( !is_free_domid(dom) )
- break;
- }
- else
- {
- for ( dom = rover + 1; dom != rover; dom++ )
- {
- if ( dom == DOMID_FIRST_RESERVED )
- dom = 1;
- if ( is_free_domid(dom) )
- break;
- }
-
- ret = -ENOMEM;
- if ( dom == rover )
- break;
-
- rover = dom;
+ break;
}
- d = domain_create(dom, &op->u.createdomain, false);
+ d = domain_create(domid, &op->u.createdomain, false);
if ( IS_ERR(d) )
{
+ domid_free(domid);
ret = PTR_ERR(d);
d = NULL;
break;
diff --git a/xen/common/domid.c b/xen/common/domid.c
new file mode 100644
index 000000000000..2387ddb08300
--- /dev/null
+++ b/xen/common/domid.c
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Domain ID allocator.
+ *
+ * Covers dom0 or late hwdom, predefined domains, post-boot domains.
+ * Excludes system domains (ID >= DOMID_FIRST_RESERVED).
+ *
+ * Copyright 2025 Ford Motor Company
+ */
+
+#include <xen/domain.h>
+
+static DEFINE_SPINLOCK(domid_lock);
+static DECLARE_BITMAP(domid_bitmap, DOMID_FIRST_RESERVED);
+
+/*
+ * Allocate domain ID.
+ *
+ * @param domid Domain ID hint:
+ * - If an explicit domain ID is provided, verify its availability and use it
+ * if ID is not used;
+ * - If DOMID_INVALID is provided, search [1..DOMID_FIRST_RESERVED-1] range,
+ * starting from the last used ID. Implementation guarantees that two
+ * consecutive calls will never return the same ID. ID#0 is reserved for
+ * the first boot domain (currently, dom0) and excluded from the allocation
+ * range.
+ * @return Valid domain ID in case of successful allocation,
+ * DOMID_INVALID - otherwise.
+ */
+domid_t domid_alloc(domid_t domid)
+{
+ static domid_t domid_last;
+
+ spin_lock(&domid_lock);
+
+ /* Exact match. */
+ if ( domid < DOMID_FIRST_RESERVED )
+ {
+ if ( __test_and_set_bit(domid, domid_bitmap) )
+ domid = DOMID_INVALID;
+ }
+ /*
+ * Exhaustive search.
+ *
+ * Domain ID#0 is reserved for the first boot domain (e.g. control domain)
+ * and excluded from allocation.
+ */
+ else
+ {
+ domid_t bound = DOMID_FIRST_RESERVED;
+
+ domid = find_next_zero_bit(domid_bitmap, bound, domid_last + 1);
+ if ( domid >= bound && domid_last != 0 )
+ {
+ bound = domid_last + 1;
+ domid = find_next_zero_bit(domid_bitmap, bound, 1);
+ }
+
+ ASSERT(domid <= DOMID_FIRST_RESERVED);
+ if ( domid < bound )
+ {
+ __set_bit(domid, domid_bitmap);
+ domid_last = domid;
+ }
+ else
+ domid = DOMID_INVALID;
+ }
+
+ spin_unlock(&domid_lock);
+
+ return domid;
+}
+
+void domid_free(domid_t domid)
+{
+ int rc;
+
+ ASSERT(domid <= DOMID_FIRST_RESERVED);
+
+ spin_lock(&domid_lock);
+ rc = __test_and_clear_bit(domid, domid_bitmap);
+ spin_unlock(&domid_lock);
+
+ ASSERT(rc);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index e10baf2615fd..8aab05ae93c8 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -38,6 +38,9 @@ void arch_get_domain_info(const struct domain *d,
domid_t get_initial_domain_id(void);
+domid_t domid_alloc(domid_t domid);
+void domid_free(domid_t domid);
+
/* CDF_* constant. Internal flags for domain creation. */
/* Is this a privileged domain? */
#define CDF_privileged (1U << 0)
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v17 2/4] tools/include: move xc_bitops.h to xen-tools/bitops.h
2025-08-29 23:21 [PATCH v17 0/4] xen/domain: domain ID allocation dmukhin
2025-08-29 23:21 ` [PATCH v17 1/4] xen/domain: unify " dmukhin
@ 2025-08-29 23:21 ` dmukhin
2025-08-29 23:21 ` [PATCH v17 3/4] tools/tests: introduce unit tests for domain ID allocator dmukhin
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: dmukhin @ 2025-08-29 23:21 UTC (permalink / raw)
To: xen-devel
Cc: andrew.cooper3, anthony.perard, jbeulich, julien, michal.orzel,
roger.pau, sstabellini, dmukhin
From: Denis Mukhin <dmukhin@ford.com>
Move xc_bitops.h to common tools location to be shared between
the toolstack and unit test code.
Adjust the guard in xen-tools/bitops.h
Correct the #include directives and comments referring to the old
xc_bitops.h in the toolstack code.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
Acked-by: Anthony PERARD <anthony.perard@vates.tech>
---
Changes since v16:
- dropped unneeded includes
- added Anthony's A-b
---
.../ctrl/xc_bitops.h => include/xen-tools/bitops.h} | 6 +++---
tools/libs/ctrl/xc_misc.c | 13 +++++++------
tools/libs/guest/xg_dom_elfloader.c | 1 -
tools/libs/guest/xg_dom_hvmloader.c | 1 -
tools/libs/guest/xg_private.h | 2 +-
tools/libs/guest/xg_sr_common.h | 2 --
6 files changed, 11 insertions(+), 14 deletions(-)
rename tools/{libs/ctrl/xc_bitops.h => include/xen-tools/bitops.h} (95%)
diff --git a/tools/libs/ctrl/xc_bitops.h b/tools/include/xen-tools/bitops.h
similarity index 95%
rename from tools/libs/ctrl/xc_bitops.h
rename to tools/include/xen-tools/bitops.h
index 4a776dc3a57f..681482f6759f 100644
--- a/tools/libs/ctrl/xc_bitops.h
+++ b/tools/include/xen-tools/bitops.h
@@ -1,5 +1,5 @@
-#ifndef XC_BITOPS_H
-#define XC_BITOPS_H 1
+#ifndef __XEN_TOOLS_BITOPS_H__
+#define __XEN_TOOLS_BITOPS_H__
/* bitmap operations for single threaded access */
@@ -81,4 +81,4 @@ static inline void bitmap_or(void *_dst, const void *_other,
dst[i] |= other[i];
}
-#endif /* XC_BITOPS_H */
+#endif /* __XEN_TOOLS_BITOPS_H__ */
diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c
index 33e87bac2868..10ddf85667a9 100644
--- a/tools/libs/ctrl/xc_misc.c
+++ b/tools/libs/ctrl/xc_misc.c
@@ -17,8 +17,8 @@
* License along with this library; If not, see <http://www.gnu.org/licenses/>.
*/
-#include "xc_bitops.h"
#include "xc_private.h"
+#include <xen-tools/bitops.h>
#include <xen/hvm/hvm_op.h>
int xc_get_max_cpus(xc_interface *xch)
@@ -94,11 +94,12 @@ xc_cpumap_t xc_cpumap_alloc(xc_interface *xch)
}
/*
- * xc_bitops.h has macros that do this as well - however they assume that
- * the bitmask is word aligned but xc_cpumap_t is only guaranteed to be
- * byte aligned and so we need byte versions for architectures which do
- * not support misaligned accesses (which is basically everyone
- * but x86, although even on x86 it can be inefficient).
+ * <xen-tools/bitops.h> has macros that do this as well - however they
+ * assume that the bitmask is word aligned but xc_cpumap_t is only
+ * guaranteed to be byte aligned and so we need byte versions for
+ * architectures which do not support misaligned accesses (which is
+ * basically everyone but x86, although even on x86 it can be
+ * inefficient).
*
* NOTE: The xc_bitops macros now use byte alignment.
* TODO: Clean up the users of this interface.
diff --git a/tools/libs/guest/xg_dom_elfloader.c b/tools/libs/guest/xg_dom_elfloader.c
index f17930d98bf7..a55b5e8c3caf 100644
--- a/tools/libs/guest/xg_dom_elfloader.c
+++ b/tools/libs/guest/xg_dom_elfloader.c
@@ -26,7 +26,6 @@
#include <inttypes.h>
#include "xg_private.h"
-#include "xc_bitops.h"
#define XEN_VER "xen-3.0"
diff --git a/tools/libs/guest/xg_dom_hvmloader.c b/tools/libs/guest/xg_dom_hvmloader.c
index 39e1e5f579a7..a98c7fe5d877 100644
--- a/tools/libs/guest/xg_dom_hvmloader.c
+++ b/tools/libs/guest/xg_dom_hvmloader.c
@@ -25,7 +25,6 @@
#include <assert.h>
#include "xg_private.h"
-#include "xc_bitops.h"
/* ------------------------------------------------------------------------ */
/* parse elf binary */
diff --git a/tools/libs/guest/xg_private.h b/tools/libs/guest/xg_private.h
index d73947094f2e..285229cf82a3 100644
--- a/tools/libs/guest/xg_private.h
+++ b/tools/libs/guest/xg_private.h
@@ -28,9 +28,9 @@
#include <sys/stat.h>
#include "xc_private.h"
-#include "xc_bitops.h"
#include "xenguest.h"
+#include <xen-tools/bitops.h>
#include <xen/memory.h>
#include <xen/elfnote.h>
#include <xen/libelf/libelf.h>
diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index 2f058ee3a6ff..0e419c3a96a0 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -5,8 +5,6 @@
#include "xg_private.h"
#include "xg_save_restore.h"
-#include "xc_bitops.h"
-
#include "xg_sr_stream_format.h"
/* String representation of Domain Header types. */
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v17 3/4] tools/tests: introduce unit tests for domain ID allocator
2025-08-29 23:21 [PATCH v17 0/4] xen/domain: domain ID allocation dmukhin
2025-08-29 23:21 ` [PATCH v17 1/4] xen/domain: unify " dmukhin
2025-08-29 23:21 ` [PATCH v17 2/4] tools/include: move xc_bitops.h to xen-tools/bitops.h dmukhin
@ 2025-08-29 23:21 ` dmukhin
2025-09-04 13:50 ` Anthony PERARD
2025-08-29 23:21 ` [PATCH v17 4/4] xen/domain: update create_dom0() messages dmukhin
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: dmukhin @ 2025-08-29 23:21 UTC (permalink / raw)
To: xen-devel
Cc: andrew.cooper3, anthony.perard, jbeulich, julien, michal.orzel,
roger.pau, sstabellini, dmukhin
From: Denis Mukhin <dmukhin@ford.com>
Introduce some basic infrastructure for doing domain ID allocation unit tests,
and add a few tests that ensure correctness of the domain ID allocator.
Use <xen-tools/bitops.h> and xen/lib/find-next-bit.c in test hardness code.
Adjust find-next-bit.c to be compiled with __XEN_TOOLS__.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v16:
- used exit() in the test suite's verify()
- various fixes in the test Makefile
---
tools/include/xen-tools/bitops.h | 10 ++++
tools/tests/Makefile | 1 +
tools/tests/domid/.gitignore | 2 +
tools/tests/domid/Makefile | 88 +++++++++++++++++++++++++++++
tools/tests/domid/harness.h | 54 ++++++++++++++++++
tools/tests/domid/test-domid.c | 95 ++++++++++++++++++++++++++++++++
xen/lib/find-next-bit.c | 5 ++
7 files changed, 255 insertions(+)
create mode 100644 tools/tests/domid/.gitignore
create mode 100644 tools/tests/domid/Makefile
create mode 100644 tools/tests/domid/harness.h
create mode 100644 tools/tests/domid/test-domid.c
diff --git a/tools/include/xen-tools/bitops.h b/tools/include/xen-tools/bitops.h
index 681482f6759f..3b98fba6d74c 100644
--- a/tools/include/xen-tools/bitops.h
+++ b/tools/include/xen-tools/bitops.h
@@ -12,6 +12,16 @@
#define BITS_PER_LONG 32
#endif
+#define ffsl(x) __builtin_ffsl(x)
+
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+
+#define BITS_TO_LONGS(bits) \
+ (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG)
+
+#define DECLARE_BITMAP(name, bits) \
+ unsigned long name[BITS_TO_LONGS(bits)]
+
#define BITMAP_ENTRY(_nr,_bmap) ((_bmap))[(_nr) / 8]
#define BITMAP_SHIFT(_nr) ((_nr) % 8)
diff --git a/tools/tests/Makefile b/tools/tests/Makefile
index 97ba2a13894d..ac5737364623 100644
--- a/tools/tests/Makefile
+++ b/tools/tests/Makefile
@@ -2,6 +2,7 @@ XEN_ROOT = $(CURDIR)/../..
include $(XEN_ROOT)/tools/Rules.mk
SUBDIRS-y :=
+SUBDIRS-y += domid
SUBDIRS-y += resource
SUBDIRS-$(CONFIG_X86) += cpu-policy
SUBDIRS-$(CONFIG_X86) += tsx
diff --git a/tools/tests/domid/.gitignore b/tools/tests/domid/.gitignore
new file mode 100644
index 000000000000..37d773103be4
--- /dev/null
+++ b/tools/tests/domid/.gitignore
@@ -0,0 +1,2 @@
+generated
+test-domid
diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
new file mode 100644
index 000000000000..22f1f15d11db
--- /dev/null
+++ b/tools/tests/domid/Makefile
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Unit tests for domain ID allocator.
+#
+# Copyright 2025 Ford Motor Company
+
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+TESTS := test-domid
+
+define list-c-headers
+$(shell sed -n -E \
+ 's/^[ \t]*# *include[ \t]*[<"]([^">]+)[">].*/\1/p' $(1) 2>/dev/null)
+endef
+
+# NB: $1 cannot be a list
+define emit-harness-nested-rule
+$(1): $(CURDIR)/harness.h
+ mkdir -p $$(@D);
+ ln -sf $$< $$@;
+
+endef
+
+define emit-harness-rules
+$(foreach x,$(2),$(call emit-harness-nested-rule,$(CURDIR)/generated/$(x)))
+$(1:.c=.o): $(addprefix $(CURDIR)/generated/,$(2))
+endef
+
+define emit-harness-deps
+$(if $(strip $(2)),$(call emit-harness-rules,$1,$2),)
+endef
+
+define vpath-with-harness-deps
+vpath $(1) $(2)
+$(call emit-harness-deps,$(1),$(call list-c-headers,$(2)$(1)))
+endef
+
+.PHONY: all
+all: $(TESTS)
+
+.PHONY: run
+run: $(TESTS)
+ set -e; $(foreach t,$(TESTS),./$(t);)
+
+.PHONY: clean
+clean:
+ $(RM) -r generated
+ $(RM) -- *.o $(TESTS) $(DEPS_RM)
+
+.PHONY: distclean
+distclean: clean
+ $(RM) -- *~
+
+.PHONY: install
+install: all
+ $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
+ $(INSTALL_PROG) test-domid $(DESTDIR)$(LIBEXEC)/tests
+
+.PHONY: uninstall
+uninstall:
+ $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/test-domid
+
+CFLAGS += -D__XEN_TOOLS__
+# find-next-bit.c
+CFLAGS += '-DEXPORT_SYMBOL(x)=' \
+ -Dfind_first_bit \
+ -Dfind_first_zero_bit \
+ -Dfind_next_bit \
+ -Dfind_next_bit_le \
+ -Dfind_next_zero_bit_le
+CFLAGS += $(APPEND_CFLAGS)
+CFLAGS += $(CFLAGS_xeninclude)
+CFLAGS += -I./generated/
+
+LDFLAGS += $(APPEND_LDFLAGS)
+
+vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
+
+# Point to the hypervisor code and generate test harness dependencies
+# on the fly, making it possible to compile parts of the hypervisor
+# within a mocked environment.
+$(eval $(call vpath-with-harness-deps,domid.c,$(XEN_ROOT)/xen/common/))
+
+test-domid: domid.o find-next-bit.o test-domid.o
+ $(CC) $^ -o $@ $(LDFLAGS)
+
+-include $(DEPS_INCLUDE)
diff --git a/tools/tests/domid/harness.h b/tools/tests/domid/harness.h
new file mode 100644
index 000000000000..17eb22a9a854
--- /dev/null
+++ b/tools/tests/domid/harness.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Unit test harness for domain ID allocator.
+ *
+ * Copyright 2025 Ford Motor Company
+ */
+
+#ifndef _TEST_HARNESS_
+#define _TEST_HARNESS_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <xen-tools/common-macros.h>
+#include <xen-tools/bitops.h>
+
+typedef bool spinlock_t;
+typedef uint16_t domid_t;
+
+extern domid_t domid_alloc(domid_t domid);
+extern void domid_free(domid_t domid);
+
+extern unsigned long find_next_zero_bit(const unsigned long *addr,
+ unsigned long size,
+ unsigned long offset);
+
+#define __test_and_set_bit(nr, addr) test_and_set_bit(nr, addr)
+#define __test_and_clear_bit(nr, addr) test_and_clear_bit(nr, addr)
+#define __set_bit(nr, addr) set_bit(nr, addr)
+
+#define BUG_ON(x) assert(!(x))
+#define ASSERT(x) assert(x)
+
+#define DEFINE_SPINLOCK(l) spinlock_t l
+#define spin_lock(l) (assert(!*(l)), *(l) = true)
+#define spin_unlock(l) (assert(*(l)), *(l) = false)
+
+#define printk printf
+
+#define DOMID_FIRST_RESERVED (100)
+#define DOMID_INVALID (101)
+
+#endif /* _TEST_HARNESS_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/tests/domid/test-domid.c b/tools/tests/domid/test-domid.c
new file mode 100644
index 000000000000..5915c4699a5c
--- /dev/null
+++ b/tools/tests/domid/test-domid.c
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Unit tests for domain ID allocator.
+ *
+ * Copyright 2025 Ford Motor Company
+ */
+
+#include <sysexits.h>
+
+#include "harness.h"
+
+#define verify(exp, fmt, args...) \
+while (!(exp)) { \
+ printf(fmt, ## args); \
+ exit(EX_SOFTWARE); \
+}
+
+/*
+ * Fail on the first error, since tests are dependent on each other.
+ */
+int main(int argc, char **argv)
+{
+ domid_t expected, allocated;
+
+ /* Test ID cannot be allocated twice. */
+ for ( expected = 0; expected < DOMID_FIRST_RESERVED; expected++ )
+ {
+ allocated = domid_alloc(expected);
+ verify(allocated == expected,
+ "TEST 1: expected %u allocated %u\n", expected, allocated);
+ }
+ for ( expected = 0; expected < DOMID_FIRST_RESERVED; expected++ )
+ {
+ allocated = domid_alloc(expected);
+ verify(allocated == DOMID_INVALID,
+ "TEST 2: expected %u allocated %u\n", DOMID_INVALID, allocated);
+ }
+
+ /* Ensure all IDs, including ID#0 are not allocated. */
+ for ( expected = 0; expected < DOMID_FIRST_RESERVED; expected++ )
+ domid_free(expected);
+
+ /*
+ * Test that that two consecutive calls of domid_alloc(DOMID_INVALID)
+ * will never return the same ID.
+ * NB: ID#0 is reserved and shall not be allocated by
+ * domid_alloc(DOMID_INVALID).
+ */
+ for ( expected = 1; expected < DOMID_FIRST_RESERVED; expected++ )
+ {
+ allocated = domid_alloc(DOMID_INVALID);
+ verify(allocated == expected,
+ "TEST 3: expected %u allocated %u\n", expected, allocated);
+ }
+ for ( expected = 1; expected < DOMID_FIRST_RESERVED; expected++ )
+ {
+ allocated = domid_alloc(DOMID_INVALID);
+ verify(allocated == DOMID_INVALID,
+ "TEST 4: expected %u allocated %u\n", DOMID_INVALID, allocated);
+ }
+
+ /* Re-allocate first ID from [1..DOMID_FIRST_RESERVED/2]. */
+ for ( expected = 1; expected < DOMID_FIRST_RESERVED / 2; expected++ )
+ domid_free(expected);
+ for ( expected = 1; expected < DOMID_FIRST_RESERVED / 2; expected++ )
+ {
+ allocated = domid_alloc(DOMID_INVALID);
+ verify(allocated == expected,
+ "TEST 5: expected %u allocated %u\n", expected, allocated);
+ }
+
+ /* Re-allocate last ID from [1..DOMID_FIRST_RESERVED - 1]. */
+ expected = DOMID_FIRST_RESERVED - 1;
+ domid_free(DOMID_FIRST_RESERVED - 1);
+ allocated = domid_alloc(DOMID_INVALID);
+ verify(allocated == expected,
+ "TEST 6: expected %u allocated %u\n", expected, allocated);
+
+ /* Allocate an invalid ID. */
+ expected = DOMID_INVALID;
+ allocated = domid_alloc(DOMID_FIRST_RESERVED);
+ verify(allocated == expected,
+ "TEST 7: expected %u allocated %u\n", expected, allocated);
+
+ return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/lib/find-next-bit.c b/xen/lib/find-next-bit.c
index 9b8d7814f20c..539c7f2022b0 100644
--- a/xen/lib/find-next-bit.c
+++ b/xen/lib/find-next-bit.c
@@ -8,8 +8,13 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
+#ifdef __XEN_TOOLS__
+#include <xen-tools/bitops.h>
+#else
#include <xen/bitops.h>
#include <xen/byteorder.h>
+#endif
#define __ffs(x) (ffsl(x) - 1)
#define ffz(x) __ffs(~(x))
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v17 3/4] tools/tests: introduce unit tests for domain ID allocator
2025-08-29 23:21 ` [PATCH v17 3/4] tools/tests: introduce unit tests for domain ID allocator dmukhin
@ 2025-09-04 13:50 ` Anthony PERARD
2025-09-05 23:19 ` dmukhin
0 siblings, 1 reply; 10+ messages in thread
From: Anthony PERARD @ 2025-09-04 13:50 UTC (permalink / raw)
To: dmukhin
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
On Fri, Aug 29, 2025 at 04:21:31PM -0700, dmukhin@xen.org wrote:
> diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
> new file mode 100644
> index 000000000000..22f1f15d11db
> --- /dev/null
> +++ b/tools/tests/domid/Makefile
> +# NB: $1 cannot be a list
Why not? It would be the same as writing the rule multiple time for
different targets.
Is about my comment on "prerequisite" on v16? In this rule, "harness.h"
is a prerequisite.
> +define emit-harness-nested-rule
> +$(1): $(CURDIR)/harness.h
> + mkdir -p $$(@D);
> + ln -sf $$< $$@;
> +
> +endef
> diff --git a/tools/tests/domid/test-domid.c b/tools/tests/domid/test-domid.c
> new file mode 100644
> index 000000000000..5915c4699a5c
> --- /dev/null
> +++ b/tools/tests/domid/test-domid.c
> +
> +#include <sysexits.h>
> +
> +#include "harness.h"
> +
> +#define verify(exp, fmt, args...) \
> +while (!(exp)) { \
> + printf(fmt, ## args); \
> + exit(EX_SOFTWARE); \
We never used any of "EX_*" macro, or even <sysexits.h>. I'm not sure
it's a good idea to introduce such use where exit(1) would have been
more than enough but sysexits.h seems to be available on BSD so it's
probably fine. It would be nice to change that to exit(1) and remove
sysexits.h.
Anyway, patch looks good enough so:
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
Thanks,
--
Anthony PERARD
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v17 3/4] tools/tests: introduce unit tests for domain ID allocator
2025-09-04 13:50 ` Anthony PERARD
@ 2025-09-05 23:19 ` dmukhin
0 siblings, 0 replies; 10+ messages in thread
From: dmukhin @ 2025-09-05 23:19 UTC (permalink / raw)
To: Anthony PERARD
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
On Thu, Sep 04, 2025 at 03:50:38PM +0200, Anthony PERARD wrote:
> On Fri, Aug 29, 2025 at 04:21:31PM -0700, dmukhin@xen.org wrote:
> > diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
> > new file mode 100644
> > index 000000000000..22f1f15d11db
> > --- /dev/null
> > +++ b/tools/tests/domid/Makefile
> > +# NB: $1 cannot be a list
>
> Why not? It would be the same as writing the rule multiple time for
> different targets.
>
> Is about my comment on "prerequisite" on v16? In this rule, "harness.h"
> is a prerequisite.
Sorry for late response.
I see the series is already comitted (thanks!)
I will send a fixup patch for that, since this fragment can be re-used in new
tests.
>
> > +define emit-harness-nested-rule
> > +$(1): $(CURDIR)/harness.h
> > + mkdir -p $$(@D);
> > + ln -sf $$< $$@;
> > +
> > +endef
> > diff --git a/tools/tests/domid/test-domid.c b/tools/tests/domid/test-domid.c
> > new file mode 100644
> > index 000000000000..5915c4699a5c
> > --- /dev/null
> > +++ b/tools/tests/domid/test-domid.c
> > +
> > +#include <sysexits.h>
> > +
> > +#include "harness.h"
> > +
> > +#define verify(exp, fmt, args...) \
> > +while (!(exp)) { \
> > + printf(fmt, ## args); \
> > + exit(EX_SOFTWARE); \
>
> We never used any of "EX_*" macro, or even <sysexits.h>. I'm not sure
> it's a good idea to introduce such use where exit(1) would have been
> more than enough but sysexits.h seems to be available on BSD so it's
> probably fine. It would be nice to change that to exit(1) and remove
> sysexits.h.
re: sysexits.h: muscle memory.
I can fix this up too in a follow on patch, please let me know.
>
> Anyway, patch looks good enough so:
> Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
Thanks!
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v17 4/4] xen/domain: update create_dom0() messages
2025-08-29 23:21 [PATCH v17 0/4] xen/domain: domain ID allocation dmukhin
` (2 preceding siblings ...)
2025-08-29 23:21 ` [PATCH v17 3/4] tools/tests: introduce unit tests for domain ID allocator dmukhin
@ 2025-08-29 23:21 ` dmukhin
2025-09-03 21:28 ` [PATCH v17 0/4] xen/domain: domain ID allocation Stefano Stabellini
2025-09-04 20:15 ` Demi Marie Obenour
5 siblings, 0 replies; 10+ messages in thread
From: dmukhin @ 2025-08-29 23:21 UTC (permalink / raw)
To: xen-devel
Cc: andrew.cooper3, anthony.perard, jbeulich, julien, michal.orzel,
roger.pau, sstabellini, dmukhin, Alejandro Vallejo, Julien Grall
From: Denis Mukhin <dmukhin@ford.com>
Use %pd for domain identification in error/panic messages in create_dom0().
No functional change.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
Reviewed-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Julien Grall <jgrall@amazon.com>
---
Changes since v16:
- n/a
---
xen/arch/arm/domain_build.c | 6 +++---
xen/arch/x86/setup.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index aca35b8961d6..670f634b8b0d 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -2084,14 +2084,14 @@ void __init create_dom0(void)
panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
if ( llc_coloring_enabled && (rc = dom0_set_llc_colors(dom0)) )
- panic("Error initializing LLC coloring for domain 0 (rc = %d)\n", rc);
+ panic("Error initializing LLC coloring for %pd (rc = %d)\n", dom0, rc);
if ( vcpu_create(dom0, 0) == NULL )
- panic("Error creating domain 0 vcpu0\n");
+ panic("Error creating %pdv0\n", dom0);
rc = construct_dom0(dom0);
if ( rc )
- panic("Could not set up DOM0 guest OS (rc = %d)\n", rc);
+ panic("Could not set up %pd guest OS (rc = %d)\n", dom0, rc);
set_xs_domain(dom0);
}
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 78e24b78c5a6..da1fe8fdb6dd 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1075,7 +1075,7 @@ static struct domain *__init create_dom0(struct boot_info *bi)
if ( (strlen(acpi_param) == 0) && acpi_disabled )
{
- printk("ACPI is disabled, notifying Domain 0 (acpi=off)\n");
+ printk("ACPI is disabled, notifying %pd (acpi=off)\n", d);
safe_strcpy(acpi_param, "off");
}
@@ -1090,7 +1090,7 @@ static struct domain *__init create_dom0(struct boot_info *bi)
bd->d = d;
if ( construct_dom0(bd) != 0 )
- panic("Could not construct domain 0\n");
+ panic("Could not construct %pd\n", d);
bd->cmdline = NULL;
xfree(cmdline);
--
2.51.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v17 0/4] xen/domain: domain ID allocation
2025-08-29 23:21 [PATCH v17 0/4] xen/domain: domain ID allocation dmukhin
` (3 preceding siblings ...)
2025-08-29 23:21 ` [PATCH v17 4/4] xen/domain: update create_dom0() messages dmukhin
@ 2025-09-03 21:28 ` Stefano Stabellini
2025-09-04 20:15 ` Demi Marie Obenour
5 siblings, 0 replies; 10+ messages in thread
From: Stefano Stabellini @ 2025-09-03 21:28 UTC (permalink / raw)
To: dmukhin
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
This series is fully acked except for:
- a minimal change to xen/arch/x86/setup.c
- the self test tools/tests/domid/
Based on this, I plan to commit it in the next couple of days. Please
let me know if you have any thoughts on that.
On Fri, 29 Aug 2025, dmukhin@xen.org wrote:
> Patch 1 introduces new domid_{alloc,free} calls.
> Patch 2 is a prep change for domain ID allocator test.
> Patch 3 introduces some basic testing for domain ID allocator.
> Patch 4 adjusts create_dom0() messages (use %pd).
>
> Link to v16: https://lore.kernel.org/xen-devel/20250812223024.2364749-1-dmukhin@ford.com/
> Link to CI: https://gitlab.com/xen-project/people/dmukhin/xen/-/pipelines/2012378054
>
> Denis Mukhin (4):
> xen/domain: unify domain ID allocation
> tools/include: move xc_bitops.h to xen-tools/bitops.h
> tools/tests: introduce unit tests for domain ID allocator
> xen/domain: update create_dom0() messages
>
> .../xen-tools/bitops.h} | 16 +++-
> tools/libs/ctrl/xc_misc.c | 13 +--
> tools/libs/guest/xg_dom_elfloader.c | 1 -
> tools/libs/guest/xg_dom_hvmloader.c | 1 -
> tools/libs/guest/xg_private.h | 2 +-
> tools/libs/guest/xg_sr_common.h | 2 -
> tools/tests/Makefile | 1 +
> tools/tests/domid/.gitignore | 2 +
> tools/tests/domid/Makefile | 88 +++++++++++++++++
> tools/tests/domid/harness.h | 54 +++++++++++
> tools/tests/domid/test-domid.c | 95 +++++++++++++++++++
> xen/arch/arm/domain_build.c | 13 ++-
> xen/arch/x86/setup.c | 11 ++-
> xen/common/Makefile | 1 +
> xen/common/device-tree/dom0less-build.c | 15 +--
> xen/common/domain.c | 2 +
> xen/common/domctl.c | 43 ++-------
> xen/common/domid.c | 95 +++++++++++++++++++
> xen/include/xen/domain.h | 3 +
> xen/lib/find-next-bit.c | 5 +
> 20 files changed, 397 insertions(+), 66 deletions(-)
> rename tools/{libs/ctrl/xc_bitops.h => include/xen-tools/bitops.h} (84%)
> create mode 100644 tools/tests/domid/.gitignore
> create mode 100644 tools/tests/domid/Makefile
> create mode 100644 tools/tests/domid/harness.h
> create mode 100644 tools/tests/domid/test-domid.c
> create mode 100644 xen/common/domid.c
>
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v17 0/4] xen/domain: domain ID allocation
2025-08-29 23:21 [PATCH v17 0/4] xen/domain: domain ID allocation dmukhin
` (4 preceding siblings ...)
2025-09-03 21:28 ` [PATCH v17 0/4] xen/domain: domain ID allocation Stefano Stabellini
@ 2025-09-04 20:15 ` Demi Marie Obenour
2025-09-05 14:23 ` Alejandro Vallejo
5 siblings, 1 reply; 10+ messages in thread
From: Demi Marie Obenour @ 2025-09-04 20:15 UTC (permalink / raw)
To: dmukhin, xen-devel
Cc: andrew.cooper3, anthony.perard, jbeulich, julien, michal.orzel,
roger.pau, sstabellini, dmukhin, Marek Marczykowski-Górecki,
Simon Gaiser
[-- Attachment #1.1.1: Type: text/plain, Size: 2835 bytes --]
On 8/29/25 19:21, dmukhin@xen.org wrote:
> Patch 1 introduces new domid_{alloc,free} calls.
> Patch 2 is a prep change for domain ID allocator test.
> Patch 3 introduces some basic testing for domain ID allocator.
> Patch 4 adjusts create_dom0() messages (use %pd).
>
> Link to v16: https://lore.kernel.org/xen-devel/20250812223024.2364749-1-dmukhin@ford.com/
> Link to CI: https://gitlab.com/xen-project/people/dmukhin/xen/-/pipelines/2012378054
>
> Denis Mukhin (4):
> xen/domain: unify domain ID allocation
> tools/include: move xc_bitops.h to xen-tools/bitops.h
> tools/tests: introduce unit tests for domain ID allocator
> xen/domain: update create_dom0() messages
>
> .../xen-tools/bitops.h} | 16 +++-
> tools/libs/ctrl/xc_misc.c | 13 +--
> tools/libs/guest/xg_dom_elfloader.c | 1 -
> tools/libs/guest/xg_dom_hvmloader.c | 1 -
> tools/libs/guest/xg_private.h | 2 +-
> tools/libs/guest/xg_sr_common.h | 2 -
> tools/tests/Makefile | 1 +
> tools/tests/domid/.gitignore | 2 +
> tools/tests/domid/Makefile | 88 +++++++++++++++++
> tools/tests/domid/harness.h | 54 +++++++++++
> tools/tests/domid/test-domid.c | 95 +++++++++++++++++++
> xen/arch/arm/domain_build.c | 13 ++-
> xen/arch/x86/setup.c | 11 ++-
> xen/common/Makefile | 1 +
> xen/common/device-tree/dom0less-build.c | 15 +--
> xen/common/domain.c | 2 +
> xen/common/domctl.c | 43 ++-------
> xen/common/domid.c | 95 +++++++++++++++++++
> xen/include/xen/domain.h | 3 +
> xen/lib/find-next-bit.c | 5 +
> 20 files changed, 397 insertions(+), 66 deletions(-)
> rename tools/{libs/ctrl/xc_bitops.h => include/xen-tools/bitops.h} (84%)
> create mode 100644 tools/tests/domid/.gitignore
> create mode 100644 tools/tests/domid/Makefile
> create mode 100644 tools/tests/domid/harness.h
> create mode 100644 tools/tests/domid/test-domid.c
> create mode 100644 xen/common/domid.c
Would it make sense to support virtualizing the domain ID space?
That would allow the toolstack to only allow a domain to communicate
with other domains of its choosing, rather than with any domain XSM
permits. This would also allow avoiding domain ID reuse problems,
because a virtual domain ID would stay valid even after the domain
it refers to no longer exists. It would need to be explicitly released
by the guest kernel before it could refer to a different domain.
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v17 0/4] xen/domain: domain ID allocation
2025-09-04 20:15 ` Demi Marie Obenour
@ 2025-09-05 14:23 ` Alejandro Vallejo
0 siblings, 0 replies; 10+ messages in thread
From: Alejandro Vallejo @ 2025-09-05 14:23 UTC (permalink / raw)
To: Demi Marie Obenour, dmukhin, xen-devel
Cc: andrew.cooper3, anthony.perard, jbeulich, julien, michal.orzel,
roger.pau, sstabellini, dmukhin, Marek Marczykowski-Górecki,
Simon Gaiser, Xen-devel
On Thu Sep 4, 2025 at 10:15 PM CEST, Demi Marie Obenour wrote:
> On 8/29/25 19:21, dmukhin@xen.org wrote:
>> Patch 1 introduces new domid_{alloc,free} calls.
>> Patch 2 is a prep change for domain ID allocator test.
>> Patch 3 introduces some basic testing for domain ID allocator.
>> Patch 4 adjusts create_dom0() messages (use %pd).
>>
>> Link to v16: https://lore.kernel.org/xen-devel/20250812223024.2364749-1-dmukhin@ford.com/
>> Link to CI: https://gitlab.com/xen-project/people/dmukhin/xen/-/pipelines/2012378054
>>
>> Denis Mukhin (4):
>> xen/domain: unify domain ID allocation
>> tools/include: move xc_bitops.h to xen-tools/bitops.h
>> tools/tests: introduce unit tests for domain ID allocator
>> xen/domain: update create_dom0() messages
>>
>> .../xen-tools/bitops.h} | 16 +++-
>> tools/libs/ctrl/xc_misc.c | 13 +--
>> tools/libs/guest/xg_dom_elfloader.c | 1 -
>> tools/libs/guest/xg_dom_hvmloader.c | 1 -
>> tools/libs/guest/xg_private.h | 2 +-
>> tools/libs/guest/xg_sr_common.h | 2 -
>> tools/tests/Makefile | 1 +
>> tools/tests/domid/.gitignore | 2 +
>> tools/tests/domid/Makefile | 88 +++++++++++++++++
>> tools/tests/domid/harness.h | 54 +++++++++++
>> tools/tests/domid/test-domid.c | 95 +++++++++++++++++++
>> xen/arch/arm/domain_build.c | 13 ++-
>> xen/arch/x86/setup.c | 11 ++-
>> xen/common/Makefile | 1 +
>> xen/common/device-tree/dom0less-build.c | 15 +--
>> xen/common/domain.c | 2 +
>> xen/common/domctl.c | 43 ++-------
>> xen/common/domid.c | 95 +++++++++++++++++++
>> xen/include/xen/domain.h | 3 +
>> xen/lib/find-next-bit.c | 5 +
>> 20 files changed, 397 insertions(+), 66 deletions(-)
>> rename tools/{libs/ctrl/xc_bitops.h => include/xen-tools/bitops.h} (84%)
>> create mode 100644 tools/tests/domid/.gitignore
>> create mode 100644 tools/tests/domid/Makefile
>> create mode 100644 tools/tests/domid/harness.h
>> create mode 100644 tools/tests/domid/test-domid.c
>> create mode 100644 xen/common/domid.c
>
> Would it make sense to support virtualizing the domain ID space?
> That would allow the toolstack to only allow a domain to communicate
> with other domains of its choosing, rather than with any domain XSM
> permits. This would also allow avoiding domain ID reuse problems,
> because a virtual domain ID would stay valid even after the domain
> it refers to no longer exists. It would need to be explicitly released
> by the guest kernel before it could refer to a different domain.
I'd be all-in for something like that. For context, this is something we
briefly touched on over lunch on the last Xen Summit (it was Juergen, Marek you
and I, I think?). Regardless, this series is only tangentially related. Even if
you do have several domclusters, you'd still need a per-cluster allocator of
domids. For something like domcluster-namespaces to work, we'd need to extend
createdomain to also take a domcluster-id, then the unique domain identifier
comes from a domcluster-id+domid.
I tried shortly after we discussed it to sketch out a credible plan to getting
there, but there were more wrinkles than I expected. You'd definitely want some
domains to be in several namespaces at the same time (The hwdom, at least),
which involves some refcounting I was unsure how to do. Not a major show-stopper
but I hate refcounts with the intensity of a power plant.
grants also become more complicated when you have a domain in several
namespaces, because now you need several grant tables per domain (one per
namespace). The ultimate consequence of this means that if dom0 wants to create
a new domcluster and bind itself to it, now it needs to create a NEW grant table
for itself. Xen is also unaware of this multi-grant table shenanigans so that
needs accounting for too.
Then there's adjustments to be done on the maptrack.
So. I'd really like for this to become a reality, but it requires someone with
time to do it to sit down and walk down the rabbit hole. It was definitely
far deeper than I expected it to be. It doesn't seem to be untractably deep,
but deep enough that I don't want to do it in my spare time. It'd require
coordinated changes at least in Linux, Xen and the toolstack.
Cheers,
Alejandro
^ permalink raw reply [flat|nested] 10+ messages in thread