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

[PATCH v2 3/3] xen/x86: Change stub page allocation/free logic


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jason Andryuk <jason.andryuk@xxxxxxx>
  • Date: Thu, 4 Jun 2026 19:18:37 -0400
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • 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=culTp5npElJ0EQCOehNU8q2yQwTQyvCCP0XUiLS9xBE=; b=mSKaooZ3gqYoBiHPajhtKWDi1nbAxT6nBKdEhuaNM/rEoCzzOch5RHEaXqwxbIgwI96PTh9QbRxe/v/aEfNyxuVqJi9ml8bux61IWr6UuIeDV/nvPvswAHBd4BHGVenD+PhsKExygSCkb2Db4wZGJTvtMVyJrm9IcZQF2ELyami2SLVvEHqIW9WOImbI60ZVp9iSHOE2MAyPeeu/raw81cXUf4IvvQ9OeQJN7eejexsV7wYxZoIMb4NOv3iw7lrgb7gmWpzZF1dBDBWgjXgsX8VvxajqWpwTQr4yJaVHgY6iFFUGwFjobRt9tylwxlWlb1/mP/oGvdry6VgXJfMNVA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DjOyVFw2/QVWNFLjXHaF6j+8H+X0sF6WJ5mXvqdeS1bmpo3EnssE3I60+rwa0bjyXUFTEhyUAFIk/P6y8gZkP2ffhiTI/e5n0Yfp6ggbed+iVRGUwAB1o/5otyL7I/4r9AixlfmbAyiHjxDqKWWG2jocUVItF23S04XrmQ2pcti80UUPWsyA+vSMD/35JiV5bfXE6WSAFcx9H7jabNRXXmGDRwXQcneC/L6tXdkmxfl8wDd+ms+eM/LDYhaKpmsR3JHtdTCgASA0XZTi5Vs0/zB99HA+JXxgzCzCmp2CK8qSHTSlSJ48dHp4A2Mv2wjiJNGOBXxXF82dpe5n9FPWZQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Cc: Jason Andryuk <jason.andryuk@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>
  • Delivery-date: Thu, 04 Jun 2026 23:47:07 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Today the inine tracking of the stub page is problematic.  0xcc is used
to indicate unused, but it is also a "clear value."  A !CONFIG_PV build
with smt=0 will bring up CPU0, bring up CPU1, bring down CPU1, and free
the in-use stub page.  Subsequent CPU onlining can write to the re-used
page.

Each stub page accomodates 32 stub regions, and each CPU uses an offset
into its portion of the page.  Each CPU used a CPU-specific mapping of
the whole page.  The virtual address of the CPU-specific mapping is
fixed, so it can be used to track the stub page.

Remove the actual free-ing from cpu_smpboot_free().  Use the stub_va PTE
to track the underlying page.  destroy_xen_mapping() would clear the
mapping, so replace it with modify_xen_mappings() to retain the PFN in
the PTE (with NX set).

In alloc_stub_page(), check for a valid PFN in the stub_va PTE.  When
found, it will be used.  This handles re-onlining a CPU.  Otherwise the
existing logic is retained to use a passed in mfn or allocate one.
These paths handle to bringing up new CPUs.

If all CPUs for a stub page are offlined, the page will be dangling and
unusable.  But it will be re-used if CPUs are re-onlined.

Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
 xen/arch/x86/smpboot.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 7241dba621..11937175a9 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -647,11 +647,21 @@ unsigned long alloc_stub_page(unsigned int cpu, unsigned 
long *mfn)
 {
     unsigned long stub_va;
     struct page_info *pg;
+    mfn_t stub_mfn;
 
     BUILD_BUG_ON(STUBS_PER_PAGE & (STUBS_PER_PAGE - 1));
 
-    if ( *mfn )
+    stub_va = XEN_VIRT_END - FIXADDR_X_SIZE - (cpu + 1) * PAGE_SIZE;
+    stub_mfn = page_walk_mfn(virt_to_mfn(idle_pg_table), stub_va);
+    if ( mfn_valid(stub_mfn) )
+    {
+        *mfn = mfn_x(stub_mfn);
+        pg = mfn_to_page(stub_mfn);
+    }
+    else if ( *mfn )
+    {
         pg = mfn_to_page(_mfn(*mfn));
+    }
     else
     {
         nodeid_t node = cpu_to_node(cpu);
@@ -664,7 +674,6 @@ unsigned long alloc_stub_page(unsigned int cpu, unsigned 
long *mfn)
         unmap_domain_page(memset(__map_domain_page(pg), 0xcc, PAGE_SIZE));
     }
 
-    stub_va = XEN_VIRT_END - FIXADDR_X_SIZE - (cpu + 1) * PAGE_SIZE;
     if ( map_pages_to_xen(stub_va, page_to_mfn(pg), 1,
                           PAGE_HYPERVISOR_RX | MAP_SMALL_PAGES) )
     {
@@ -990,19 +999,18 @@ static void cpu_smpboot_free(unsigned int cpu, bool 
remove)
     {
         mfn_t mfn = _mfn(per_cpu(stubs.mfn, cpu));
         unsigned char *stub_page = map_domain_page(mfn);
-        unsigned int i;
 
         memset(stub_page + STUB_BUF_CPU_OFFS(cpu), 0xcc, STUB_BUF_SIZE);
-        for ( i = 0; i < STUBS_PER_PAGE; ++i )
-            if ( stub_page[i * STUB_BUF_SIZE] != 0xcc )
-                break;
         unmap_domain_page(stub_page);
-        destroy_xen_mappings(per_cpu(stubs.addr, cpu) & PAGE_MASK,
-                             (per_cpu(stubs.addr, cpu) | ~PAGE_MASK) + 1);
+        /*
+         * destroy_xen_mappings() clears the PFN from the PTE, but we want to
+         * keep it for potential reuse if re-onlined.  Pass _PAGE_PRESENT to
+         * retain the PFN.
+         */
+        modify_xen_mappings(per_cpu(stubs.addr, cpu) & PAGE_MASK,
+                            (per_cpu(stubs.addr, cpu) | ~PAGE_MASK) + 1,
+                            _PAGE_PRESENT | _PAGE_NX);
         per_cpu(stubs.addr, cpu) = 0;
-        per_cpu(stubs.mfn, cpu) = 0;
-        if ( i == STUBS_PER_PAGE )
-            free_domheap_page(mfn_to_page(mfn));
     }
 
     if ( IS_ENABLED(CONFIG_PV32) )
-- 
2.54.0




 


Rackspace

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