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

[PATCH XTF 6/6] Add test mmu-pt-update-swap


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Kevin Lampis <kevin.lampis@xxxxxxxxxx>
  • Date: Thu, 12 Nov 2026 10:00:05 +0000
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=WENd0E22XD9Go2PbAvzQt+Aa3h6x7D9Dlx+/ss54nAc=; b=C/e9zDi8p4SRuIdQvf2UTCxi9/oHAmw5Wrwwuu5dpYpAX6QUBYSs98oSSHdag7mPvFnhOYhpPozBQNZJsu1FybeIGW+OhP6gdZR3XAaOWqQza5dujbm12hYadK4quO9S5/bDNdVuyU+hfkBvabFsUSbF82ROkBFV9V4ZxlAKoeGlGfI6nu+TujhqR2FzjWxb6QmHBysdo6g/cQLaPeQ8S0gS1Hv2wEEf75g5DGevK8gYTBTl8ec1xtIe9aakVAzsubAodOAgLZWUYa05NzNMJj5z9+EOpWuqtNzI63OZ3okxroiENIpI6wZU9FQC37wOuXWt7Y//BF2eYpulBvVedw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=t6Nvtp1lYplDFGSXfjv882NaZ9HNwDLhmvZKzrvi4gsDI+x0rt6KzIuQGs4lntlfWrGd3CsNKRA9UYgLfUNfPijC9gEFsjBrGApSCNgmvRTng5nbvJ6MZRa5b6ZgsQwiWys0TfSwYQtEzkVYAwtV+mCGmZ2Rq5p/udhUoiFfYyqCBtn5Nw5XEVkkdFqJ4+xPew++Zt7avb0KFDslghqLLC+2P2UdjFuiCkGpNQaCc1uVOIeMfjDxZ1Jqrr2ipSQeIbAhnshxEjBXkxNBuYQCSAHY+nC9Eko8eTdWtwi6AP5OAN3B7QmwIZBXxsiE1JAD0aU6A6aLUag95vssGWzU9w==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: jbeulich@xxxxxxxx, andrew.cooper3@xxxxxxxxxx, roger@xxxxxxxxxxxxxx, teddy.astie@xxxxxxxxxx, Kevin Lampis <kevin.lampis@xxxxxxxxxx>
  • Delivery-date: Thu, 12 Nov 2026 10:00:59 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Test for new mmu_update subop MMU_PT_UPDATE_SWAP

Signed-off-by: Kevin Lampis <kevin.lampis@xxxxxxxxxx>
---
Changes in v5:
- New patch
---
 include/xen/version.h             |   8 +++
 include/xen/xen.h                 |   1 +
 tests/mmu-pt-update-swap/Makefile |   9 +++
 tests/mmu-pt-update-swap/main.c   | 114 ++++++++++++++++++++++++++++++
 4 files changed, 132 insertions(+)
 create mode 100644 tests/mmu-pt-update-swap/Makefile
 create mode 100644 tests/mmu-pt-update-swap/main.c

diff --git a/include/xen/version.h b/include/xen/version.h
index 45ce490b4b8f..73719a358c9a 100644
--- a/include/xen/version.h
+++ b/include/xen/version.h
@@ -24,6 +24,14 @@ typedef struct xen_compile_info xen_compile_info_t;
 #define XENVER_changeset 4
 typedef char xen_changeset_info_t[64];
 
+#define XENVER_get_features 6
+struct xen_feature_info {
+    uint32_t     submap_idx;    /* IN: which 32-bit submap to return */
+    uint32_t     submap;        /* OUT: 32-bit submap */
+};
+typedef struct xen_feature_info xen_feature_info_t;
+#define XENFEAT_mmu_pt_update_swap        21
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */
 
 /*
diff --git a/include/xen/xen.h b/include/xen/xen.h
index 11af167702cd..8a239ea2b046 100644
--- a/include/xen/xen.h
+++ b/include/xen/xen.h
@@ -246,6 +246,7 @@ struct mmu_update {
 #define MMU_NORMAL_PT_UPDATE      0 /* checked '*ptr = val'. ptr is MA.      */
 #define MMU_MACHPHYS_UPDATE       1 /* ptr = MA of frame to modify entry for */
 #define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr = val | (*ptr&(A|D)) */
+#define MMU_PT_UPDATE_SWAP        4 /* Update and return the old value. */
     uint64_t ptr;       /* Machine address of PTE. */
     uint64_t val;       /* New contents of PTE.    */
 };
