* [PATCH v2 1/4] tests: fixup domid make fragment
2026-01-11 4:11 [PATCH v2 0/4] tools/tests: test harness fragment dmukhin
@ 2026-01-11 4:11 ` dmukhin
2026-01-12 11:16 ` Jan Beulich
2026-01-24 0:59 ` Stefano Stabellini
2026-01-11 4:11 ` [PATCH v2 2/4] tests: introduce common fragment for unit tests dmukhin
` (2 subsequent siblings)
3 siblings, 2 replies; 13+ messages in thread
From: dmukhin @ 2026-01-11 4:11 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>
There can be multiple test harnesses per one test target (e.g. harness.h
and harness2.h). Account for that by further parametrizing existing
emit-harness-nested-rule().
Add guard against HOSTCC != CC (similarly to how its done in PDX unit test).
Account for multiple test targets in install and uninstall make targets.
Introduce CFLAGS dedicated for find-next-bit.c only to avoid contaminating
global CFLAGS.
Honor mocked hypervisor header over tools/include/xen symlinks.
Finally, add some clarifications for the functions.
Amends: 2d5065060710 ("xen/domain: unify domain ID allocation")
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v1:
- updated commentaries
- added ability to select the harness header filename
- fixup for picking up mocked header files
---
tools/tests/domid/Makefile | 63 ++++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 19 deletions(-)
diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
index 753129029ed9..dd22a25b038a 100644
--- a/tools/tests/domid/Makefile
+++ b/tools/tests/domid/Makefile
@@ -4,36 +4,55 @@
#
# Copyright 2025 Ford Motor Company
-XEN_ROOT=$(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
TESTS := test-domid
+XEN_ROOT = $(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
define list-c-headers
$(shell sed -n \
's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
endef
-# NB: $1 cannot be a list
+# Generate mock environment by replicating header file hierarchy;
+# each header file will point to a harness header.
+#
+# $1 target
+# $2 list of test harnesses
define emit-harness-nested-rule
-$(1): $(CURDIR)/harness.h
- mkdir -p $$(@D);
- ln -sf $$< $$@;
+$(1): $(2)
+ set -e; \
+ mkdir -p $$(@D); \
+ for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
endef
+# Helper function to emit mocked hypervisor code dependencies.
+#
+# $1 Harness file name.
+# $2 Mocked hypervisor file name.
+# $3 List of dependencies to mock.
define emit-harness-rules
-$(foreach x,$(2),$(call emit-harness-nested-rule,$(CURDIR)/generated/$(x)))
-$(1:.c=.o): $(addprefix $(CURDIR)/generated/,$(2))
+$(foreach x,$(3),$(call emit-harness-nested-rule,\
+ $(CURDIR)/generated/$(x),\
+ $(addprefix $(CURDIR)/,$(1))))
+$(2:.c=.o): $(addprefix $(CURDIR)/generated/,$(3))
endef
define emit-harness-deps
-$(if $(strip $(2)),$(call emit-harness-rules,$1,$2),)
+$(if $(strip $(3)),$(call emit-harness-rules,$1,$2,$3),)
endef
+# Emit dependencies for mocked hypervisor code.
+#
+# $1 Hypervisor file name.
+# $2 Hypervisor source path.
+# $3 Harness header file name (optional).
define vpath-with-harness-deps
vpath $(1) $(2)
-$(call emit-harness-deps,$(1),$(call list-c-headers,$(2)$(1)))
+$(call emit-harness-deps,$(or $(strip $(3)),harness.h),\
+ $(1),\
+ $(call list-c-headers,$(2)$(1)))
endef
.PHONY: all
@@ -41,7 +60,11 @@ all: $(TESTS)
.PHONY: run
run: $(TESTS)
+ifeq ($(CC),$(HOSTCC))
set -e; $(foreach t,$(TESTS),./$(t);)
+else
+ $(warning HOSTCC != CC, will not run test)
+endif
.PHONY: clean
clean:
@@ -55,25 +78,27 @@ distclean: clean
.PHONY: install
install: all
$(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
- $(INSTALL_PROG) test-domid $(DESTDIR)$(LIBEXEC)/tests
+ set -e; $(foreach t,$(TESTS),$(INSTALL_PROG) $t $(DESTDIR)$(LIBEXEC)/tests;)
.PHONY: uninstall
uninstall:
- $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/test-domid
+ set -e; $(foreach t,$(TESTS),$(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$t;)
CFLAGS += -D__XEN_TOOLS__
+
# find-next-bit.c
-CFLAGS += '-DEXPORT_SYMBOL(x)=' \
+CFLAGS-find-next-bit.c += '-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)
+find-next-bit.o: CFLAGS += $(CFLAGS-find-next-bit.c)
+
+# Honor mocked hypervisor header over tools/include/xen symlinks
+CFLAGS += -I$(CURDIR)/generated/
+CFLAGS += $(CFLAGS_xeninclude)
vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
@@ -83,6 +108,6 @@ vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
$(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)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
-include $(DEPS_INCLUDE)
--
2.52.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 1/4] tests: fixup domid make fragment
2026-01-11 4:11 ` [PATCH v2 1/4] tests: fixup domid make fragment dmukhin
@ 2026-01-12 11:16 ` Jan Beulich
2026-01-15 9:01 ` dmukhin
2026-01-24 0:59 ` Stefano Stabellini
1 sibling, 1 reply; 13+ messages in thread
From: Jan Beulich @ 2026-01-12 11:16 UTC (permalink / raw)
To: dmukhin
Cc: andrew.cooper3, anthony.perard, julien, michal.orzel, roger.pau,
sstabellini, dmukhin, xen-devel
On 11.01.2026 05:11, dmukhin@xen.org wrote:
> From: Denis Mukhin <dmukhin@ford.com>
>
> There can be multiple test harnesses per one test target (e.g. harness.h
> and harness2.h). Account for that by further parametrizing existing
> emit-harness-nested-rule().
Multiple harnesses within a single dir imo likely would share headers, but
use different .c files. Also, why would dependencies on headers need
recording at all? The Makefile includes $(DEPS_INCLUDE), so all dependency
concerns should be covered (or else the generic machinery would need
fixing). Imo all of this wants simplifying (dropping?) rather than further
complicating.
Jan
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/4] tests: fixup domid make fragment
2026-01-12 11:16 ` Jan Beulich
@ 2026-01-15 9:01 ` dmukhin
0 siblings, 0 replies; 13+ messages in thread
From: dmukhin @ 2026-01-15 9:01 UTC (permalink / raw)
To: Jan Beulich
Cc: andrew.cooper3, anthony.perard, julien, michal.orzel, roger.pau,
sstabellini, dmukhin, xen-devel
On Mon, Jan 12, 2026 at 12:16:46PM +0100, Jan Beulich wrote:
> On 11.01.2026 05:11, dmukhin@xen.org wrote:
> > From: Denis Mukhin <dmukhin@ford.com>
> >
> > There can be multiple test harnesses per one test target (e.g. harness.h
> > and harness2.h). Account for that by further parametrizing existing
> > emit-harness-nested-rule().
>
> Multiple harnesses within a single dir imo likely would share headers, but
> use different .c files. Also, why would dependencies on headers need
> recording at all? The Makefile includes $(DEPS_INCLUDE), so all dependency
> concerns should be covered (or else the generic machinery would need
> fixing). Imo all of this wants simplifying (dropping?) rather than further
> complicating.
Whoops, I forgot to drop that multi-harness stuff.
Thanks!
>
> Jan
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/4] tests: fixup domid make fragment
2026-01-11 4:11 ` [PATCH v2 1/4] tests: fixup domid make fragment dmukhin
2026-01-12 11:16 ` Jan Beulich
@ 2026-01-24 0:59 ` Stefano Stabellini
1 sibling, 0 replies; 13+ messages in thread
From: Stefano Stabellini @ 2026-01-24 0:59 UTC (permalink / raw)
To: dmukhin
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
On Sat, 10 Jan 2026, dmukhin@xen.org wrote:
> From: Denis Mukhin <dmukhin@ford.com>
>
> There can be multiple test harnesses per one test target (e.g. harness.h
> and harness2.h). Account for that by further parametrizing existing
> emit-harness-nested-rule().
>
> Add guard against HOSTCC != CC (similarly to how its done in PDX unit test).
>
> Account for multiple test targets in install and uninstall make targets.
>
> Introduce CFLAGS dedicated for find-next-bit.c only to avoid contaminating
> global CFLAGS.
>
> Honor mocked hypervisor header over tools/include/xen symlinks.
>
> Finally, add some clarifications for the functions.
>
> Amends: 2d5065060710 ("xen/domain: unify domain ID allocation")
> Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> ---
> Changes since v1:
> - updated commentaries
> - added ability to select the harness header filename
> - fixup for picking up mocked header files
> ---
> tools/tests/domid/Makefile | 63 ++++++++++++++++++++++++++------------
> 1 file changed, 44 insertions(+), 19 deletions(-)
>
> diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
> index 753129029ed9..dd22a25b038a 100644
> --- a/tools/tests/domid/Makefile
> +++ b/tools/tests/domid/Makefile
> @@ -4,36 +4,55 @@
> #
> # Copyright 2025 Ford Motor Company
>
> -XEN_ROOT=$(CURDIR)/../../..
> -include $(XEN_ROOT)/tools/Rules.mk
> -
> TESTS := test-domid
>
> +XEN_ROOT = $(CURDIR)/../../..
> +include $(XEN_ROOT)/tools/Rules.mk
> +
> define list-c-headers
> $(shell sed -n \
> 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
> endef
>
> -# NB: $1 cannot be a list
> +# Generate mock environment by replicating header file hierarchy;
> +# each header file will point to a harness header.
> +#
> +# $1 target
> +# $2 list of test harnesses
> define emit-harness-nested-rule
> -$(1): $(CURDIR)/harness.h
> - mkdir -p $$(@D);
> - ln -sf $$< $$@;
> +$(1): $(2)
> + set -e; \
> + mkdir -p $$(@D); \
> + for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
Are you sure this is correct? Everything seems to be escaped too many
times? Shouldn't this be:
$(1): $(2)
set -e; \
mkdir -p "$(@D)"; \
for i in $(2); do \
[ -e "$@" ] || ln -s "$$i" "$@"; \
done
endef
> endef
>
> +# Helper function to emit mocked hypervisor code dependencies.
> +#
> +# $1 Harness file name.
> +# $2 Mocked hypervisor file name.
> +# $3 List of dependencies to mock.
> define emit-harness-rules
> -$(foreach x,$(2),$(call emit-harness-nested-rule,$(CURDIR)/generated/$(x)))
> -$(1:.c=.o): $(addprefix $(CURDIR)/generated/,$(2))
> +$(foreach x,$(3),$(call emit-harness-nested-rule,\
> + $(CURDIR)/generated/$(x),\
> + $(addprefix $(CURDIR)/,$(1))))
> +$(2:.c=.o): $(addprefix $(CURDIR)/generated/,$(3))
> endef
>
> define emit-harness-deps
> -$(if $(strip $(2)),$(call emit-harness-rules,$1,$2),)
> +$(if $(strip $(3)),$(call emit-harness-rules,$1,$2,$3),)
> endef
>
> +# Emit dependencies for mocked hypervisor code.
> +#
> +# $1 Hypervisor file name.
> +# $2 Hypervisor source path.
> +# $3 Harness header file name (optional).
> define vpath-with-harness-deps
> vpath $(1) $(2)
> -$(call emit-harness-deps,$(1),$(call list-c-headers,$(2)$(1)))
> +$(call emit-harness-deps,$(or $(strip $(3)),harness.h),\
> + $(1),\
> + $(call list-c-headers,$(2)$(1)))
> endef
>
> .PHONY: all
> @@ -41,7 +60,11 @@ all: $(TESTS)
>
> .PHONY: run
> run: $(TESTS)
> +ifeq ($(CC),$(HOSTCC))
> set -e; $(foreach t,$(TESTS),./$(t);)
> +else
> + $(warning HOSTCC != CC, will not run test)
> +endif
>
> .PHONY: clean
> clean:
> @@ -55,25 +78,27 @@ distclean: clean
> .PHONY: install
> install: all
> $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
> - $(INSTALL_PROG) test-domid $(DESTDIR)$(LIBEXEC)/tests
> + set -e; $(foreach t,$(TESTS),$(INSTALL_PROG) $t $(DESTDIR)$(LIBEXEC)/tests;)
>
> .PHONY: uninstall
> uninstall:
> - $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/test-domid
> + set -e; $(foreach t,$(TESTS),$(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$t;)
>
> CFLAGS += -D__XEN_TOOLS__
> +
> # find-next-bit.c
> -CFLAGS += '-DEXPORT_SYMBOL(x)=' \
> +CFLAGS-find-next-bit.c += '-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)
APPEND_CFLAGS and APPEND_LDFLAGS are lost?
> +find-next-bit.o: CFLAGS += $(CFLAGS-find-next-bit.c)
> +
> +# Honor mocked hypervisor header over tools/include/xen symlinks
> +CFLAGS += -I$(CURDIR)/generated/
> +CFLAGS += $(CFLAGS_xeninclude)
>
> vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
>
> @@ -83,6 +108,6 @@ vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
> $(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)
> + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
My understanding is that $(LDFLAGS) should be last, e.g.:
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
> -include $(DEPS_INCLUDE)
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/4] tests: introduce common fragment for unit tests
2026-01-11 4:11 [PATCH v2 0/4] tools/tests: test harness fragment dmukhin
2026-01-11 4:11 ` [PATCH v2 1/4] tests: fixup domid make fragment dmukhin
@ 2026-01-11 4:11 ` dmukhin
2026-01-24 1:05 ` Stefano Stabellini
2026-01-11 4:11 ` [PATCH v2 3/4] tests: use unit test fragment in PDX test dmukhin
2026-01-11 4:11 ` [PATCH v2 4/4] tests: use unit test fragment in vPCI test dmukhin
3 siblings, 1 reply; 13+ messages in thread
From: dmukhin @ 2026-01-11 4:11 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 test harness generation into a new shared make fragment so that
it can be reused by other unit tests.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes from v1:
- moved fragment to tools/tests/
---
tools/tests/Rules.mk | 91 ++++++++++++++++++++++++++++++++++++++
tools/tests/domid/Makefile | 85 +----------------------------------
2 files changed, 92 insertions(+), 84 deletions(-)
create mode 100644 tools/tests/Rules.mk
diff --git a/tools/tests/Rules.mk b/tools/tests/Rules.mk
new file mode 100644
index 000000000000..daa9e69301e4
--- /dev/null
+++ b/tools/tests/Rules.mk
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Common unit test fragment.
+#
+# Copyright 2025 Ford Motor Company
+
+include $(XEN_ROOT)/tools/Rules.mk
+
+define list-c-headers
+$(shell sed -n \
+ 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
+endef
+
+# Generate mock environment by replicating header file hierarchy;
+# each header file will point to a harness header.
+#
+# $1 target
+# $2 list of test harnesses
+define emit-harness-nested-rule
+$(1): $(2)
+ set -e; \
+ mkdir -p $$(@D); \
+ for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
+
+endef
+
+# Helper function to emit mocked hypervisor code dependencies.
+#
+# $1 Harness file name.
+# $2 Mocked hypervisor file name.
+# $3 List of dependencies to mock.
+define emit-harness-rules
+$(foreach x,$(3),$(call emit-harness-nested-rule,\
+ $(CURDIR)/generated/$(x),\
+ $(addprefix $(CURDIR)/,$(1))))
+$(2:.c=.o): $(addprefix $(CURDIR)/generated/,$(3))
+endef
+
+define emit-harness-deps
+$(if $(strip $(3)),$(call emit-harness-rules,$1,$2,$3),)
+endef
+
+# Emit dependencies for mocked hypervisor code.
+#
+# $1 Hypervisor file name.
+# $2 Hypervisor source path.
+# $3 Harness header file name (optional).
+define vpath-with-harness-deps
+vpath $(1) $(2)
+$(call emit-harness-deps,$(or $(strip $(3)),harness.h),\
+ $(1),\
+ $(call list-c-headers,$(2)$(1)))
+endef
+
+.PHONY: all
+all: $(TESTS)
+
+.PHONY: run
+run: $(TESTS)
+ifeq ($(CC),$(HOSTCC))
+ set -e; $(foreach t,$(TESTS),./$(t);)
+else
+ $(warning HOSTCC != CC, will not run test)
+endif
+
+.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
+ set -e; $(foreach t,$(TESTS),$(INSTALL_PROG) $t $(DESTDIR)$(LIBEXEC)/tests;)
+
+.PHONY: uninstall
+uninstall:
+ set -e; $(foreach t,$(TESTS),$(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$t;)
+
+CFLAGS += -D__XEN_TOOLS__
+# Honor mocked hypervisor header over tools/include/xen symlinks
+CFLAGS += -I$(CURDIR)/generated/
+CFLAGS += $(CFLAGS_xeninclude)
+
+ifeq ($(filter clean distclean,$(MAKECMDGOALS)),)
+-include $(DEPS_INCLUDE)
+endif
diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
index dd22a25b038a..2f8cc5380462 100644
--- a/tools/tests/domid/Makefile
+++ b/tools/tests/domid/Makefile
@@ -7,84 +7,7 @@
TESTS := test-domid
XEN_ROOT = $(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-define list-c-headers
-$(shell sed -n \
- 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
-endef
-
-# Generate mock environment by replicating header file hierarchy;
-# each header file will point to a harness header.
-#
-# $1 target
-# $2 list of test harnesses
-define emit-harness-nested-rule
-$(1): $(2)
- set -e; \
- mkdir -p $$(@D); \
- for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
-
-endef
-
-# Helper function to emit mocked hypervisor code dependencies.
-#
-# $1 Harness file name.
-# $2 Mocked hypervisor file name.
-# $3 List of dependencies to mock.
-define emit-harness-rules
-$(foreach x,$(3),$(call emit-harness-nested-rule,\
- $(CURDIR)/generated/$(x),\
- $(addprefix $(CURDIR)/,$(1))))
-$(2:.c=.o): $(addprefix $(CURDIR)/generated/,$(3))
-endef
-
-define emit-harness-deps
-$(if $(strip $(3)),$(call emit-harness-rules,$1,$2,$3),)
-endef
-
-# Emit dependencies for mocked hypervisor code.
-#
-# $1 Hypervisor file name.
-# $2 Hypervisor source path.
-# $3 Harness header file name (optional).
-define vpath-with-harness-deps
-vpath $(1) $(2)
-$(call emit-harness-deps,$(or $(strip $(3)),harness.h),\
- $(1),\
- $(call list-c-headers,$(2)$(1)))
-endef
-
-.PHONY: all
-all: $(TESTS)
-
-.PHONY: run
-run: $(TESTS)
-ifeq ($(CC),$(HOSTCC))
- set -e; $(foreach t,$(TESTS),./$(t);)
-else
- $(warning HOSTCC != CC, will not run test)
-endif
-
-.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
- set -e; $(foreach t,$(TESTS),$(INSTALL_PROG) $t $(DESTDIR)$(LIBEXEC)/tests;)
-
-.PHONY: uninstall
-uninstall:
- set -e; $(foreach t,$(TESTS),$(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$t;)
-
-CFLAGS += -D__XEN_TOOLS__
+include $(XEN_ROOT)/tools/tests/Rules.mk
# find-next-bit.c
CFLAGS-find-next-bit.c += '-DEXPORT_SYMBOL(x)=' \
@@ -96,10 +19,6 @@ CFLAGS-find-next-bit.c += '-DEXPORT_SYMBOL(x)=' \
find-next-bit.o: CFLAGS += $(CFLAGS-find-next-bit.c)
-# Honor mocked hypervisor header over tools/include/xen symlinks
-CFLAGS += -I$(CURDIR)/generated/
-CFLAGS += $(CFLAGS_xeninclude)
-
vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
# Point to the hypervisor code and generate test harness dependencies
@@ -109,5 +28,3 @@ $(eval $(call vpath-with-harness-deps,domid.c,$(XEN_ROOT)/xen/common/))
test-domid: domid.o find-next-bit.o test-domid.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
-
--include $(DEPS_INCLUDE)
--
2.52.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/4] tests: introduce common fragment for unit tests
2026-01-11 4:11 ` [PATCH v2 2/4] tests: introduce common fragment for unit tests dmukhin
@ 2026-01-24 1:05 ` Stefano Stabellini
0 siblings, 0 replies; 13+ messages in thread
From: Stefano Stabellini @ 2026-01-24 1:05 UTC (permalink / raw)
To: dmukhin
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
On Sat, 10 Jan 2026, dmukhin@xen.org wrote:
> From: Denis Mukhin <dmukhin@ford.com>
>
> Move test harness generation into a new shared make fragment so that
> it can be reused by other unit tests.
>
> Signed-off-by: Denis Mukhin <dmukhin@ford.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
> ---
> Changes from v1:
> - moved fragment to tools/tests/
> ---
> tools/tests/Rules.mk | 91 ++++++++++++++++++++++++++++++++++++++
> tools/tests/domid/Makefile | 85 +----------------------------------
> 2 files changed, 92 insertions(+), 84 deletions(-)
> create mode 100644 tools/tests/Rules.mk
>
> diff --git a/tools/tests/Rules.mk b/tools/tests/Rules.mk
> new file mode 100644
> index 000000000000..daa9e69301e4
> --- /dev/null
> +++ b/tools/tests/Rules.mk
> @@ -0,0 +1,91 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Common unit test fragment.
> +#
> +# Copyright 2025 Ford Motor Company
> +
> +include $(XEN_ROOT)/tools/Rules.mk
> +
> +define list-c-headers
> +$(shell sed -n \
> + 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
> +endef
> +
> +# Generate mock environment by replicating header file hierarchy;
> +# each header file will point to a harness header.
> +#
> +# $1 target
> +# $2 list of test harnesses
> +define emit-harness-nested-rule
> +$(1): $(2)
> + set -e; \
> + mkdir -p $$(@D); \
> + for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
> +
> +endef
> +
> +# Helper function to emit mocked hypervisor code dependencies.
> +#
> +# $1 Harness file name.
> +# $2 Mocked hypervisor file name.
> +# $3 List of dependencies to mock.
> +define emit-harness-rules
> +$(foreach x,$(3),$(call emit-harness-nested-rule,\
> + $(CURDIR)/generated/$(x),\
> + $(addprefix $(CURDIR)/,$(1))))
> +$(2:.c=.o): $(addprefix $(CURDIR)/generated/,$(3))
> +endef
> +
> +define emit-harness-deps
> +$(if $(strip $(3)),$(call emit-harness-rules,$1,$2,$3),)
> +endef
> +
> +# Emit dependencies for mocked hypervisor code.
> +#
> +# $1 Hypervisor file name.
> +# $2 Hypervisor source path.
> +# $3 Harness header file name (optional).
> +define vpath-with-harness-deps
> +vpath $(1) $(2)
> +$(call emit-harness-deps,$(or $(strip $(3)),harness.h),\
> + $(1),\
> + $(call list-c-headers,$(2)$(1)))
> +endef
> +
> +.PHONY: all
> +all: $(TESTS)
> +
> +.PHONY: run
> +run: $(TESTS)
> +ifeq ($(CC),$(HOSTCC))
> + set -e; $(foreach t,$(TESTS),./$(t);)
> +else
> + $(warning HOSTCC != CC, will not run test)
> +endif
> +
> +.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
> + set -e; $(foreach t,$(TESTS),$(INSTALL_PROG) $t $(DESTDIR)$(LIBEXEC)/tests;)
> +
> +.PHONY: uninstall
> +uninstall:
> + set -e; $(foreach t,$(TESTS),$(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$t;)
> +
> +CFLAGS += -D__XEN_TOOLS__
> +# Honor mocked hypervisor header over tools/include/xen symlinks
> +CFLAGS += -I$(CURDIR)/generated/
> +CFLAGS += $(CFLAGS_xeninclude)
> +
> +ifeq ($(filter clean distclean,$(MAKECMDGOALS)),)
> +-include $(DEPS_INCLUDE)
> +endif
> diff --git a/tools/tests/domid/Makefile b/tools/tests/domid/Makefile
> index dd22a25b038a..2f8cc5380462 100644
> --- a/tools/tests/domid/Makefile
> +++ b/tools/tests/domid/Makefile
> @@ -7,84 +7,7 @@
> TESTS := test-domid
>
> XEN_ROOT = $(CURDIR)/../../..
> -include $(XEN_ROOT)/tools/Rules.mk
> -
> -define list-c-headers
> -$(shell sed -n \
> - 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
> -endef
> -
> -# Generate mock environment by replicating header file hierarchy;
> -# each header file will point to a harness header.
> -#
> -# $1 target
> -# $2 list of test harnesses
> -define emit-harness-nested-rule
> -$(1): $(2)
> - set -e; \
> - mkdir -p $$(@D); \
> - for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
> -
> -endef
> -
> -# Helper function to emit mocked hypervisor code dependencies.
> -#
> -# $1 Harness file name.
> -# $2 Mocked hypervisor file name.
> -# $3 List of dependencies to mock.
> -define emit-harness-rules
> -$(foreach x,$(3),$(call emit-harness-nested-rule,\
> - $(CURDIR)/generated/$(x),\
> - $(addprefix $(CURDIR)/,$(1))))
> -$(2:.c=.o): $(addprefix $(CURDIR)/generated/,$(3))
> -endef
> -
> -define emit-harness-deps
> -$(if $(strip $(3)),$(call emit-harness-rules,$1,$2,$3),)
> -endef
> -
> -# Emit dependencies for mocked hypervisor code.
> -#
> -# $1 Hypervisor file name.
> -# $2 Hypervisor source path.
> -# $3 Harness header file name (optional).
> -define vpath-with-harness-deps
> -vpath $(1) $(2)
> -$(call emit-harness-deps,$(or $(strip $(3)),harness.h),\
> - $(1),\
> - $(call list-c-headers,$(2)$(1)))
> -endef
> -
> -.PHONY: all
> -all: $(TESTS)
> -
> -.PHONY: run
> -run: $(TESTS)
> -ifeq ($(CC),$(HOSTCC))
> - set -e; $(foreach t,$(TESTS),./$(t);)
> -else
> - $(warning HOSTCC != CC, will not run test)
> -endif
> -
> -.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
> - set -e; $(foreach t,$(TESTS),$(INSTALL_PROG) $t $(DESTDIR)$(LIBEXEC)/tests;)
> -
> -.PHONY: uninstall
> -uninstall:
> - set -e; $(foreach t,$(TESTS),$(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$t;)
> -
> -CFLAGS += -D__XEN_TOOLS__
> +include $(XEN_ROOT)/tools/tests/Rules.mk
>
> # find-next-bit.c
> CFLAGS-find-next-bit.c += '-DEXPORT_SYMBOL(x)=' \
> @@ -96,10 +19,6 @@ CFLAGS-find-next-bit.c += '-DEXPORT_SYMBOL(x)=' \
>
> find-next-bit.o: CFLAGS += $(CFLAGS-find-next-bit.c)
>
> -# Honor mocked hypervisor header over tools/include/xen symlinks
> -CFLAGS += -I$(CURDIR)/generated/
> -CFLAGS += $(CFLAGS_xeninclude)
> -
> vpath find-next-bit.c $(XEN_ROOT)/xen/lib/
>
> # Point to the hypervisor code and generate test harness dependencies
> @@ -109,5 +28,3 @@ $(eval $(call vpath-with-harness-deps,domid.c,$(XEN_ROOT)/xen/common/))
>
> test-domid: domid.o find-next-bit.o test-domid.o
> $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
> -
> --include $(DEPS_INCLUDE)
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 3/4] tests: use unit test fragment in PDX test
2026-01-11 4:11 [PATCH v2 0/4] tools/tests: test harness fragment dmukhin
2026-01-11 4:11 ` [PATCH v2 1/4] tests: fixup domid make fragment dmukhin
2026-01-11 4:11 ` [PATCH v2 2/4] tests: introduce common fragment for unit tests dmukhin
@ 2026-01-11 4:11 ` dmukhin
2026-01-24 1:09 ` Stefano Stabellini
2026-01-11 4:11 ` [PATCH v2 4/4] tests: use unit test fragment in vPCI test dmukhin
3 siblings, 1 reply; 13+ messages in thread
From: dmukhin @ 2026-01-11 4:11 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>
Use the new make fragment to generate test harness code for the PDX unit test.
Move <xen/bitops.h> earlier in xen/common/pdx.c to ensure harness.h is
included before triggering the #ifndef MAX_PFN_RANGES check when building a
unit test.
Additionally, use real <xen/pdx.h> in harness.h instead of a locally
copied version.
Update .gitignore to exclude generated test build-time dependencies.
Not a functional change.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v1:
- new patch
---
tools/tests/pdx/.gitignore | 2 +-
tools/tests/pdx/Makefile | 55 +++++++++-----------------------------
tools/tests/pdx/harness.h | 2 +-
tools/tests/pdx/test-pdx.c | 2 --
xen/common/pdx.c | 3 ++-
5 files changed, 16 insertions(+), 48 deletions(-)
diff --git a/tools/tests/pdx/.gitignore b/tools/tests/pdx/.gitignore
index 1202a531a7fd..1bf9c05985c4 100644
--- a/tools/tests/pdx/.gitignore
+++ b/tools/tests/pdx/.gitignore
@@ -1,3 +1,3 @@
-/pdx.h
+/generated
/test-pdx-mask
/test-pdx-offset
diff --git a/tools/tests/pdx/Makefile b/tools/tests/pdx/Makefile
index 3c431d7c7822..178b451cb611 100644
--- a/tools/tests/pdx/Makefile
+++ b/tools/tests/pdx/Makefile
@@ -1,50 +1,19 @@
-XEN_ROOT=$(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Unit tests for PDX (Page inDeX).
+#
-TARGETS := test-pdx-mask test-pdx-offset
+TESTS := test-pdx-mask test-pdx-offset
-.PHONY: all
-all: $(TARGETS)
+XEN_ROOT = $(CURDIR)/../../..
-.PHONY: run
-run: $(TARGETS)
-ifeq ($(CC),$(HOSTCC))
- set -e; \
- for test in $? ; do \
- ./$$test ; \
- done
-else
- $(warning HOSTCC != CC, will not run test)
-endif
+CFLAGS += -DCONFIG_PDX_MASK_COMPRESSION
-.PHONY: clean
-clean:
- $(RM) -- *.o $(TARGETS) $(DEPS_RM) pdx.h
+include $(XEN_ROOT)/tools/tests/Rules.mk
-.PHONY: distclean
-distclean: clean
- $(RM) -- *~
+CFLAGS += -I $(XEN_ROOT)/xen/include/
-.PHONY: install
-install: all
- $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
- $(INSTALL_PROG) $(TARGETS) $(DESTDIR)$(LIBEXEC)/tests
+$(eval $(call vpath-with-harness-deps,pdx.c,$(XEN_ROOT)/xen/common/))
-.PHONY: uninstall
-uninstall:
- $(RM) -- $(patsubst %,$(DESTDIR)$(LIBEXEC)/tests/%,$(TARGETS))
-
-pdx.h: $(XEN_ROOT)/xen/include/xen/pdx.h
- sed -e '/^#[[:space:]]*include/d' <$< >$@
-
-CFLAGS += -D__XEN_TOOLS__
-CFLAGS += $(APPEND_CFLAGS)
-CFLAGS += $(CFLAGS_xeninclude)
-
-test-pdx-mask: CFLAGS += -DCONFIG_PDX_MASK_COMPRESSION
-test-pdx-offset: CFLAGS += -DCONFIG_PDX_OFFSET_COMPRESSION
-
-test-pdx-%: test-pdx.c pdx.h
- $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -o $@ $< $(APPEND_CFLAGS)
-
--include $(DEPS_INCLUDE)
+test-pdx-%: test-pdx.o pdx.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
diff --git a/tools/tests/pdx/harness.h b/tools/tests/pdx/harness.h
index e49d6bcf92c2..4cdda931feb2 100644
--- a/tools/tests/pdx/harness.h
+++ b/tools/tests/pdx/harness.h
@@ -84,7 +84,7 @@ typedef uint64_t paddr_t;
qsort(elem, nr, size, cmp); \
})
-#include "pdx.h"
+#include <xen/pdx.h>
#endif
diff --git a/tools/tests/pdx/test-pdx.c b/tools/tests/pdx/test-pdx.c
index eefd54c76815..3633c231abaa 100644
--- a/tools/tests/pdx/test-pdx.c
+++ b/tools/tests/pdx/test-pdx.c
@@ -7,8 +7,6 @@
#include "harness.h"
-#include "../../xen/common/pdx.c"
-
struct range {
/* Ranges are defined as [start, end). */
unsigned long start, end;
diff --git a/xen/common/pdx.c b/xen/common/pdx.c
index 7e070ff962e8..068a2098b41b 100644
--- a/xen/common/pdx.c
+++ b/xen/common/pdx.c
@@ -15,11 +15,12 @@
* along with this program; If not, see <http://www.gnu.org/licenses/>.
*/
+#include <xen/bitops.h>
+
/* Trim content when built for the test harness. */
#ifdef __XEN__
#include <xen/init.h>
#include <xen/mm.h>
-#include <xen/bitops.h>
#include <xen/nospec.h>
#include <xen/param.h>
#include <xen/pfn.h>
--
2.52.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 3/4] tests: use unit test fragment in PDX test
2026-01-11 4:11 ` [PATCH v2 3/4] tests: use unit test fragment in PDX test dmukhin
@ 2026-01-24 1:09 ` Stefano Stabellini
2026-02-06 1:42 ` dmukhin
0 siblings, 1 reply; 13+ messages in thread
From: Stefano Stabellini @ 2026-01-24 1:09 UTC (permalink / raw)
To: dmukhin
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
On Sat, 10 Jan 2026, dmukhin@xen.org wrote:
> From: Denis Mukhin <dmukhin@ford.com>
>
> Use the new make fragment to generate test harness code for the PDX unit test.
>
> Move <xen/bitops.h> earlier in xen/common/pdx.c to ensure harness.h is
> included before triggering the #ifndef MAX_PFN_RANGES check when building a
> unit test.
>
> Additionally, use real <xen/pdx.h> in harness.h instead of a locally
> copied version.
>
> Update .gitignore to exclude generated test build-time dependencies.
>
> Not a functional change.
>
> Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> ---
> Changes since v1:
> - new patch
> ---
> tools/tests/pdx/.gitignore | 2 +-
> tools/tests/pdx/Makefile | 55 +++++++++-----------------------------
> tools/tests/pdx/harness.h | 2 +-
> tools/tests/pdx/test-pdx.c | 2 --
> xen/common/pdx.c | 3 ++-
> 5 files changed, 16 insertions(+), 48 deletions(-)
>
> diff --git a/tools/tests/pdx/.gitignore b/tools/tests/pdx/.gitignore
> index 1202a531a7fd..1bf9c05985c4 100644
> --- a/tools/tests/pdx/.gitignore
> +++ b/tools/tests/pdx/.gitignore
> @@ -1,3 +1,3 @@
> -/pdx.h
> +/generated
> /test-pdx-mask
> /test-pdx-offset
> diff --git a/tools/tests/pdx/Makefile b/tools/tests/pdx/Makefile
> index 3c431d7c7822..178b451cb611 100644
> --- a/tools/tests/pdx/Makefile
> +++ b/tools/tests/pdx/Makefile
> @@ -1,50 +1,19 @@
> -XEN_ROOT=$(CURDIR)/../../..
> -include $(XEN_ROOT)/tools/Rules.mk
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Unit tests for PDX (Page inDeX).
> +#
>
> -TARGETS := test-pdx-mask test-pdx-offset
> +TESTS := test-pdx-mask test-pdx-offset
>
> -.PHONY: all
> -all: $(TARGETS)
> +XEN_ROOT = $(CURDIR)/../../..
>
> -.PHONY: run
> -run: $(TARGETS)
> -ifeq ($(CC),$(HOSTCC))
> - set -e; \
> - for test in $? ; do \
> - ./$$test ; \
> - done
> -else
> - $(warning HOSTCC != CC, will not run test)
> -endif
> +CFLAGS += -DCONFIG_PDX_MASK_COMPRESSION
>
> -.PHONY: clean
> -clean:
> - $(RM) -- *.o $(TARGETS) $(DEPS_RM) pdx.h
> +include $(XEN_ROOT)/tools/tests/Rules.mk
>
> -.PHONY: distclean
> -distclean: clean
> - $(RM) -- *~
> +CFLAGS += -I $(XEN_ROOT)/xen/include/
>
> -.PHONY: install
> -install: all
> - $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
> - $(INSTALL_PROG) $(TARGETS) $(DESTDIR)$(LIBEXEC)/tests
> +$(eval $(call vpath-with-harness-deps,pdx.c,$(XEN_ROOT)/xen/common/))
>
> -.PHONY: uninstall
> -uninstall:
> - $(RM) -- $(patsubst %,$(DESTDIR)$(LIBEXEC)/tests/%,$(TARGETS))
> -
> -pdx.h: $(XEN_ROOT)/xen/include/xen/pdx.h
> - sed -e '/^#[[:space:]]*include/d' <$< >$@
> -
> -CFLAGS += -D__XEN_TOOLS__
> -CFLAGS += $(APPEND_CFLAGS)
> -CFLAGS += $(CFLAGS_xeninclude)
> -
> -test-pdx-mask: CFLAGS += -DCONFIG_PDX_MASK_COMPRESSION
> -test-pdx-offset: CFLAGS += -DCONFIG_PDX_OFFSET_COMPRESSION
The test with -DCONFIG_PDX_OFFSET_COMPRESSION is lost?
> -test-pdx-%: test-pdx.c pdx.h
> - $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -o $@ $< $(APPEND_CFLAGS)
> -
> --include $(DEPS_INCLUDE)
> +test-pdx-%: test-pdx.o pdx.o
> + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
> diff --git a/tools/tests/pdx/harness.h b/tools/tests/pdx/harness.h
> index e49d6bcf92c2..4cdda931feb2 100644
> --- a/tools/tests/pdx/harness.h
> +++ b/tools/tests/pdx/harness.h
> @@ -84,7 +84,7 @@ typedef uint64_t paddr_t;
> qsort(elem, nr, size, cmp); \
> })
>
> -#include "pdx.h"
> +#include <xen/pdx.h>
>
> #endif
>
> diff --git a/tools/tests/pdx/test-pdx.c b/tools/tests/pdx/test-pdx.c
> index eefd54c76815..3633c231abaa 100644
> --- a/tools/tests/pdx/test-pdx.c
> +++ b/tools/tests/pdx/test-pdx.c
> @@ -7,8 +7,6 @@
>
> #include "harness.h"
>
> -#include "../../xen/common/pdx.c"
> -
> struct range {
> /* Ranges are defined as [start, end). */
> unsigned long start, end;
> diff --git a/xen/common/pdx.c b/xen/common/pdx.c
> index 7e070ff962e8..068a2098b41b 100644
> --- a/xen/common/pdx.c
> +++ b/xen/common/pdx.c
> @@ -15,11 +15,12 @@
> * along with this program; If not, see <http://www.gnu.org/licenses/>.
> */
>
> +#include <xen/bitops.h>
> +
> /* Trim content when built for the test harness. */
> #ifdef __XEN__
> #include <xen/init.h>
> #include <xen/mm.h>
> -#include <xen/bitops.h>
> #include <xen/nospec.h>
> #include <xen/param.h>
> #include <xen/pfn.h>
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 3/4] tests: use unit test fragment in PDX test
2026-01-24 1:09 ` Stefano Stabellini
@ 2026-02-06 1:42 ` dmukhin
0 siblings, 0 replies; 13+ messages in thread
From: dmukhin @ 2026-02-06 1:42 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, dmukhin
On Fri, Jan 23, 2026 at 05:09:05PM -0800, Stefano Stabellini wrote:
> On Sat, 10 Jan 2026, dmukhin@xen.org wrote:
> > From: Denis Mukhin <dmukhin@ford.com>
> >
> > Use the new make fragment to generate test harness code for the PDX unit test.
> >
> > Move <xen/bitops.h> earlier in xen/common/pdx.c to ensure harness.h is
> > included before triggering the #ifndef MAX_PFN_RANGES check when building a
> > unit test.
> >
> > Additionally, use real <xen/pdx.h> in harness.h instead of a locally
> > copied version.
> >
> > Update .gitignore to exclude generated test build-time dependencies.
> >
> > Not a functional change.
> >
> > Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> > ---
> > Changes since v1:
[..]
> > -
> > -test-pdx-mask: CFLAGS += -DCONFIG_PDX_MASK_COMPRESSION
> > -test-pdx-offset: CFLAGS += -DCONFIG_PDX_OFFSET_COMPRESSION
>
> The test with -DCONFIG_PDX_OFFSET_COMPRESSION is lost?
Whoops, thanks for catching this!
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 4/4] tests: use unit test fragment in vPCI test
2026-01-11 4:11 [PATCH v2 0/4] tools/tests: test harness fragment dmukhin
` (2 preceding siblings ...)
2026-01-11 4:11 ` [PATCH v2 3/4] tests: use unit test fragment in PDX test dmukhin
@ 2026-01-11 4:11 ` dmukhin
2026-01-24 1:25 ` Stefano Stabellini
3 siblings, 1 reply; 13+ messages in thread
From: dmukhin @ 2026-01-11 4:11 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>
Use the new make fragment to generate test harness code for
the vPCI unit test.
Add new prepare-harness target to tests/Rules.mk as an optional step for
setting up mocked environment for building a test.
Fix hypervisor headers used to compile vpci.c against host environment
where necessary.
Fixup emul.h by adding missing mocks to account for new unit test infra.
Update .gitignore to exclude generated test build-time dependencies.
Not a functional change.
Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v1:
- new patch
---
tools/tests/Rules.mk | 5 +++-
tools/tests/vpci/.gitignore | 2 ++
tools/tests/vpci/Makefile | 52 ++++++++++++-------------------------
tools/tests/vpci/emul.h | 50 +++++++++++++----------------------
tools/tests/vpci/main.c | 2 --
xen/include/xen/irq.h | 2 ++
xen/include/xen/list.h | 2 ++
xen/include/xen/numa.h | 2 ++
xen/include/xen/pci.h | 2 ++
xen/include/xen/pfn.h | 2 ++
xen/include/xen/spinlock.h | 2 ++
xen/include/xen/types.h | 4 +++
12 files changed, 56 insertions(+), 71 deletions(-)
create mode 100644 tools/tests/vpci/.gitignore
diff --git a/tools/tests/Rules.mk b/tools/tests/Rules.mk
index daa9e69301e4..26f3d00b5fb9 100644
--- a/tools/tests/Rules.mk
+++ b/tools/tests/Rules.mk
@@ -11,13 +11,16 @@ $(shell sed -n \
's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
endef
+.PHONY: prepare-harness
+prepare-harness:
+
# Generate mock environment by replicating header file hierarchy;
# each header file will point to a harness header.
#
# $1 target
# $2 list of test harnesses
define emit-harness-nested-rule
-$(1): $(2)
+$(1): prepare-harness $(2)
set -e; \
mkdir -p $$(@D); \
for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
diff --git a/tools/tests/vpci/.gitignore b/tools/tests/vpci/.gitignore
new file mode 100644
index 000000000000..d66c2cd56be6
--- /dev/null
+++ b/tools/tests/vpci/.gitignore
@@ -0,0 +1,2 @@
+/generated
+test-vpci
diff --git a/tools/tests/vpci/Makefile b/tools/tests/vpci/Makefile
index 97359ff67f86..695a275675f8 100644
--- a/tools/tests/vpci/Makefile
+++ b/tools/tests/vpci/Makefile
@@ -1,43 +1,23 @@
-XEN_ROOT=$(CURDIR)/../../..
-include $(XEN_ROOT)/tools/Rules.mk
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Unit tests for vPCI.
+#
-TARGET := test_vpci
+TESTS := test-vpci
-.PHONY: all
-all: $(TARGET)
+XEN_ROOT = $(CURDIR)/../../..
+CFLAGS += -DCONFIG_HAS_VPCI
-.PHONY: run
-run: $(TARGET)
-ifeq ($(CC),$(HOSTCC))
- ./$(TARGET)
-else
- $(warning HOSTCC != CC, will not run test)
-endif
+include $(XEN_ROOT)/tools/tests/Rules.mk
-$(TARGET): vpci.c vpci.h list.h main.c emul.h
- $(CC) $(CFLAGS_xeninclude) -g -o $@ vpci.c main.c
+# Do not mock xen/vpci.h header for the test
+prepare-harness:
+ set -e; mkdir -p $(CURDIR)/generated/xen; \
+ ln -sf $(XEN_ROOT)/xen/include/xen/vpci.h $(CURDIR)/generated/xen
-.PHONY: clean
-clean:
- rm -rf $(TARGET) *.o *~ vpci.h vpci.c list.h
+CFLAGS += -I $(XEN_ROOT)/xen/include/
-.PHONY: distclean
-distclean: clean
+$(eval $(call vpath-with-harness-deps,vpci.c,$(XEN_ROOT)/xen/drivers/vpci/,emul.h))
-.PHONY: install
-install: all
- $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
- $(INSTALL_PROG) $(TARGET) $(DESTDIR)$(LIBEXEC)/tests
-
-.PHONY: uninstall
-uninstall:
- $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$(TARGET)
-
-vpci.c: $(XEN_ROOT)/xen/drivers/vpci/vpci.c
- # Remove includes and add the test harness header
- sed -e '/#include/d' -e '1s/^/#include "emul.h"/' <$< >$@
-
-list.h: $(XEN_ROOT)/xen/include/xen/list.h
-vpci.h: $(XEN_ROOT)/xen/include/xen/vpci.h
-list.h vpci.h:
- sed -e '/#include/d' <$< >$@
+test-vpci: vpci.o main.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
diff --git a/tools/tests/vpci/emul.h b/tools/tests/vpci/emul.h
index dd048cffbf9d..979e86e2692e 100644
--- a/tools/tests/vpci/emul.h
+++ b/tools/tests/vpci/emul.h
@@ -34,8 +34,16 @@
#define ASSERT(x) assert(x)
#define __must_check __attribute__((__warn_unused_result__))
#define cf_check
+#define always_inline inline
-#include "list.h"
+typedef int64_t s_time_t;
+typedef uint8_t nodeid_t;
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#include <xen/list.h>
typedef bool rwlock_t;
@@ -43,10 +51,6 @@ struct domain {
rwlock_t pci_lock;
};
-struct pci_dev {
- struct vpci *vpci;
-};
-
struct vcpu
{
struct domain *domain;
@@ -57,35 +61,17 @@ extern const struct pci_dev test_pdev;
typedef bool spinlock_t;
#define spin_lock_init(l) (*(l) = false)
-#define spin_lock(l) (*(l) = true)
-#define spin_unlock(l) (*(l) = false)
-#define read_lock(l) (*(l) = true)
-#define read_unlock(l) (*(l) = false)
-#define write_lock(l) (*(l) = true)
-#define write_unlock(l) (*(l) = false)
+#define spin_lock(l) (assert(!*(l)), *(l) = true)
+#define spin_unlock(l) (assert(*(l)), *(l) = false)
+#define read_lock(l) (assert(!*(l)), *(l) = true)
+#define read_unlock(l) (assert(*(l)), *(l) = false)
+#define write_lock(l) (assert(!*(l)), *(l) = true)
+#define write_unlock(l) (assert(*(l)), *(l) = false)
-typedef union {
- uint32_t sbdf;
- struct {
- union {
- uint16_t bdf;
- struct {
- union {
- struct {
- uint8_t func : 3,
- dev : 5;
- };
- uint8_t extfunc;
- };
- uint8_t bus;
- };
- };
- uint16_t seg;
- };
-} pci_sbdf_t;
+#define lock_evaluate_nospec(l) (l)
+#define block_lock_speculation()
-#define CONFIG_HAS_VPCI
-#include "vpci.h"
+#include <xen/vpci.h>
#define __hwdom_init
diff --git a/tools/tests/vpci/main.c b/tools/tests/vpci/main.c
index 2ef8d4e03f1d..3753417e866d 100644
--- a/tools/tests/vpci/main.c
+++ b/tools/tests/vpci/main.c
@@ -189,8 +189,6 @@ main(int argc, char **argv)
uint32_t r24 = 0;
uint8_t r28, r30;
struct mask_data r32;
- unsigned int i;
- int rc;
INIT_LIST_HEAD(&vpci.handlers);
spin_lock_init(&vpci.lock);
diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h
index 6071b00f621e..f7fa1d0fa29b 100644
--- a/xen/include/xen/irq.h
+++ b/xen/include/xen/irq.h
@@ -1,5 +1,6 @@
#ifndef __XEN_IRQ_H__
#define __XEN_IRQ_H__
+#ifdef __XEN__
#include <xen/cpumask.h>
#include <xen/rcupdate.h>
@@ -208,4 +209,5 @@ unsigned int arch_hwdom_irqs(const struct domain *d);
void arch_evtchn_bind_pirq(struct domain *d, int pirq);
#endif
+#endif /* __XEN__ */
#endif /* __XEN_IRQ_H__ */
diff --git a/xen/include/xen/list.h b/xen/include/xen/list.h
index 98d8482daba1..06d2fa3aed15 100644
--- a/xen/include/xen/list.h
+++ b/xen/include/xen/list.h
@@ -7,8 +7,10 @@
#ifndef __XEN_LIST_H__
#define __XEN_LIST_H__
+#ifdef __XEN__
#include <xen/bug.h>
#include <asm/system.h>
+#endif
/*
* These are non-NULL pointers that will result in faults under normal
diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h
index f6c1f27ca105..80d60fd49178 100644
--- a/xen/include/xen/numa.h
+++ b/xen/include/xen/numa.h
@@ -1,5 +1,6 @@
#ifndef _XEN_NUMA_H
#define _XEN_NUMA_H
+#ifdef __XEN__
#include <xen/mm-frame.h>
@@ -152,4 +153,5 @@ static inline nodeid_t mfn_to_nid(mfn_t mfn)
#define page_to_nid(pg) mfn_to_nid(page_to_mfn(pg))
+#endif /* __XEN__ */
#endif /* _XEN_NUMA_H */
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 130c2a8c1a65..f5965a68ae33 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -14,7 +14,9 @@
#include <xen/numa.h>
#include <xen/pci_regs.h>
#include <xen/pfn.h>
+#ifdef __XEN__
#include <asm/device.h>
+#endif
/*
* The PCI interface treats multi-function devices as independent
diff --git a/xen/include/xen/pfn.h b/xen/include/xen/pfn.h
index 1ca9b095e0df..98ff669d7def 100644
--- a/xen/include/xen/pfn.h
+++ b/xen/include/xen/pfn.h
@@ -1,7 +1,9 @@
#ifndef __XEN_PFN_H__
#define __XEN_PFN_H__
+#ifdef __XEN__
#include <xen/page-size.h>
+#endif
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
diff --git a/xen/include/xen/spinlock.h b/xen/include/xen/spinlock.h
index ca9d8c7ec0a1..ad5094c4eb92 100644
--- a/xen/include/xen/spinlock.h
+++ b/xen/include/xen/spinlock.h
@@ -1,5 +1,6 @@
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
+#ifdef __XEN__
#include <xen/nospec.h>
#include <xen/time.h>
@@ -360,4 +361,5 @@ static always_inline void nrspin_lock_irq(rspinlock_t *l)
#define nrspin_unlock_irqrestore(l, f) _nrspin_unlock_irqrestore(l, f)
#define nrspin_unlock_irq(l) _nrspin_unlock_irq(l)
+#endif /* __XEN__ */
#endif /* __SPINLOCK_H__ */
diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h
index 73ddccbbd5dc..e5d702b48ac0 100644
--- a/xen/include/xen/types.h
+++ b/xen/include/xen/types.h
@@ -4,6 +4,7 @@
#include <xen/stdbool.h>
#include <xen/stdint.h>
+#ifdef __XEN__
/* Linux inherited types which are being phased out */
typedef uint8_t u8;
typedef uint16_t u16;
@@ -15,6 +16,7 @@ typedef uint64_t u64;
typedef __SIZE_TYPE__ size_t;
typedef signed long ssize_t;
+#endif /* __XEN__ */
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __UINTPTR_TYPE__ uintptr_t;
@@ -33,6 +35,7 @@ typedef __UINTPTR_TYPE__ uintptr_t;
#define NULL ((void*)0)
#endif
+#ifdef __XEN__
#define INT8_MIN (-127-1)
#define INT16_MIN (-32767-1)
#define INT32_MIN (-2147483647-1)
@@ -52,6 +55,7 @@ typedef __UINTPTR_TYPE__ uintptr_t;
#define LONG_MAX ((long)(~0UL>>1))
#define LONG_MIN (-LONG_MAX - 1)
#define ULONG_MAX (~0UL)
+#endif /* __XEN__ */
typedef uint16_t __le16;
typedef uint16_t __be16;
--
2.52.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 4/4] tests: use unit test fragment in vPCI test
2026-01-11 4:11 ` [PATCH v2 4/4] tests: use unit test fragment in vPCI test dmukhin
@ 2026-01-24 1:25 ` Stefano Stabellini
2026-02-06 1:47 ` dmukhin
0 siblings, 1 reply; 13+ messages in thread
From: Stefano Stabellini @ 2026-01-24 1:25 UTC (permalink / raw)
To: dmukhin
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, sstabellini, dmukhin
On Sat, 10 Jan 2026, dmukhin@xen.org wrote:
> From: Denis Mukhin <dmukhin@ford.com>
>
> Use the new make fragment to generate test harness code for
> the vPCI unit test.
>
> Add new prepare-harness target to tests/Rules.mk as an optional step for
> setting up mocked environment for building a test.
>
> Fix hypervisor headers used to compile vpci.c against host environment
> where necessary.
>
> Fixup emul.h by adding missing mocks to account for new unit test infra.
>
> Update .gitignore to exclude generated test build-time dependencies.
>
> Not a functional change.
>
> Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> ---
> Changes since v1:
> - new patch
> ---
> tools/tests/Rules.mk | 5 +++-
> tools/tests/vpci/.gitignore | 2 ++
> tools/tests/vpci/Makefile | 52 ++++++++++++-------------------------
> tools/tests/vpci/emul.h | 50 +++++++++++++----------------------
> tools/tests/vpci/main.c | 2 --
> xen/include/xen/irq.h | 2 ++
> xen/include/xen/list.h | 2 ++
> xen/include/xen/numa.h | 2 ++
> xen/include/xen/pci.h | 2 ++
> xen/include/xen/pfn.h | 2 ++
> xen/include/xen/spinlock.h | 2 ++
> xen/include/xen/types.h | 4 +++
> 12 files changed, 56 insertions(+), 71 deletions(-)
> create mode 100644 tools/tests/vpci/.gitignore
>
> diff --git a/tools/tests/Rules.mk b/tools/tests/Rules.mk
> index daa9e69301e4..26f3d00b5fb9 100644
> --- a/tools/tests/Rules.mk
> +++ b/tools/tests/Rules.mk
> @@ -11,13 +11,16 @@ $(shell sed -n \
> 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
> endef
>
> +.PHONY: prepare-harness
> +prepare-harness:
> +
> # Generate mock environment by replicating header file hierarchy;
> # each header file will point to a harness header.
> #
> # $1 target
> # $2 list of test harnesses
> define emit-harness-nested-rule
> -$(1): $(2)
> +$(1): prepare-harness $(2)
> set -e; \
> mkdir -p $$(@D); \
> for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
> diff --git a/tools/tests/vpci/.gitignore b/tools/tests/vpci/.gitignore
> new file mode 100644
> index 000000000000..d66c2cd56be6
> --- /dev/null
> +++ b/tools/tests/vpci/.gitignore
> @@ -0,0 +1,2 @@
> +/generated
> +test-vpci
> diff --git a/tools/tests/vpci/Makefile b/tools/tests/vpci/Makefile
> index 97359ff67f86..695a275675f8 100644
> --- a/tools/tests/vpci/Makefile
> +++ b/tools/tests/vpci/Makefile
> @@ -1,43 +1,23 @@
> -XEN_ROOT=$(CURDIR)/../../..
> -include $(XEN_ROOT)/tools/Rules.mk
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Unit tests for vPCI.
> +#
>
> -TARGET := test_vpci
> +TESTS := test-vpci
>
> -.PHONY: all
> -all: $(TARGET)
> +XEN_ROOT = $(CURDIR)/../../..
> +CFLAGS += -DCONFIG_HAS_VPCI
>
> -.PHONY: run
> -run: $(TARGET)
> -ifeq ($(CC),$(HOSTCC))
> - ./$(TARGET)
> -else
> - $(warning HOSTCC != CC, will not run test)
> -endif
> +include $(XEN_ROOT)/tools/tests/Rules.mk
>
> -$(TARGET): vpci.c vpci.h list.h main.c emul.h
> - $(CC) $(CFLAGS_xeninclude) -g -o $@ vpci.c main.c
> +# Do not mock xen/vpci.h header for the test
> +prepare-harness:
> + set -e; mkdir -p $(CURDIR)/generated/xen; \
> + ln -sf $(XEN_ROOT)/xen/include/xen/vpci.h $(CURDIR)/generated/xen
>
> -.PHONY: clean
> -clean:
> - rm -rf $(TARGET) *.o *~ vpci.h vpci.c list.h
> +CFLAGS += -I $(XEN_ROOT)/xen/include/
>
> -.PHONY: distclean
> -distclean: clean
> +$(eval $(call vpath-with-harness-deps,vpci.c,$(XEN_ROOT)/xen/drivers/vpci/,emul.h))
>
> -.PHONY: install
> -install: all
> - $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
> - $(INSTALL_PROG) $(TARGET) $(DESTDIR)$(LIBEXEC)/tests
> -
> -.PHONY: uninstall
> -uninstall:
> - $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$(TARGET)
> -
> -vpci.c: $(XEN_ROOT)/xen/drivers/vpci/vpci.c
> - # Remove includes and add the test harness header
> - sed -e '/#include/d' -e '1s/^/#include "emul.h"/' <$< >$@
> -
> -list.h: $(XEN_ROOT)/xen/include/xen/list.h
> -vpci.h: $(XEN_ROOT)/xen/include/xen/vpci.h
> -list.h vpci.h:
> - sed -e '/#include/d' <$< >$@
> +test-vpci: vpci.o main.o
> + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
> diff --git a/tools/tests/vpci/emul.h b/tools/tests/vpci/emul.h
> index dd048cffbf9d..979e86e2692e 100644
> --- a/tools/tests/vpci/emul.h
> +++ b/tools/tests/vpci/emul.h
> @@ -34,8 +34,16 @@
> #define ASSERT(x) assert(x)
> #define __must_check __attribute__((__warn_unused_result__))
> #define cf_check
> +#define always_inline inline
>
> -#include "list.h"
> +typedef int64_t s_time_t;
> +typedef uint8_t nodeid_t;
> +typedef uint8_t u8;
> +typedef uint16_t u16;
> +typedef uint32_t u32;
> +typedef uint64_t u64;
> +
> +#include <xen/list.h>
>
> typedef bool rwlock_t;
>
> @@ -43,10 +51,6 @@ struct domain {
> rwlock_t pci_lock;
> };
>
> -struct pci_dev {
> - struct vpci *vpci;
> -};
> -
> struct vcpu
> {
> struct domain *domain;
> @@ -57,35 +61,17 @@ extern const struct pci_dev test_pdev;
>
> typedef bool spinlock_t;
> #define spin_lock_init(l) (*(l) = false)
> -#define spin_lock(l) (*(l) = true)
> -#define spin_unlock(l) (*(l) = false)
> -#define read_lock(l) (*(l) = true)
> -#define read_unlock(l) (*(l) = false)
> -#define write_lock(l) (*(l) = true)
> -#define write_unlock(l) (*(l) = false)
> +#define spin_lock(l) (assert(!*(l)), *(l) = true)
> +#define spin_unlock(l) (assert(*(l)), *(l) = false)
> +#define read_lock(l) (assert(!*(l)), *(l) = true)
> +#define read_unlock(l) (assert(*(l)), *(l) = false)
> +#define write_lock(l) (assert(!*(l)), *(l) = true)
> +#define write_unlock(l) (assert(*(l)), *(l) = false)
>
> -typedef union {
> - uint32_t sbdf;
> - struct {
> - union {
> - uint16_t bdf;
> - struct {
> - union {
> - struct {
> - uint8_t func : 3,
> - dev : 5;
> - };
> - uint8_t extfunc;
> - };
> - uint8_t bus;
> - };
> - };
> - uint16_t seg;
> - };
> -} pci_sbdf_t;
> +#define lock_evaluate_nospec(l) (l)
> +#define block_lock_speculation()
>
> -#define CONFIG_HAS_VPCI
> -#include "vpci.h"
> +#include <xen/vpci.h>
>
> #define __hwdom_init
>
> diff --git a/tools/tests/vpci/main.c b/tools/tests/vpci/main.c
> index 2ef8d4e03f1d..3753417e866d 100644
> --- a/tools/tests/vpci/main.c
> +++ b/tools/tests/vpci/main.c
> @@ -189,8 +189,6 @@ main(int argc, char **argv)
> uint32_t r24 = 0;
> uint8_t r28, r30;
> struct mask_data r32;
> - unsigned int i;
> - int rc;
>
> INIT_LIST_HEAD(&vpci.handlers);
> spin_lock_init(&vpci.lock);
The patch looks OK but I recommend to split the xen headers changes into
a separate patch
> diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h
> index 6071b00f621e..f7fa1d0fa29b 100644
> --- a/xen/include/xen/irq.h
> +++ b/xen/include/xen/irq.h
> @@ -1,5 +1,6 @@
> #ifndef __XEN_IRQ_H__
> #define __XEN_IRQ_H__
> +#ifdef __XEN__
>
> #include <xen/cpumask.h>
> #include <xen/rcupdate.h>
> @@ -208,4 +209,5 @@ unsigned int arch_hwdom_irqs(const struct domain *d);
> void arch_evtchn_bind_pirq(struct domain *d, int pirq);
> #endif
>
> +#endif /* __XEN__ */
> #endif /* __XEN_IRQ_H__ */
> diff --git a/xen/include/xen/list.h b/xen/include/xen/list.h
> index 98d8482daba1..06d2fa3aed15 100644
> --- a/xen/include/xen/list.h
> +++ b/xen/include/xen/list.h
> @@ -7,8 +7,10 @@
> #ifndef __XEN_LIST_H__
> #define __XEN_LIST_H__
>
> +#ifdef __XEN__
> #include <xen/bug.h>
> #include <asm/system.h>
> +#endif
>
> /*
> * These are non-NULL pointers that will result in faults under normal
> diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h
> index f6c1f27ca105..80d60fd49178 100644
> --- a/xen/include/xen/numa.h
> +++ b/xen/include/xen/numa.h
> @@ -1,5 +1,6 @@
> #ifndef _XEN_NUMA_H
> #define _XEN_NUMA_H
> +#ifdef __XEN__
>
> #include <xen/mm-frame.h>
>
> @@ -152,4 +153,5 @@ static inline nodeid_t mfn_to_nid(mfn_t mfn)
>
> #define page_to_nid(pg) mfn_to_nid(page_to_mfn(pg))
>
> +#endif /* __XEN__ */
> #endif /* _XEN_NUMA_H */
> diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
> index 130c2a8c1a65..f5965a68ae33 100644
> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -14,7 +14,9 @@
> #include <xen/numa.h>
> #include <xen/pci_regs.h>
> #include <xen/pfn.h>
> +#ifdef __XEN__
> #include <asm/device.h>
> +#endif
There seem to be other Xen internal declarations in this header. I am
not sure what the best policy should be: try to cover them all within
the #ifdef __XEN__ even thought we don't really have a specific build
test that needs it, or only fix the specific build issue in this patch.
I am OK either way but I wanted to mention the possible choice in case
others have an opinion.
> /*
> * The PCI interface treats multi-function devices as independent
> diff --git a/xen/include/xen/pfn.h b/xen/include/xen/pfn.h
> index 1ca9b095e0df..98ff669d7def 100644
> --- a/xen/include/xen/pfn.h
> +++ b/xen/include/xen/pfn.h
> @@ -1,7 +1,9 @@
> #ifndef __XEN_PFN_H__
> #define __XEN_PFN_H__
>
> +#ifdef __XEN__
> #include <xen/page-size.h>
> +#endif
>
> #define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
> #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
> diff --git a/xen/include/xen/spinlock.h b/xen/include/xen/spinlock.h
> index ca9d8c7ec0a1..ad5094c4eb92 100644
> --- a/xen/include/xen/spinlock.h
> +++ b/xen/include/xen/spinlock.h
> @@ -1,5 +1,6 @@
> #ifndef __SPINLOCK_H__
> #define __SPINLOCK_H__
> +#ifdef __XEN__
>
> #include <xen/nospec.h>
> #include <xen/time.h>
> @@ -360,4 +361,5 @@ static always_inline void nrspin_lock_irq(rspinlock_t *l)
> #define nrspin_unlock_irqrestore(l, f) _nrspin_unlock_irqrestore(l, f)
> #define nrspin_unlock_irq(l) _nrspin_unlock_irq(l)
>
> +#endif /* __XEN__ */
> #endif /* __SPINLOCK_H__ */
> diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h
> index 73ddccbbd5dc..e5d702b48ac0 100644
> --- a/xen/include/xen/types.h
> +++ b/xen/include/xen/types.h
> @@ -4,6 +4,7 @@
> #include <xen/stdbool.h>
> #include <xen/stdint.h>
>
> +#ifdef __XEN__
> /* Linux inherited types which are being phased out */
> typedef uint8_t u8;
> typedef uint16_t u16;
> @@ -15,6 +16,7 @@ typedef uint64_t u64;
> typedef __SIZE_TYPE__ size_t;
>
> typedef signed long ssize_t;
> +#endif /* __XEN__ */
>
> typedef __PTRDIFF_TYPE__ ptrdiff_t;
> typedef __UINTPTR_TYPE__ uintptr_t;
> @@ -33,6 +35,7 @@ typedef __UINTPTR_TYPE__ uintptr_t;
> #define NULL ((void*)0)
> #endif
>
> +#ifdef __XEN__
> #define INT8_MIN (-127-1)
> #define INT16_MIN (-32767-1)
> #define INT32_MIN (-2147483647-1)
> @@ -52,6 +55,7 @@ typedef __UINTPTR_TYPE__ uintptr_t;
> #define LONG_MAX ((long)(~0UL>>1))
> #define LONG_MIN (-LONG_MAX - 1)
> #define ULONG_MAX (~0UL)
> +#endif /* __XEN__ */
>
> typedef uint16_t __le16;
> typedef uint16_t __be16;
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 4/4] tests: use unit test fragment in vPCI test
2026-01-24 1:25 ` Stefano Stabellini
@ 2026-02-06 1:47 ` dmukhin
0 siblings, 0 replies; 13+ messages in thread
From: dmukhin @ 2026-02-06 1:47 UTC (permalink / raw)
To: Stefano Stabellini
Cc: xen-devel, andrew.cooper3, anthony.perard, jbeulich, julien,
michal.orzel, roger.pau, dmukhin
On Fri, Jan 23, 2026 at 05:25:18PM -0800, Stefano Stabellini wrote:
> On Sat, 10 Jan 2026, dmukhin@xen.org wrote:
> > From: Denis Mukhin <dmukhin@ford.com>
> >
> > Use the new make fragment to generate test harness code for
> > the vPCI unit test.
> >
> > Add new prepare-harness target to tests/Rules.mk as an optional step for
> > setting up mocked environment for building a test.
> >
> > Fix hypervisor headers used to compile vpci.c against host environment
> > where necessary.
> >
> > Fixup emul.h by adding missing mocks to account for new unit test infra.
> >
> > Update .gitignore to exclude generated test build-time dependencies.
> >
> > Not a functional change.
> >
> > Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> > ---
> > Changes since v1:
> > - new patch
> > ---
> > tools/tests/Rules.mk | 5 +++-
> > tools/tests/vpci/.gitignore | 2 ++
> > tools/tests/vpci/Makefile | 52 ++++++++++++-------------------------
> > tools/tests/vpci/emul.h | 50 +++++++++++++----------------------
> > tools/tests/vpci/main.c | 2 --
> > xen/include/xen/irq.h | 2 ++
> > xen/include/xen/list.h | 2 ++
> > xen/include/xen/numa.h | 2 ++
> > xen/include/xen/pci.h | 2 ++
> > xen/include/xen/pfn.h | 2 ++
> > xen/include/xen/spinlock.h | 2 ++
> > xen/include/xen/types.h | 4 +++
> > 12 files changed, 56 insertions(+), 71 deletions(-)
> > create mode 100644 tools/tests/vpci/.gitignore
> >
> > diff --git a/tools/tests/Rules.mk b/tools/tests/Rules.mk
> > index daa9e69301e4..26f3d00b5fb9 100644
> > --- a/tools/tests/Rules.mk
> > +++ b/tools/tests/Rules.mk
> > @@ -11,13 +11,16 @@ $(shell sed -n \
> > 's/^[ \t]*# *include[ \t]*[<"]\([^">]*\)[">].*/\1/p' $(1) 2>/dev/null)
> > endef
> >
> > +.PHONY: prepare-harness
> > +prepare-harness:
> > +
> > # Generate mock environment by replicating header file hierarchy;
> > # each header file will point to a harness header.
> > #
> > # $1 target
> > # $2 list of test harnesses
> > define emit-harness-nested-rule
> > -$(1): $(2)
> > +$(1): prepare-harness $(2)
> > set -e; \
> > mkdir -p $$(@D); \
> > for i in $(2); do [ -e $$@ ] || ln -s $$$$i $$@; done
> > diff --git a/tools/tests/vpci/.gitignore b/tools/tests/vpci/.gitignore
> > new file mode 100644
> > index 000000000000..d66c2cd56be6
> > --- /dev/null
> > +++ b/tools/tests/vpci/.gitignore
> > @@ -0,0 +1,2 @@
> > +/generated
> > +test-vpci
> > diff --git a/tools/tests/vpci/Makefile b/tools/tests/vpci/Makefile
> > index 97359ff67f86..695a275675f8 100644
> > --- a/tools/tests/vpci/Makefile
> > +++ b/tools/tests/vpci/Makefile
> > @@ -1,43 +1,23 @@
> > -XEN_ROOT=$(CURDIR)/../../..
> > -include $(XEN_ROOT)/tools/Rules.mk
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +#
> > +# Unit tests for vPCI.
> > +#
> >
> > -TARGET := test_vpci
> > +TESTS := test-vpci
> >
> > -.PHONY: all
> > -all: $(TARGET)
> > +XEN_ROOT = $(CURDIR)/../../..
> > +CFLAGS += -DCONFIG_HAS_VPCI
> >
> > -.PHONY: run
> > -run: $(TARGET)
> > -ifeq ($(CC),$(HOSTCC))
> > - ./$(TARGET)
> > -else
> > - $(warning HOSTCC != CC, will not run test)
> > -endif
> > +include $(XEN_ROOT)/tools/tests/Rules.mk
> >
> > -$(TARGET): vpci.c vpci.h list.h main.c emul.h
> > - $(CC) $(CFLAGS_xeninclude) -g -o $@ vpci.c main.c
> > +# Do not mock xen/vpci.h header for the test
> > +prepare-harness:
> > + set -e; mkdir -p $(CURDIR)/generated/xen; \
> > + ln -sf $(XEN_ROOT)/xen/include/xen/vpci.h $(CURDIR)/generated/xen
> >
> > -.PHONY: clean
> > -clean:
> > - rm -rf $(TARGET) *.o *~ vpci.h vpci.c list.h
> > +CFLAGS += -I $(XEN_ROOT)/xen/include/
> >
> > -.PHONY: distclean
> > -distclean: clean
> > +$(eval $(call vpath-with-harness-deps,vpci.c,$(XEN_ROOT)/xen/drivers/vpci/,emul.h))
> >
> > -.PHONY: install
> > -install: all
> > - $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests
> > - $(INSTALL_PROG) $(TARGET) $(DESTDIR)$(LIBEXEC)/tests
> > -
> > -.PHONY: uninstall
> > -uninstall:
> > - $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$(TARGET)
> > -
> > -vpci.c: $(XEN_ROOT)/xen/drivers/vpci/vpci.c
> > - # Remove includes and add the test harness header
> > - sed -e '/#include/d' -e '1s/^/#include "emul.h"/' <$< >$@
> > -
> > -list.h: $(XEN_ROOT)/xen/include/xen/list.h
> > -vpci.h: $(XEN_ROOT)/xen/include/xen/vpci.h
> > -list.h vpci.h:
> > - sed -e '/#include/d' <$< >$@
> > +test-vpci: vpci.o main.o
> > + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
> > diff --git a/tools/tests/vpci/emul.h b/tools/tests/vpci/emul.h
> > index dd048cffbf9d..979e86e2692e 100644
> > --- a/tools/tests/vpci/emul.h
> > +++ b/tools/tests/vpci/emul.h
> > @@ -34,8 +34,16 @@
> > #define ASSERT(x) assert(x)
> > #define __must_check __attribute__((__warn_unused_result__))
> > #define cf_check
> > +#define always_inline inline
> >
> > -#include "list.h"
> > +typedef int64_t s_time_t;
> > +typedef uint8_t nodeid_t;
> > +typedef uint8_t u8;
> > +typedef uint16_t u16;
> > +typedef uint32_t u32;
> > +typedef uint64_t u64;
> > +
> > +#include <xen/list.h>
> >
> > typedef bool rwlock_t;
> >
> > @@ -43,10 +51,6 @@ struct domain {
> > rwlock_t pci_lock;
> > };
> >
> > -struct pci_dev {
> > - struct vpci *vpci;
> > -};
> > -
> > struct vcpu
> > {
> > struct domain *domain;
> > @@ -57,35 +61,17 @@ extern const struct pci_dev test_pdev;
> >
> > typedef bool spinlock_t;
> > #define spin_lock_init(l) (*(l) = false)
> > -#define spin_lock(l) (*(l) = true)
> > -#define spin_unlock(l) (*(l) = false)
> > -#define read_lock(l) (*(l) = true)
> > -#define read_unlock(l) (*(l) = false)
> > -#define write_lock(l) (*(l) = true)
> > -#define write_unlock(l) (*(l) = false)
> > +#define spin_lock(l) (assert(!*(l)), *(l) = true)
> > +#define spin_unlock(l) (assert(*(l)), *(l) = false)
> > +#define read_lock(l) (assert(!*(l)), *(l) = true)
> > +#define read_unlock(l) (assert(*(l)), *(l) = false)
> > +#define write_lock(l) (assert(!*(l)), *(l) = true)
> > +#define write_unlock(l) (assert(*(l)), *(l) = false)
> >
> > -typedef union {
> > - uint32_t sbdf;
> > - struct {
> > - union {
> > - uint16_t bdf;
> > - struct {
> > - union {
> > - struct {
> > - uint8_t func : 3,
> > - dev : 5;
> > - };
> > - uint8_t extfunc;
> > - };
> > - uint8_t bus;
> > - };
> > - };
> > - uint16_t seg;
> > - };
> > -} pci_sbdf_t;
> > +#define lock_evaluate_nospec(l) (l)
> > +#define block_lock_speculation()
> >
> > -#define CONFIG_HAS_VPCI
> > -#include "vpci.h"
> > +#include <xen/vpci.h>
> >
> > #define __hwdom_init
> >
> > diff --git a/tools/tests/vpci/main.c b/tools/tests/vpci/main.c
> > index 2ef8d4e03f1d..3753417e866d 100644
> > --- a/tools/tests/vpci/main.c
> > +++ b/tools/tests/vpci/main.c
> > @@ -189,8 +189,6 @@ main(int argc, char **argv)
> > uint32_t r24 = 0;
> > uint8_t r28, r30;
> > struct mask_data r32;
> > - unsigned int i;
> > - int rc;
> >
> > INIT_LIST_HEAD(&vpci.handlers);
> > spin_lock_init(&vpci.lock);
>
> The patch looks OK but I recommend to split the xen headers changes into
> a separate patch
Will do.
>
>
> > diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h
> > index 6071b00f621e..f7fa1d0fa29b 100644
> > --- a/xen/include/xen/irq.h
> > +++ b/xen/include/xen/irq.h
> > @@ -1,5 +1,6 @@
> > #ifndef __XEN_IRQ_H__
> > #define __XEN_IRQ_H__
> > +#ifdef __XEN__
> >
> > #include <xen/cpumask.h>
> > #include <xen/rcupdate.h>
> > @@ -208,4 +209,5 @@ unsigned int arch_hwdom_irqs(const struct domain *d);
> > void arch_evtchn_bind_pirq(struct domain *d, int pirq);
> > #endif
> >
> > +#endif /* __XEN__ */
> > #endif /* __XEN_IRQ_H__ */
> > diff --git a/xen/include/xen/list.h b/xen/include/xen/list.h
> > index 98d8482daba1..06d2fa3aed15 100644
> > --- a/xen/include/xen/list.h
> > +++ b/xen/include/xen/list.h
> > @@ -7,8 +7,10 @@
> > #ifndef __XEN_LIST_H__
> > #define __XEN_LIST_H__
> >
> > +#ifdef __XEN__
> > #include <xen/bug.h>
> > #include <asm/system.h>
> > +#endif
> >
> > /*
> > * These are non-NULL pointers that will result in faults under normal
> > diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h
> > index f6c1f27ca105..80d60fd49178 100644
> > --- a/xen/include/xen/numa.h
> > +++ b/xen/include/xen/numa.h
> > @@ -1,5 +1,6 @@
> > #ifndef _XEN_NUMA_H
> > #define _XEN_NUMA_H
> > +#ifdef __XEN__
> >
> > #include <xen/mm-frame.h>
> >
> > @@ -152,4 +153,5 @@ static inline nodeid_t mfn_to_nid(mfn_t mfn)
> >
> > #define page_to_nid(pg) mfn_to_nid(page_to_mfn(pg))
> >
> > +#endif /* __XEN__ */
> > #endif /* _XEN_NUMA_H */
> > diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
> > index 130c2a8c1a65..f5965a68ae33 100644
> > --- a/xen/include/xen/pci.h
> > +++ b/xen/include/xen/pci.h
> > @@ -14,7 +14,9 @@
> > #include <xen/numa.h>
> > #include <xen/pci_regs.h>
> > #include <xen/pfn.h>
> > +#ifdef __XEN__
> > #include <asm/device.h>
> > +#endif
>
> There seem to be other Xen internal declarations in this header. I am
> not sure what the best policy should be: try to cover them all within
> the #ifdef __XEN__ even thought we don't really have a specific build
> test that needs it, or only fix the specific build issue in this patch.
>
> I am OK either way but I wanted to mention the possible choice in case
> others have an opinion.
I decided to modify the headers, because I hope is there will be more unit
tests using these headers.
>
>
> > /*
> > * The PCI interface treats multi-function devices as independent
> > diff --git a/xen/include/xen/pfn.h b/xen/include/xen/pfn.h
> > index 1ca9b095e0df..98ff669d7def 100644
> > --- a/xen/include/xen/pfn.h
> > +++ b/xen/include/xen/pfn.h
> > @@ -1,7 +1,9 @@
> > #ifndef __XEN_PFN_H__
> > #define __XEN_PFN_H__
> >
> > +#ifdef __XEN__
> > #include <xen/page-size.h>
> > +#endif
> >
> > #define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
> > #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
> > diff --git a/xen/include/xen/spinlock.h b/xen/include/xen/spinlock.h
> > index ca9d8c7ec0a1..ad5094c4eb92 100644
> > --- a/xen/include/xen/spinlock.h
> > +++ b/xen/include/xen/spinlock.h
> > @@ -1,5 +1,6 @@
> > #ifndef __SPINLOCK_H__
> > #define __SPINLOCK_H__
> > +#ifdef __XEN__
> >
> > #include <xen/nospec.h>
> > #include <xen/time.h>
> > @@ -360,4 +361,5 @@ static always_inline void nrspin_lock_irq(rspinlock_t *l)
> > #define nrspin_unlock_irqrestore(l, f) _nrspin_unlock_irqrestore(l, f)
> > #define nrspin_unlock_irq(l) _nrspin_unlock_irq(l)
> >
> > +#endif /* __XEN__ */
> > #endif /* __SPINLOCK_H__ */
> > diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h
> > index 73ddccbbd5dc..e5d702b48ac0 100644
> > --- a/xen/include/xen/types.h
> > +++ b/xen/include/xen/types.h
> > @@ -4,6 +4,7 @@
> > #include <xen/stdbool.h>
> > #include <xen/stdint.h>
> >
> > +#ifdef __XEN__
> > /* Linux inherited types which are being phased out */
> > typedef uint8_t u8;
> > typedef uint16_t u16;
> > @@ -15,6 +16,7 @@ typedef uint64_t u64;
> > typedef __SIZE_TYPE__ size_t;
> >
> > typedef signed long ssize_t;
> > +#endif /* __XEN__ */
> >
> > typedef __PTRDIFF_TYPE__ ptrdiff_t;
> > typedef __UINTPTR_TYPE__ uintptr_t;
> > @@ -33,6 +35,7 @@ typedef __UINTPTR_TYPE__ uintptr_t;
> > #define NULL ((void*)0)
> > #endif
> >
> > +#ifdef __XEN__
> > #define INT8_MIN (-127-1)
> > #define INT16_MIN (-32767-1)
> > #define INT32_MIN (-2147483647-1)
> > @@ -52,6 +55,7 @@ typedef __UINTPTR_TYPE__ uintptr_t;
> > #define LONG_MAX ((long)(~0UL>>1))
> > #define LONG_MIN (-LONG_MAX - 1)
> > #define ULONG_MAX (~0UL)
> > +#endif /* __XEN__ */
> >
> > typedef uint16_t __le16;
> > typedef uint16_t __be16;
> > --
> > 2.52.0
> >
^ permalink raw reply [flat|nested] 13+ messages in thread