On 17/12/2025 5:01 pm, Roger Pau Monné wrote: > On Tue, Dec 16, 2025 at 04:32:30PM +0000, Andrew Cooper wrote: >> Add some basic testing of the memory claims mechainsm. >> >> Signed-off-by: Andrew Cooper <[email protected]> > Reviewed-by: Roger Pau Monné <[email protected]>
Thanks. > Some nits below. > >> --- >> CC: Anthony PERARD <[email protected]> >> CC: Michal Orzel <[email protected]> >> CC: Jan Beulich <[email protected]> >> CC: Julien Grall <[email protected]> >> CC: Roger Pau Monné <[email protected]> >> CC: Stefano Stabellini <[email protected]> >> --- >> tools/tests/Makefile | 1 + >> tools/tests/mem-claim/.gitignore | 1 + >> tools/tests/mem-claim/Makefile | 38 +++++ >> tools/tests/mem-claim/test-mem-claim.c | 190 +++++++++++++++++++++++++ >> 4 files changed, 230 insertions(+) >> create mode 100644 tools/tests/mem-claim/.gitignore >> create mode 100644 tools/tests/mem-claim/Makefile >> create mode 100644 tools/tests/mem-claim/test-mem-claim.c >> >> diff --git a/tools/tests/Makefile b/tools/tests/Makefile >> index e566bd169952..6477a4386dda 100644 >> --- a/tools/tests/Makefile >> +++ b/tools/tests/Makefile >> @@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk >> >> SUBDIRS-y := >> SUBDIRS-y += domid >> +SUBDIRS-y += mem-claim >> SUBDIRS-y += paging-mempool >> SUBDIRS-y += pdx >> SUBDIRS-y += rangeset >> diff --git a/tools/tests/mem-claim/.gitignore >> b/tools/tests/mem-claim/.gitignore >> new file mode 100644 >> index 000000000000..cfcee00b819b >> --- /dev/null >> +++ b/tools/tests/mem-claim/.gitignore >> @@ -0,0 +1 @@ >> +test-mem-claim >> diff --git a/tools/tests/mem-claim/Makefile b/tools/tests/mem-claim/Makefile >> new file mode 100644 >> index 000000000000..76ba3e3c8bef >> --- /dev/null >> +++ b/tools/tests/mem-claim/Makefile >> @@ -0,0 +1,38 @@ >> +XEN_ROOT = $(CURDIR)/../../.. >> +include $(XEN_ROOT)/tools/Rules.mk >> + >> +TARGET := test-mem-claim >> + >> +.PHONY: all >> +all: $(TARGET) >> + >> +.PHONY: clean >> +clean: >> + $(RM) -- *.o $(TARGET) $(DEPS_RM) >> + >> +.PHONY: distclean >> +distclean: clean >> + $(RM) -- *~ >> + >> +.PHONY: install >> +install: all >> + $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests >> + $(INSTALL_PROG) $(TARGET) $(DESTDIR)$(LIBEXEC)/tests >> + >> +.PHONY: uninstall >> +uninstall: >> + $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$(TARGET) >> + >> +CFLAGS += $(CFLAGS_xeninclude) >> +CFLAGS += $(CFLAGS_libxenctrl) >> +CFLAGS += $(APPEND_CFLAGS) >> + >> +LDFLAGS += $(LDLIBS_libxenctrl) >> +LDFLAGS += $(APPEND_LDFLAGS) >> + >> +%.o: Makefile >> + >> +$(TARGET): test-mem-claim.o >> + $(CC) -o $@ $< $(LDFLAGS) >> + >> +-include $(DEPS_INCLUDE) >> diff --git a/tools/tests/mem-claim/test-mem-claim.c >> b/tools/tests/mem-claim/test-mem-claim.c >> new file mode 100644 >> index 000000000000..78eae9091f52 >> --- /dev/null >> +++ b/tools/tests/mem-claim/test-mem-claim.c >> @@ -0,0 +1,190 @@ > SPDX header comment? Will do. > >> +#include <err.h> >> +#include <errno.h> >> +#include <inttypes.h> >> +#include <stdio.h> >> +#include <string.h> >> +#include <sys/mman.h> >> + >> +#include <xenctrl.h> >> +#include <xenforeignmemory.h> >> +#include <xengnttab.h> >> +#include <xen-tools/common-macros.h> >> + >> +static unsigned int nr_failures; >> +#define fail(fmt, ...) \ >> +({ \ >> + nr_failures++; \ >> + (void)printf(fmt, ##__VA_ARGS__); \ >> +}) >> + >> +static xc_interface *xch; >> +static uint32_t domid = -1; > I think you could use domid_t and DOMID_INVALID as the default value? Sadly can't. Domid's are strictly uint32_t due to xc_domain_create() taking it by pointer. > And then you could avoid the casting and just use domid < > DOMID_FIRST_RESERVED as the check for whether the cleanup is needed? Hmm. The DOMID_INVALID part of that is nice-ish, but having the boundary check be a different constant isn't. Maybe I can just do != DOMID_INVALID for the cleanup. > >> + >> +static xc_physinfo_t physinfo; >> + >> +static struct xen_domctl_createdomain create = { >> + .flags = XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap, >> + .max_vcpus = 1, >> + .max_grant_frames = 1, >> + .grant_opts = XEN_DOMCTL_GRANT_version(1), >> + >> + .arch = { >> +#if defined(__x86_64__) || defined(__i386__) >> + .emulation_flags = XEN_X86_EMU_LAPIC, >> +#endif >> + }, >> +}; >> + >> +static void run_tests(void) >> +{ >> + int rc; >> + >> + /* >> + * Check that the system is quiescent. Outstanding claims is a global >> + * field. >> + */ >> + rc = xc_physinfo(xch, &physinfo); >> + if ( rc ) >> + return fail("Failed to obtain physinfo: %d - %s\n", >> + errno, strerror(errno)); >> + >> + printf("Free pages: %"PRIu64", Oustanding claims: %"PRIu64"\n", >> + physinfo.free_pages, physinfo.outstanding_pages); >> + >> + if ( physinfo.outstanding_pages ) >> + return fail(" Test needs running on a quiescent system\n"); >> + >> + /* >> + * We want any arbitrary domain. Start with HVM/HAP, falling back to >> + * HVM/Shadow and then to PV. The dom0 running this test case is one of >> + * these modes. >> + */ >> +#if defined(__x86_64__) || defined(__i386__) >> + if ( !(physinfo.capabilities & XEN_SYSCTL_PHYSCAP_hap) ) >> + create.flags &= ~XEN_DOMCTL_CDF_hap; >> + >> + if ( !(physinfo.capabilities & >> (XEN_SYSCTL_PHYSCAP_hap|XEN_SYSCTL_PHYSCAP_shadow)) || >> + !(physinfo.capabilities & XEN_SYSCTL_PHYSCAP_hvm) ) >> + { >> + create.flags &= ~XEN_DOMCTL_CDF_hvm; >> + create.arch.emulation_flags = 0; >> + } >> +#endif >> + >> + rc = xc_domain_create(xch, &domid, &create); >> + if ( rc ) >> + return fail(" Domain create failure: %d - %s\n", >> + errno, strerror(errno)); >> + >> + rc = xc_domain_setmaxmem(xch, domid, -1); >> + if ( rc ) >> + return fail(" Failed to set maxmem: %d - %s\n", >> + errno, strerror(errno)); >> + >> + printf(" Created d%u\n", domid); >> + >> + /* >> + * Creating a domain shouldn't change the claim. Check it's still 0. >> + */ >> + rc = xc_physinfo(xch, &physinfo); >> + if ( rc ) >> + return fail(" Failed to obtain physinfo: %d - %s\n", >> + errno, strerror(errno)); >> + >> + if ( physinfo.outstanding_pages ) >> + return fail(" Unexpected outstanding claim of %"PRIu64" pages\n", >> + physinfo.outstanding_pages); >> + >> + /* >> + * Set a claim for 4M. This should be the only claim in the system, and >> + * show up globally. >> + */ >> + rc = xc_domain_claim_pages(xch, domid, 4*1024*1024/4096); > You can use MB(4) (macro is in tools/common-macros.h) I think for > clarity? Same below with MB(2). I'll wrap it as MB_TO_PAGES() to hide the divide by 4k. ~Andrew
