From nobody Sat Jun 13 07:31:56 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; arc=pass (i=1 dmarc=pass fromdomain=citrix.com); dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=2; a=rsa-sha256; t=1781165371; cv=pass; d=zohomail.com; s=zohoarc; b=LMH5mrdZmk6PGIlr4lbGXZfbhrFKi37E9zZCQEykfEklkPwKmWbhxZCoBSzHZ6a+71OsjX+shOjA4iZgDvhLk62HXxtYBDhJIrA9Assx67yKE3cbhkiYIfzPWVGnAafwPSWW+Do0oI+w1sKVaz0tYeAb4UJ+9EFllFrdYh7ze5I= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781165371; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uhM9SDJwUwcFVUro1wVHTOQpVWwH6UWu6BSkodrAWSI=; b=ZNznDfARFWtAO6n5w00uQq7FlNmGEL0Lx7OHXr8/TNiAohUUDAUB/Ka2ZcY1LuplHV85HJsD3FQcyv6u/mcOmFbwN35hT8Y6M12QDQmUEUB6m+sH6JWQ5KjhzcXzCOanYU5a5HjuAnNGaCCFOloEcvt6DfFFvI15uI9U3RK9I3Y= ARC-Authentication-Results: i=2; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; arc=pass (i=1 dmarc=pass fromdomain=citrix.com); dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1781165371050380.9520403300113; Thu, 11 Jun 2026 01:09:31 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1335176.1597621 (Exim 4.92) (envelope-from ) id 1wXaTH-00063w-OT; Thu, 11 Jun 2026 08:09:03 +0000 Received: by outflank-mailman (output) from mailman id 1335176.1597621; Thu, 11 Jun 2026 08:09:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wXaTH-00063p-LM; Thu, 11 Jun 2026 08:09:03 +0000 Received: by outflank-mailman (input) for mailman id 1335176; Thu, 11 Jun 2026 08:09:02 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wXaTG-00063j-MN for xen-devel@lists.xenproject.org; Thu, 11 Jun 2026 08:09:02 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wXaTF-00A091-OA for xen-devel@lists.xenproject.org; Thu, 11 Jun 2026 10:09:01 +0200 Received: from [10.42.69.7] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a2a6d1d-e002-0a2a0a5209dd-0a2a4507d518-0 for ; Thu, 11 Jun 2026 10:09:01 +0200 Received: from [52.101.48.40] (helo=MW6PR02CU001.outbound.protection.outlook.com) by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.1) (envelope-from ) id 6a2a6d1b-229c-0a2a45070019-3465302846ab-3 for ; Thu, 11 Jun 2026 10:09:01 +0200 Received: from CH7PR03MB7860.namprd03.prod.outlook.com (2603:10b6:610:24e::14) by MWHPR03MB989341.namprd03.prod.outlook.com (2603:10b6:303:2a8::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.13; Thu, 11 Jun 2026 08:08:57 +0000 Received: from CH7PR03MB7860.namprd03.prod.outlook.com ([fe80::f5ba:35df:1c9f:b343]) by CH7PR03MB7860.namprd03.prod.outlook.com ([fe80::f5ba:35df:1c9f:b343%4]) with mapi id 15.21.0113.013; Thu, 11 Jun 2026 08:08:57 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" 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" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xu73hOPIeRcV3Es5GvZ8mlzII+RsZhvglOUf8m2eGSo93gqoLZgK6fQkcaqMNKtmN1iwmpEE8RzvVAUL2armtuTfPzfLqJ1YDcqom78WR/KRF0MEiLlN68uMtjZDDwudqwiJapz9Wr2tw0/d1Ae6//kHUYgFWeYnUQxLZuVCgyn5Exj2LUg9dwYTO5w1iEXvCbxzqXAYQEZ0W7qOmTKDu7C2Cs9Iluxe+3/OeGwaJUpqawxF2t+JwZG2a+nElI30Mj9Wp2utipd2KG3IuBX9lfHxJpx6fpRTMiosCJ7G1TsBw+UgggGlUdnNvJSb0dRzbUyo5DLWwVFcH+8bNuEhGQ== 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=uhM9SDJwUwcFVUro1wVHTOQpVWwH6UWu6BSkodrAWSI=; b=gk2anq1OX+UVTqH+yzscaOtqygxD3afdVAleOaHF/afKxGpmWhH9VB7CUIcff/qCIInyU4uw0rsTrspRDNyOJl7aeNorki0kOGK+V0LPlt9qwKn8l/TQVOPOFxiv/1Ey/2q5SxKc92vrtrHALncBVPaSp+Aya3WPUmUkzIczlkIvmcCIYsRsmKYXSXryspi2UfPobsXTVIy95RPRslRmo3WUKBRqBFUKPkfK/4VF61FzScCiMAur6HzH6GgVBRRFIcDXCYplxiTrTlBYd+oKt4t2T1kZ0kId0Wj8uamUxtMyAG143ruqAReDCWtQMCUXjlZqQrDMKbS1F3SCvj4ywg== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uhM9SDJwUwcFVUro1wVHTOQpVWwH6UWu6BSkodrAWSI=; b=j7W40Gnqko2XHuyuHn0XzPbOpxpABs+4yRCsNL2BFnLHbjbCKbVG8OYCL8SKdtsBZTil9GEQlZX221ZPZLgkQ4GNllz4OsTGqmspq35ZFWjGbQIYldaRYrJZkztGu5ZG2l5k3n3s0Jx7Y2+oLgRVappKyJcPbIWOAoFqZZeVMAE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com; From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Jason Andryuk , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie Subject: [PATCH for-4.22] xen/x86: Change stub page allocation/free Date: Thu, 11 Jun 2026 09:53:42 +0200 Message-ID: <20260611075342.58428-1-roger.pau@citrix.com> X-Mailer: git-send-email 2.53.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BN9PR03CA0512.namprd03.prod.outlook.com (2603:10b6:408:131::7) To CH7PR03MB7860.namprd03.prod.outlook.com (2603:10b6:610:24e::14) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH7PR03MB7860:EE_|MWHPR03MB989341:EE_ X-MS-Office365-Filtering-Correlation-Id: b09eab00-9e20-407b-c8de-08dec790af8d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|1800799024|376014|23010399003|18002099003|56012099006|11063799006; X-Microsoft-Antispam-Message-Info: X4GbKWVq0u1347bDBxdOkPWFBeyrVVfHjhAg1D6AphD5YMgNgZKrjSX9dXX9nls0Xml5nUpn+Qp6M5m+8UJ36mlizPkGg+W5gDyk8gwFUm3s/sb0pWibCPjksJofVjphBlQVSqDkr/rTIBZc8/0Mnh9/IrGq7GSIsEm1Qqt2RCqMimQf4jxpsCU3h+jQ5wzsrsaXnLhAEx7kXVvIbbXUl4kI4/lVC2ysWe+xxGvuG3VXAt6eEOHDvU2lEhRIOrUZlwHW+Gsi+Z22qIoDVnv6/lQyBHzNnw3y7tv2l/C4HJWQppEwfmW5GpKttTfjumknbWyQq1ATnLz6XDluMLL458Q63gfEn7AJBZgta9RVGp6fDRC4E99XjLp9yB1iGaRQccW/6zJttFbwA7B1ZJkTH2yzTkOzyAVqEgfhK8GPdVc2JbFI6IfGl/3KhxGlEBwNWTYIxftaRteayPhnt6UTvVBKL/P7WsHHPq05mwg/NRL9NaLG8PVCDYIAm6b4W+0xokY312pO9/7H3NPrIeGEUNUNB92fTEVUdBJm4Zzau3po/R3Z4GdIMKZG5V2ta+CEAx+LOiy9ysbQVvbNUvog+Pw+7YmNfeX8pwFa5R8Zvfrzzc6CdNeS+mJx0WQaFG3/wNJ+WmtFwNrxShu3Lv57zyre03ja5YXYe7GE0FVtn3xCS3rVbZiN7rnlqfOzleOj X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CH7PR03MB7860.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(1800799024)(376014)(23010399003)(18002099003)(56012099006)(11063799006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?L3BSVmdieHJEU01wYnp6RDA5dnBhblN4SEZVZDFQNlVFSHpPSHNtc2FSTGo4?= =?utf-8?B?ZlZTM3hXOUJ5RTY0UWVRTHVJSFhEd3Z2TXNOZERGRkRuZy8wbjJyL3dDa3Jj?= =?utf-8?B?andBd3NueGlzVFJPdm1MYzBjaUxNODBKZ2hjWlZLOExpRnBycVJQWEZWWjdy?= =?utf-8?B?eUx5ck5BZnE2SEw1RmEyL2crK2Z3MGlWVHp4bjduQURGVExUaXdrTjZ3VGd0?= =?utf-8?B?a0s5OERwSUlyVm5QUHE5bkNHL2FyTFpDQWFXdG5wMmFoYm02WHBtWlNodmov?= =?utf-8?B?Q0k2SUFidTZmUVNWb1dtRFNCVU9HT0tFdHNTN0NvdTVZeG1IazdTalRRY2Rs?= =?utf-8?B?ZU10RDVieXdoSlI4UlZVNkNRcUhWVHFGeDgxakszYXkyTEJKSDhGc1VSZmRD?= =?utf-8?B?YjlGL2RRZlpROWlJbnZhZHM4ZDZ6V2RyRGtFRU0vUkRCTlpvM3lmeERxZG5H?= =?utf-8?B?dkx6NlVvM1hrQWRTcjRaNTE5N3UwUFg2K3ByMUdocHQ2LzNMTko5ODF3Zk1w?= =?utf-8?B?ODBrVG9zVDZKVkRPOGJvSGlueFpaREdncVl4ckpxcWdUbmFsU0tFdWhWUi9s?= =?utf-8?B?eUxDRDd5c0dtSUtUc0JqSzB1QU1OdEQ3MkVlM1BCLy9vaU9GL0JMTUJ6Q3lv?= =?utf-8?B?Vk83UWV0emlIS2wzWHZtSkpJdUs3SkZEZzY2OUZLaUVZNlRNUzM2dWcvTUYv?= =?utf-8?B?ekN0RTh6Sk04VWRGaWs2dVNMOHFySHBJbDZNTlR0WFlBK3E0a2U0UGczTTB1?= =?utf-8?B?Q0NJcTF5elBteGtBVlZXdGJhQ041K1htZ3NuQkh2Q21vZm1WdlhTVGk4UDU2?= =?utf-8?B?WGRhdUVacTJITFRTSkRxekkwSlFxNjY3NStjcFVxTE11SUtLeW40UzNvenlw?= =?utf-8?B?bGNPQVAzanloVjFhV1FmYXFVZllMeXo2cjdqbWI4SklLVkUyeXk0NE5BREVG?= =?utf-8?B?eXNVOG1aMEcwZ0h4WmEvakNyV3UraERpeDIwNndkc1doaWNlRVE0RDU4TU0v?= =?utf-8?B?aEJFaTd3SUhoL2QxM0ZFbmpvNUx4YlF6ckwrUnBoMUErOS9YdzV3cUk1enV2?= =?utf-8?B?NEZZVUxONU9Na0RyUHJpZHhYRGJyTFFBNFE0OWtjUmxQWTYvZEdORU42MDlF?= =?utf-8?B?aTNCYktXcnI5MThUS0pzZG0rckhDOTUyOEJ2eEZJeTJHTmN2eHpzRGxGb1RV?= =?utf-8?B?b252YWphRlFlejJTQ0JaNm42bEk5UFdmR3ZRZmE1Ri80UTY0cytTRUdSVTBX?= =?utf-8?B?VnR5QzcrRzc4a2kydjF6QmladDhIajVoazFFSi9zWlBUYU5LcEJ1Rm16bUh6?= =?utf-8?B?aDY0V2ZhbkE4MjRvSDRPYXhmV01qdWpPem9XWW1XZGtFNC9WeUcxM2pTUGQ0?= =?utf-8?B?YnJCMENWQTYvajJDZWNTU01iVzgzYTVhWWQzci96eVBGWVpIOVYxSjBxb0Y4?= =?utf-8?B?b3FQbjhQN3dub29hK2J4aXhGUmJ5emNwWUZsUzVMUTk3VmJLTlVadEhjaXZF?= =?utf-8?B?N1VVQlEzeUVzVmtoRWlVUmlIbzhwdEsvMUgvKzJKOHo2dk4zMVpwaWdVYS9p?= =?utf-8?B?eE50ajRZR2NHU2FhSFp4RncrVTdadEsyM2JlK3hodC96dTdmblBBVjhOQ1JG?= =?utf-8?B?RFhIaHkzVUhPUVM1Y0tDYkxva29Ob2VxaVBZOGRVSS9NMElrK2EzeGNnQWkz?= =?utf-8?B?YnR1SkdxRm1vN3FyUURUd242d3ptWHd2NU42amhQaDc1dHdDWTY4MThSbUl1?= =?utf-8?B?SUpWclpjL3dYL3dJV0VqNFZBaVltWEJndTZQL2cvME1kU2tEbnZQdSt2cE1R?= =?utf-8?B?dDNzM1VSajY4SzhVcDFpc0ZCbHJsREpTMkxBcWEyVVpiTC9lU1phRkhFTk5p?= =?utf-8?B?c01IUkxCRlVTL1dnRUd6dDQyOW1GQU0rVEFuM3IwOHo2VU5MNXp2OHFBYURJ?= =?utf-8?B?M0tXQzRDT0xjMzhINHZ6L1Z5b2NqejVSOHhZNmJHeVhRZ1dWOGpMZjVLTGxH?= =?utf-8?B?L3g4TnlIWnVqT0k3Z0grU3krczI2cmJXRy9qZzd3VEkrdHFTc3kvcDVTSGUv?= =?utf-8?B?cU5hSEJsbXF4VXJzVks2WXpob3g0enNueVM3OTlRMTU4UzJzeUxsR0tVOXpk?= =?utf-8?B?cHVDTGgrdW9DeHhzNGNybHJUZGVSQUptKzgxQjVKMDFsallOaEVWT0Zid0Nu?= =?utf-8?B?Y2dWc2tjYS9OdWFBcHZJU01HRHpTeGMzbzdibVRrdXZnNHdoN0hjeFkxOWFL?= =?utf-8?B?c2ZwaXdUeUtRSys3OUJ5WnE0bEgxTkVldkNuOGJyb3ZnaUhsY25DVmRiTDYy?= =?utf-8?B?ZjRpNEUydnJQTlN6cVFVMXNvNDlSZWliSlZCcFNOeTBMcWlmaFpQdz09?= X-OriginatorOrg: citrix.com X-MS-Exchange-CrossTenant-Network-Message-Id: b09eab00-9e20-407b-c8de-08dec790af8d X-MS-Exchange-CrossTenant-AuthSource: CH7PR03MB7860.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jun 2026 08:08:56.9495 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 335836de-42ef-43a2-b145-348c2ee9ca5b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 00+GmuMgiZ9re/JuQaBWmDC17yU7aizD8lnRctXHWHLxb8kGZQqdfdm61+baamzxZs13sTmqjM74zfmojJn9LQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR03MB989341 X-purgate-ID: tlsNG-ef75cf/1781165341-23374C48-8D0306E1/0/0 X-purgate-type: clean X-purgate-size: 8111 X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1781165373783158500 From: Jason Andryuk Today the inline 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=3D0 will bring up CPU0, bring up CPU1, bring down CPU1, and free the in-use stub page. CPU0 or subsequent onlined CPUs can write to the re-used page. The new approach uses a global, CPU-indexed dynamically allocated array of stub addresses. However, to handle NUMA aware allocations, we cannot allocate all the memory in advance because of the NUMA dependency. Take advantage of the fact that Xen will attempt to contiguously pack CPUs on the same NUMA node (see normalise_cpu_order()), and on CPU bringup use the same stubs page the previous CPU did if suitable. Note the code would still function properly even if CPUs from NUMA nodes are not contiguously packed, it just consumes more memory. stub pages are no longer freed. They remain referenced in the global CPU-indexed array and are re-used if the CPU is re-onlined. stubs and node_stubs don't have an explicit lock. During boot they are accessed single threaded. During runtime, &cpu_add_remove_lock serializes access. Fixes: 7a66ac8d1633 ("x86: move syscall trampolines off the stack") Signed-off-by: Jason Andryuk Signed-off-by: Roger Pau Monn=C3=A9 --- There are other even more simple options here: for example Andrew proposed to pack stubs contiguously in both the physical and the linear address spaces, at the cost of possibly loosing the NUMA memory affinity between the allocated page and the CPU using it. We have decided to go for a more conservative approach here, that keeps the same properties as the current logic regarding NUMA memory affinity of the stub region. --- xen/arch/x86/include/asm/stubs.h | 2 +- xen/arch/x86/setup.c | 4 +- xen/arch/x86/smpboot.c | 91 +++++++++++++++++--------------- 3 files changed, 49 insertions(+), 48 deletions(-) diff --git a/xen/arch/x86/include/asm/stubs.h b/xen/arch/x86/include/asm/st= ubs.h index a520928e9a50..7d8d302e0623 100644 --- a/xen/arch/x86/include/asm/stubs.h +++ b/xen/arch/x86/include/asm/stubs.h @@ -32,6 +32,6 @@ struct stubs { }; =20 DECLARE_PER_CPU(struct stubs, stubs); -unsigned long alloc_stub_page(unsigned int cpu, unsigned long *mfn); +void init_bsp_stub(void); =20 #endif /* X86_ASM_STUBS_H */ diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 4192edf635b6..cddf8806c877 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -2089,9 +2089,7 @@ void asmlinkage __init noreturn __start_xen(void) =20 init_idle_domain(); =20 - this_cpu(stubs.addr) =3D alloc_stub_page(smp_processor_id(), - &this_cpu(stubs).mfn); - BUG_ON(!this_cpu(stubs.addr)); + init_bsp_stub(); =20 bsp_traps_reinit(); /* Needs stubs allocated, must be before presmp_in= itcalls. */ =20 diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index d8fd71ffab37..3282392317f4 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -20,6 +20,7 @@ #include #include #include +#include =20 #include #include @@ -641,41 +642,61 @@ static int do_boot_cpu(int apicid, int cpu) return rc; } =20 -#define STUB_BUF_CPU_OFFS(cpu) (((cpu) & (STUBS_PER_PAGE - 1)) * STUB_BUF_= SIZE) +/* Dynamically allocated, indexed by CPU. Store physical address of stubs= . */ +static paddr_t *__ro_after_init stubs; =20 -unsigned long alloc_stub_page(unsigned int cpu, unsigned long *mfn) +static bool assign_stub_page(unsigned int cpu) { unsigned long stub_va; - struct page_info *pg; + paddr_t addr =3D stubs[cpu]; =20 - BUILD_BUG_ON(STUBS_PER_PAGE & (STUBS_PER_PAGE - 1)); - - if ( *mfn ) - pg =3D mfn_to_page(_mfn(*mfn)); - else + if ( addr =3D=3D INVALID_PADDR ) { - nodeid_t node =3D cpu_to_node(cpu); - unsigned int memflags =3D node !=3D NUMA_NO_NODE ? MEMF_node(node)= : 0; + nodeid_t nid =3D cpu_to_node(cpu); =20 - pg =3D alloc_domheap_page(NULL, memflags); - if ( !pg ) - return 0; + /* + * Attempt to use the same page as the previous CPU if possible, + * otherwise allocate a new one. + */ + if ( cpu && nid =3D=3D cpu_to_node(cpu - 1) && + PAGE_OFFSET(stubs[cpu - 1] + STUB_BUF_SIZE) ) + addr =3D stubs[cpu - 1] + STUB_BUF_SIZE; + else + { + struct page_info *pg =3D alloc_domheap_page(NULL, MEMF_node(ni= d)); =20 - unmap_domain_page(memset(__map_domain_page(pg), 0xcc, PAGE_SIZE)); + if ( !pg ) + return false; + addr =3D page_to_maddr(pg); + } + stubs[cpu] =3D addr; } =20 stub_va =3D XEN_VIRT_END - FIXADDR_X_SIZE - (cpu + 1) * PAGE_SIZE; - if ( map_pages_to_xen(stub_va, page_to_mfn(pg), 1, + if ( map_pages_to_xen(stub_va, maddr_to_mfn(addr), 1, PAGE_HYPERVISOR_RX | MAP_SMALL_PAGES) ) - { - if ( !*mfn ) - free_domheap_page(pg); - stub_va =3D 0; - } - else if ( !*mfn ) - *mfn =3D mfn_x(page_to_mfn(pg)); + return false; =20 - return stub_va; + per_cpu(stubs.mfn, cpu) =3D PFN_DOWN(addr); + per_cpu(stubs.addr, cpu) =3D stub_va + PAGE_OFFSET(addr); + return true; +} + +void __init init_bsp_stub(void) +{ + const unsigned int num_cpus =3D num_present_cpus(); + unsigned int i; + + ASSERT(!stubs); + stubs =3D xvmalloc_array(typeof(*stubs), num_cpus); + if ( !stubs ) + panic("Unable to allocate stub array"); + + for ( i =3D 0; i < num_cpus; i++ ) + stubs[i] =3D INVALID_PADDR; + + if ( !assign_stub_page(0) ) + panic("Unable to initialize BSP stub region"); } =20 void cpu_exit_clear(unsigned int cpu) @@ -990,19 +1011,12 @@ static void cpu_smpboot_free(unsigned int cpu, bool = remove) { mfn_t mfn =3D _mfn(per_cpu(stubs.mfn, cpu)); unsigned char *stub_page =3D map_domain_page(mfn); - unsigned int i; =20 - memset(stub_page + STUB_BUF_CPU_OFFS(cpu), 0xcc, STUB_BUF_SIZE); - for ( i =3D 0; i < STUBS_PER_PAGE; ++i ) - if ( stub_page[i * STUB_BUF_SIZE] !=3D 0xcc ) - break; + memset(stub_page + PAGE_OFFSET(stubs[cpu]), 0xcc, STUB_BUF_SIZE); unmap_domain_page(stub_page); destroy_xen_mappings(per_cpu(stubs.addr, cpu) & PAGE_MASK, (per_cpu(stubs.addr, cpu) | ~PAGE_MASK) + 1); per_cpu(stubs.addr, cpu) =3D 0; - per_cpu(stubs.mfn, cpu) =3D 0; - if ( i =3D=3D STUBS_PER_PAGE ) - free_domheap_page(mfn_to_page(mfn)); } =20 if ( IS_ENABLED(CONFIG_PV32) ) @@ -1041,10 +1055,9 @@ void *cpu_alloc_stack(unsigned int cpu) static int cpu_smpboot_alloc(unsigned int cpu) { struct cpu_info *info; - unsigned int i, memflags =3D 0; + unsigned int memflags =3D 0; nodeid_t node =3D cpu_to_node(cpu); seg_desc_t *gdt; - unsigned long stub_page; int rc =3D -ENOMEM; =20 if ( node !=3D NUMA_NO_NODE ) @@ -1092,18 +1105,8 @@ static int cpu_smpboot_alloc(unsigned int cpu) memcpy(per_cpu(idt, cpu), bsp_idt, sizeof(bsp_idt)); disable_each_ist(per_cpu(idt, cpu)); =20 - for ( stub_page =3D 0, i =3D cpu & ~(STUBS_PER_PAGE - 1); - i < nr_cpu_ids && i <=3D (cpu | (STUBS_PER_PAGE - 1)); ++i ) - if ( cpu_online(i) && cpu_to_node(i) =3D=3D node ) - { - per_cpu(stubs.mfn, cpu) =3D per_cpu(stubs.mfn, i); - break; - } - BUG_ON(i =3D=3D cpu); - stub_page =3D alloc_stub_page(cpu, &per_cpu(stubs.mfn, cpu)); - if ( !stub_page ) + if ( !assign_stub_page(cpu) ) goto out; - per_cpu(stubs.addr, cpu) =3D stub_page + STUB_BUF_CPU_OFFS(cpu); =20 rc =3D setup_cpu_root_pgt(cpu); if ( rc ) --=20 2.53.0