From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Jan Beulich" <JBeulich@suse.com>,
"Roger Pau Monné" <roger.pau@citrix.com>, "Wei Liu" <wl@xen.org>,
"Stefano Stabellini" <sstabellini@kernel.org>,
"Julien Grall" <julien@xen.org>,
"Volodymyr Babchuk" <Volodymyr_Babchuk@epam.com>,
"Bertrand Marquis" <bertrand.marquis@arm.com>,
"Henry Wang" <Henry.Wang@arm.com>,
"Anthony PERARD" <anthony.perard@citrix.com>
Subject: [PATCH 2/4] tools/tests: Unit test for paging mempool size
Date: Thu, 17 Nov 2022 01:08:02 +0000 [thread overview]
Message-ID: <20221117010804.9384-3-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <20221117010804.9384-1-andrew.cooper3@citrix.com>
Exercise some basic functionality of the new
xc_{get,set}_paging_mempool_size() hypercalls.
This passes on x86, but fails currently on ARM. ARM will be fixed up in
future patches.
This is part of XSA-409 / CVE-2022-33747.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Release-acked-by: Henry Wang <Henry.Wang@arm.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Wei Liu <wl@xen.org>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
CC: Bertrand Marquis <bertrand.marquis@arm.com>
CC: Henry Wang <Henry.Wang@arm.com>
CC: Anthony PERARD <anthony.perard@citrix.com>
x86 Shadow is complicated because of how it behaves for PV guests, and because
of how it forms a simultaneous equation with tot_pages. This will require
more work to untangle.
v2:
* s/p2m/paging/
* Fix CFLAGS_libxenforeginmemory typo
---
tools/tests/Makefile | 1 +
tools/tests/paging-mempool/.gitignore | 1 +
tools/tests/paging-mempool/Makefile | 42 ++++++
tools/tests/paging-mempool/test-paging-mempool.c | 181 +++++++++++++++++++++++
4 files changed, 225 insertions(+)
create mode 100644 tools/tests/paging-mempool/.gitignore
create mode 100644 tools/tests/paging-mempool/Makefile
create mode 100644 tools/tests/paging-mempool/test-paging-mempool.c
diff --git a/tools/tests/Makefile b/tools/tests/Makefile
index d99146d56a64..1319c3a9d88c 100644
--- a/tools/tests/Makefile
+++ b/tools/tests/Makefile
@@ -11,6 +11,7 @@ endif
SUBDIRS-y += xenstore
SUBDIRS-y += depriv
SUBDIRS-y += vpci
+SUBDIRS-y += paging-mempool
.PHONY: all clean install distclean uninstall
all clean distclean install uninstall: %: subdirs-%
diff --git a/tools/tests/paging-mempool/.gitignore b/tools/tests/paging-mempool/.gitignore
new file mode 100644
index 000000000000..2f9305b7cc07
--- /dev/null
+++ b/tools/tests/paging-mempool/.gitignore
@@ -0,0 +1 @@
+test-paging-mempool
diff --git a/tools/tests/paging-mempool/Makefile b/tools/tests/paging-mempool/Makefile
new file mode 100644
index 000000000000..5d49497710e0
--- /dev/null
+++ b/tools/tests/paging-mempool/Makefile
@@ -0,0 +1,42 @@
+XEN_ROOT = $(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+TARGET := test-paging-mempool
+
+.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_BIN)
+ $(INSTALL_PROG) $(TARGET) $(DESTDIR)$(LIBEXEC_BIN)
+
+.PHONY: uninstall
+uninstall:
+ $(RM) -- $(DESTDIR)$(LIBEXEC_BIN)/$(TARGET)
+
+CFLAGS += $(CFLAGS_xeninclude)
+CFLAGS += $(CFLAGS_libxenctrl)
+CFLAGS += $(CFLAGS_libxenforeignmemory)
+CFLAGS += $(CFLAGS_libxengnttab)
+CFLAGS += $(APPEND_CFLAGS)
+
+LDFLAGS += $(LDLIBS_libxenctrl)
+LDFLAGS += $(LDLIBS_libxenforeignmemory)
+LDFLAGS += $(LDLIBS_libxengnttab)
+LDFLAGS += $(APPEND_LDFLAGS)
+
+%.o: Makefile
+
+$(TARGET): test-paging-mempool.o
+ $(CC) -o $@ $< $(LDFLAGS)
+
+-include $(DEPS_INCLUDE)
diff --git a/tools/tests/paging-mempool/test-paging-mempool.c b/tools/tests/paging-mempool/test-paging-mempool.c
new file mode 100644
index 000000000000..942a2fde19c7
--- /dev/null
+++ b/tools/tests/paging-mempool/test-paging-mempool.c
@@ -0,0 +1,181 @@
+#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/libs.h>
+
+static unsigned int nr_failures;
+#define fail(fmt, ...) \
+({ \
+ nr_failures++; \
+ (void)printf(fmt, ##__VA_ARGS__); \
+})
+
+static xc_interface *xch;
+static uint32_t domid;
+
+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 uint64_t default_mempool_size_bytes =
+#if defined(__x86_64__) || defined(__i386__)
+ 256 << 12; /* Only x86 HAP for now. x86 Shadow needs more work. */
+#elif defined (__arm__) || defined(__aarch64__)
+ 16 << 12;
+#endif
+
+static void run_tests(void)
+{
+ xen_pfn_t physmap[] = { 0 };
+ uint64_t size_bytes, old_size_bytes;
+ int rc;
+
+ printf("Test default mempool size\n");
+
+ rc = xc_get_paging_mempool_size(xch, domid, &size_bytes);
+ if ( rc )
+ return fail(" Fail: get mempool size: %d - %s\n",
+ errno, strerror(errno));
+
+ printf("mempool size %"PRIu64" bytes (%"PRIu64"kB, %"PRIu64"MB)\n",
+ size_bytes, size_bytes >> 10, size_bytes >> 20);
+
+
+ /*
+ * Check that the domain has the expected default allocation size. This
+ * will fail if the logic in Xen is altered without an equivelent
+ * adjustment here.
+ */
+ if ( size_bytes != default_mempool_size_bytes )
+ return fail(" Fail: size %"PRIu64" != expected size %"PRIu64"\n",
+ size_bytes, default_mempool_size_bytes);
+
+
+ printf("Test that allocate doesn't alter pool size\n");
+
+ /*
+ * Populate the domain with some RAM. This will cause more of the mempool
+ * to be used.
+ */
+ old_size_bytes = size_bytes;
+
+ rc = xc_domain_setmaxmem(xch, domid, -1);
+ if ( rc )
+ return fail(" Fail: setmaxmem: : %d - %s\n",
+ errno, strerror(errno));
+
+ rc = xc_domain_populate_physmap_exact(xch, domid, 1, 0, 0, physmap);
+ if ( rc )
+ return fail(" Fail: populate physmap: %d - %s\n",
+ errno, strerror(errno));
+
+ /*
+ * Re-get the p2m size. Should not have changed as a consequence of
+ * populate physmap.
+ */
+ rc = xc_get_paging_mempool_size(xch, domid, &size_bytes);
+ if ( rc )
+ return fail(" Fail: get mempool size: %d - %s\n",
+ errno, strerror(errno));
+
+ if ( old_size_bytes != size_bytes )
+ return fail(" Fail: mempool size changed %"PRIu64" => %"PRIu64"\n",
+ old_size_bytes, size_bytes);
+
+
+
+ printf("Test bad set size\n");
+
+ /*
+ * Check that setting a non-page size results in failure.
+ */
+ rc = xc_set_paging_mempool_size(xch, domid, size_bytes + 1);
+ if ( rc != -1 || errno != EINVAL )
+ return fail(" Fail: Bad set size: expected -1/EINVAL, got %d/%d - %s\n",
+ rc, errno, strerror(errno));
+
+
+ printf("Test very large set size\n");
+
+ /*
+ * Check that setting a large P2M size succeeds. This is expecting to
+ * trigger continuations.
+ */
+ rc = xc_set_paging_mempool_size(xch, domid, 64 << 20);
+ if ( rc )
+ return fail(" Fail: Set size 64MB: %d - %s\n",
+ errno, strerror(errno));
+
+
+ /*
+ * Check that the reported size matches what set consumed.
+ */
+ rc = xc_get_paging_mempool_size(xch, domid, &size_bytes);
+ if ( rc )
+ return fail(" Fail: get p2m mempool size: %d - %s\n",
+ errno, strerror(errno));
+
+ if ( size_bytes != 64 << 20 )
+ return fail(" Fail: expected mempool size %u, got %"PRIu64"\n",
+ 64 << 20, size_bytes);
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+
+ printf("Paging mempool tests\n");
+
+ xch = xc_interface_open(NULL, NULL, 0);
+
+ if ( !xch )
+ err(1, "xc_interface_open");
+
+ rc = xc_domain_create(xch, &domid, &create);
+ if ( rc )
+ {
+ if ( errno == EINVAL || errno == EOPNOTSUPP )
+ printf(" Skip: %d - %s\n", errno, strerror(errno));
+ else
+ fail(" Domain create failure: %d - %s\n",
+ errno, strerror(errno));
+ goto out;
+ }
+
+ printf(" Created d%u\n", domid);
+
+ run_tests();
+
+ rc = xc_domain_destroy(xch, domid);
+ if ( rc )
+ fail(" Failed to destroy domain: %d - %s\n",
+ errno, strerror(errno));
+ out:
+ return !!nr_failures;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.11.0
next prev parent reply other threads:[~2022-11-17 1:08 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-17 1:08 [PATCH for-4.17 0/4] XSA-409 fixes Andrew Cooper
2022-11-17 1:08 ` [PATCH 1/4] xen: Introduce non-broken hypercalls for the paging mempool size Andrew Cooper
2022-11-17 2:08 ` Stefano Stabellini
2022-11-17 10:18 ` Jan Beulich
2022-11-17 15:51 ` Andrew Cooper
2022-11-17 14:10 ` Anthony PERARD
2022-11-17 1:08 ` Andrew Cooper [this message]
2022-11-17 10:39 ` [PATCH 2/4] tools/tests: Unit test for " Jan Beulich
2022-11-17 16:27 ` Andrew Cooper
2022-11-17 14:20 ` Anthony PERARD
2022-11-17 1:08 ` [PATCH 3/4] xen/arm, libxl: Revert XEN_DOMCTL_shadow_op; use p2m mempool hypercalls Andrew Cooper
2022-11-17 2:12 ` Stefano Stabellini
2022-11-17 14:07 ` Anthony PERARD
2022-11-17 1:08 ` [PATCH 4/4] xen/arm: Correct the p2m pool size calculations Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221117010804.9384-3-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=Henry.Wang@arm.com \
--cc=JBeulich@suse.com \
--cc=Volodymyr_Babchuk@epam.com \
--cc=anthony.perard@citrix.com \
--cc=bertrand.marquis@arm.com \
--cc=julien@xen.org \
--cc=roger.pau@citrix.com \
--cc=sstabellini@kernel.org \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.