diff --git a/tests/mmu-pt-update-swap/Makefile 
b/tests/mmu-pt-update-swap/Makefile
new file mode 100644
index 000000000000..9e01c6bace63
--- /dev/null
+++ b/tests/mmu-pt-update-swap/Makefile
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := mmu-pt-update-swap
+CATEGORY  := functional
+TEST-ENVS := $(PV_ENVIRONMENTS)
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/mmu-pt-update-swap/main.c b/tests/mmu-pt-update-swap/main.c
new file mode 100644
index 000000000000..b43fcef57ed1
--- /dev/null
+++ b/tests/mmu-pt-update-swap/main.c
@@ -0,0 +1,114 @@
+/**
+ * @file tests/mmu-pt-update-swap/main.c
+ * @ref mmu-pt-update-swap
+ *
+ * Test new mmu_update subop MMU_PT_UPDATE_SWAP
+ * - Create a minimal l1 page table
+ * - Create a page table entry for a test page
+ * - Swap the page table entry with 0 using the new subop
+ * - If the feature is supported by Xen then
+ *   - Test the new page table entry is zero
+ *   - Test the old page table entry was returned by the hypercall
+ * - If the feature is not supported by Xen then
+ *   - Test the hypercall failed
+ *
+ * @see tests/mmu-pt-update-swap/main.c
+ */
+#include <xtf.h>
+
+const char test_title[] = "mmu-pt-update-swap";
+
+static intpte_t nl1t[L1_PT_ENTRIES] __page_aligned_bss;
+static uint8_t target_page[PAGE_SIZE] __page_aligned_bss;
+
+static bool check_pte(intpte_t value, intpte_t expected)
+{
+    const intpte_t v = value & PADDR_MASK & PAGE_MASK;
+    const intpte_t e = expected & PADDR_MASK & PAGE_MASK;
+    if ( v != e )
+    {
+        xtf_failure("Fail: PTE mismatch got %"PRIpte" expected %"PRIpte"\n", 
v, e);
+        return false;
+    }
+
+    return true;
+}
+
+void test_main(void)
+{
+    long rc = 0;
+
+    rc = hypercall_update_va_mapping(_u(nl1t),
+                                     pte_from_virt(nl1t, PF_SYM(AD, P)),
+                                     UVMF_INVLPG | UVMF_LOCAL);
+    if ( rc )
+        return xtf_failure("Failed to remap nl1t as readonly: %ld\n", rc);
+
+    /* Turn nl1t into a L1 page table page */
+    mmuext_op_t pin = {
+        .cmd       = MMUEXT_PIN_L1_TABLE,
+        .arg1.mfn  = virt_to_mfn(nl1t),
+    };
+    rc = hypercall_mmuext_op(&pin, 1, NULL, DOMID_SELF);
+    if ( rc )
+        return xtf_failure("Failed to pin nl1t: %ld\n", rc);
+
+    /* Add target_page into our new nl1t */
+    intpte_t test_pte = pte_from_virt(target_page, PF_SYM(AD, RW, P));
+    mmu_update_t req = {
+        .ptr = virt_to_maddr(&nl1t[0]),
+        .val = test_pte,
+    };
+    unsigned int done = 0;
+    rc = hypercall_mmu_update(&req, 1, &done, DOMID_SELF);
+    if ( rc || done != 1 )
+        return xtf_failure("Failed mmu_update: rc %ld, done %u\n", rc, done);
+
+    /* Confirm target_page was added correctly */
+    if ( !check_pte(nl1t[0], test_pte) )
+        return;
+
+    /* Try to swap the target_page PTE with 0 using the new subop */
+    req.ptr = virt_to_maddr(&nl1t[0]) | MMU_PT_UPDATE_SWAP;
+    req.val = 0;
+    rc = hypercall_mmu_update(&req, 1, &done, DOMID_SELF);
+
+    /* Check if Xen supports the new subop */
+    xen_feature_info_t fi = { .submap_idx = 0 };
+    if ( hypercall_xen_version(XENVER_get_features, &fi) )
+        return xtf_failure("Failed to run hypercall_xen_version\n");
+
+    if ( fi.submap & (1 << XENFEAT_mmu_pt_update_swap) )
+    {
+        if ( rc )
+            return xtf_failure("Fail: MMU_PT_UPDATE_SWAP rc=%ld expected 
%d\n", rc, 0);
+
+        if ( done != 1 )
+            return xtf_failure("Fail: MMU_PT_UPDATE_SWAP done=%d expected 
%d\n", done, 1);
+
+        /* Check the new PTE value is 0 */
+        if ( !check_pte(nl1t[0], 0) )
+            return;
+
+        /* Check the old PTE value was returned by the hypercall */
+        if ( !check_pte(req.val, test_pte) )
+            return;
+    }
+    else
+    {
+        if ( !rc )
+            return xtf_failure("Fail: MMU_PT_UPDATE_SWAP unsupported but 
didn't fail rc=%ld\n", rc);
+    }
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.52.0




 


Rackspace

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