From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417922; cv=none; d=zohomail.com; s=zohoarc; b=BNyt0Mv/CZQzW4Pqzybk+NTPlRMgd3cBXbpWlO1ibUs8idCVs3T+uQ+mgZ2VWFDAMo9jAJEDQWY4sJpbxx9xYvPpaNA89Zdk6t1ZKIWfdRg/89oQJ33Tyoij3PDow4e+Oo4MJt7qqPpmuX0ZKtTncnWdnBlTAWtTx6NTfsFfOHw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417922; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zxbjBN87wnj0AUXMvgpO31kjAgExGSkQK2SRaU2awvM=; b=kopL6upkkcBhPoIjvEpwo4FqSIjWfU75IxfiUXjKwvHYJzCo4PHnbg81IcGot1DuEE03ajur5Xd3cgCYhYsoY33kkX5cwuU00A2jUR93ZJmKWgKTpIwTYyffyshdurLW+02F6P02YoE6oMpwloDgUYiK3RzcgyoZURxAP3qWzJk= ARC-Authentication-Results: i=1; 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; 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 1750417921993715.7369829398655; Fri, 20 Jun 2025 04:12:01 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020844.1396965 (Exim 4.92) (envelope-from ) id 1uSZel-0005Xo-OD; Fri, 20 Jun 2025 11:11:39 +0000 Received: by outflank-mailman (output) from mailman id 1020844.1396965; Fri, 20 Jun 2025 11:11:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZel-0005Xh-L0; Fri, 20 Jun 2025 11:11:39 +0000 Received: by outflank-mailman (input) for mailman id 1020844; Fri, 20 Jun 2025 11:11:38 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZek-0005XV-AG for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:38 +0000 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [2a00:1450:4864:20::32c]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 548d64f5-4dc7-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 13:11:36 +0200 (CEST) Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-43ea40a6e98so19883375e9.1 for ; Fri, 20 Jun 2025 04:11:36 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a6d0f18215sm1745673f8f.29.2025.06.20.04.11.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:34 -0700 (PDT) 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" X-Inumbo-ID: 548d64f5-4dc7-11f0-b894-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417895; x=1751022695; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zxbjBN87wnj0AUXMvgpO31kjAgExGSkQK2SRaU2awvM=; b=F4WW8zMa2sNxMiNbWZ93+M+ZG2Q2ni2wuLtPOYkBsi5M/JkSjwn0/H8GnZvg8zfksx b+qrpXKuWXSrcJvGoI5pxRyeuwOXU95374bFdVYNJ5n+kLy+ycL2wCbLSZUXEI6npurh Fz11vSE0adPSVTB4fnGCd0Me+CX0kiyPwHx/o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417895; x=1751022695; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zxbjBN87wnj0AUXMvgpO31kjAgExGSkQK2SRaU2awvM=; b=nWbpLs84TDQOpiMlzKhijNqv+2k8CjzntPRiCylTo19Vpm0krgEEH53RNyPYbUl2/C bohxwvvTuVRgPk01/k6VL8ul4Aci4cDShZxBnZqvfg62qlflZtstfA6Mug0czahZrWRH dtuxAsh7pE7RXS+57GsX7Ffcm8L/e+OfFCvt//B4i5sMIEZIjIwOqX40eThEtKAdJnJH PsYJjDFWkEhm4dSVBTfxGL80BSW9TXiTpy4uULSCSd/JwOnv01m0H2gEEOP6562TKoFV GsJJ5FH7GaKzDitWtea3Rivi50tKPpklF/CWo5k8B/00AOcsXqukjkuZYBEXYd0tCdql Wofw== X-Gm-Message-State: AOJu0YzZtLIEMO39yafehOtGB8XvzxVHpXm4h3eP85I1NE8WgAe07Ge6 gDzNnpq9j/s92VhRuU2Z64zb3JgpiLzDtxRKWLkUhlBhfsV5u1V0C0tGc+PABnl8gyiyJ2oaC1r 9pZLB X-Gm-Gg: ASbGnctU0P3Nf1hqSlORuUH+sr8kH6CiXtlzcjWP2UYj1852Luu/IrQ3LCiJiK+W0El C5pLVJvomx2KS5IwUuXsQiH2StblmVOF3Tjjl+beE1lvPe4IGsSRcN8ay0R9L+/NZs6mUZZuygM 18/YRGFJvbGejpckXrw10rp9g5kK7FX+xeHW86zXkgbSwE44jybBSTrqhpPf86IDOHtNRK61S0z z1OWr0oYqMdohOhhZmsvcaFXKJC96qdpYoDS0vZ+NRKBr9L7ENTn821m56mNKcTDkCNqRbzbyke iPSQUU1TV2dJlxr5bvNL56T6uYIxC/b7G516eYqiy34/2rOj3uwNZ7Z+/Zyydm5b2GUPP4DRTZC qWMVEiil4I+SmJcneRo4wHo9hbphHHg== X-Google-Smtp-Source: AGHT+IHIHPRlAOwa/O+aSU6bCJZbLczlcEvaLpUOCx3IIEZT5rimkIyoz4ISU2abc5Fd+dvjKFczNg== X-Received: by 2002:a05:600c:4747:b0:43d:300f:fa1d with SMTP id 5b1f17b1804b1-453659c0c2fmr24473355e9.31.1750417895165; Fri, 20 Jun 2025 04:11:35 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Jan Beulich , Andrew Cooper , Anthony PERARD , Michal Orzel , Julien Grall , Stefano Stabellini Subject: [PATCH v2 1/8] x86/pdx: simplify calculation of domain struct allocation boundary Date: Fri, 20 Jun 2025 13:11:23 +0200 Message-ID: <20250620111130.29057-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417924419116600 When not using CONFIG_BIGMEM there are some restrictions in the address width for allocations of the domain structure, as it's PDX truncated to 32 bits it's stashed into page_info structure for domain allocated pages. The current logic to calculate this limit is based on the internals of the PDX compression used, which is not strictly required. Instead simplify the logic to rely on the existing PDX to PFN conversion helpers used elsewhere. This has the added benefit of allowing alternative PDX compression algorithms to be implemented without requiring to change the calculation of the domain structure allocation boundary. As a side effect introduce pdx_to_paddr() conversion macro and use it. Signed-off-by: Roger Pau Monn=C3=A9 Reviewed-by: Jan Beulich --- Changes since v1: - Use sizeof_field(). - Introduce and use pdx_to_paddr(). - Add comment. --- xen/arch/x86/domain.c | 40 +++++++++++----------------------------- xen/include/xen/pdx.h | 1 + 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index d025befe3d8e..14a0f6dda791 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -461,30 +461,6 @@ void domain_cpu_policy_changed(struct domain *d) } } =20 -#if !defined(CONFIG_BIGMEM) && defined(CONFIG_PDX_COMPRESSION) -/* - * The hole may be at or above the 44-bit boundary, so we need to determine - * the total bit count until reaching 32 significant (not squashed out) bi= ts - * in PFN representations. - * Note that the way "bits" gets initialized/updated/bounds-checked guaran= tees - * that the function will never return zero, and hence will never be called - * more than once (which is important due to it being deliberately placed = in - * .init.text). - */ -static unsigned int __init noinline _domain_struct_bits(void) -{ - unsigned int bits =3D 32 + PAGE_SHIFT; - unsigned int sig =3D hweight32(~pfn_hole_mask); - unsigned int mask =3D pfn_hole_mask >> 32; - - for ( ; bits < BITS_PER_LONG && sig < 32; ++bits, mask >>=3D 1 ) - if ( !(mask & 1) ) - ++sig; - - return bits; -} -#endif - struct domain *alloc_domain_struct(void) { struct domain *d; @@ -498,14 +474,20 @@ struct domain *alloc_domain_struct(void) * On systems with CONFIG_BIGMEM there's no packing, and so there's no * such restriction. */ -#if defined(CONFIG_BIGMEM) || !defined(CONFIG_PDX_COMPRESSION) - const unsigned int bits =3D IS_ENABLED(CONFIG_BIGMEM) ? 0 : - 32 + PAGE_SHIFT; +#if defined(CONFIG_BIGMEM) + const unsigned int bits =3D 0; #else - static unsigned int __read_mostly bits; + static unsigned int __ro_after_init bits; =20 if ( unlikely(!bits) ) - bits =3D _domain_struct_bits(); + /* + * Get the width for the next pfn, and unconditionally subtract o= ne + * from it to ensure the used width will not allocate past the PDX + * field limit. + */ + bits =3D flsl(pdx_to_paddr(1UL << (sizeof_field(struct page_info, + v.inuse._domain) * = 8))) + - 1; #endif =20 BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE); diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 9faeea3ac9f2..c1423d64a95b 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -99,6 +99,7 @@ bool __mfn_valid(unsigned long mfn); #define pdx_to_mfn(pdx) _mfn(pdx_to_pfn(pdx)) =20 #define paddr_to_pdx(pa) pfn_to_pdx(paddr_to_pfn(pa)) +#define pdx_to_paddr(px) pfn_to_paddr(pdx_to_pfn(px)) =20 #ifdef CONFIG_PDX_COMPRESSION =20 --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417923; cv=none; d=zohomail.com; s=zohoarc; b=MRoQiGIKGtUgt5MO4emp6kb20rVInTlTi86o7gFwDQrzneukTLLxn9wSiPcBSxPHUyLuBVvHBsvhc91Bbfvg8ziflmJaG8kZ3Yu3f0aGk6T9xqQRANOA/mg8NLJYN3QKLkIBeBX8sLOYZW33504RF58lVPMZptk5lUWJrBvOOJI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417923; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uXLi+ILPXh/BGa4CWHzGZodhu1oUday7zbZjpBMD9ug=; b=PFcei/J8A7EC9d21zdvwXWy7V8yBqVQ3drCzlg4WvNklHXMxmunk57wPUILu+AyG3LyLOa4R1kykX4xe4i4hn93l0+nnSnB7Znrn1tRrCc3AnDuEms17Cp+DmBAtIzpui326W139F4V+Fq9KV9b4OhY2v1cOqnNfC0bQTBLDdMo= ARC-Authentication-Results: i=1; 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; 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 175041792381489.04526746234444; Fri, 20 Jun 2025 04:12:03 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020845.1396974 (Exim 4.92) (envelope-from ) id 1uSZem-0005lS-UD; Fri, 20 Jun 2025 11:11:40 +0000 Received: by outflank-mailman (output) from mailman id 1020845.1396974; Fri, 20 Jun 2025 11:11:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZem-0005lK-R9; Fri, 20 Jun 2025 11:11:40 +0000 Received: by outflank-mailman (input) for mailman id 1020845; Fri, 20 Jun 2025 11:11:38 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZek-0005XW-Ow for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:38 +0000 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [2a00:1450:4864:20::436]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 553e7198-4dc7-11f0-a30e-13f23c93f187; Fri, 20 Jun 2025 13:11:37 +0200 (CEST) Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-3a4f71831abso1460179f8f.3 for ; Fri, 20 Jun 2025 04:11:37 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a6d0f1d1bbsm1771319f8f.41.2025.06.20.04.11.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:35 -0700 (PDT) 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" X-Inumbo-ID: 553e7198-4dc7-11f0-a30e-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417896; x=1751022696; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uXLi+ILPXh/BGa4CWHzGZodhu1oUday7zbZjpBMD9ug=; b=OV+N26tRC/hfZpn8XC708vr2ZDbYzVmnDz7jty9MlDnHbq5K+3PaG4bxUjM0wQbfLe 8MlXX5YcmFOOwJdWQLPYqmVuNgw2JMWbhL+7qoOe9HLhzkBsp8yKeMVsOIooheeIfCef JPk5mhE0Ru6dYwHSLLLrYSdwto3d68I9UCUK0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417896; x=1751022696; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uXLi+ILPXh/BGa4CWHzGZodhu1oUday7zbZjpBMD9ug=; b=i0PIdlSmoybvRb6jpjTJFUvJ26UcIpdO4NmY0UnmNiGyrg3jM80/XZ3CirjHiUd5z0 ffWP/Kq4Q2aRIWQt3/8WVqQ2tPR5XElM8VXu10UWfc7N+1cYWt0Fdw1OVnO/ovVfADed 0g8Cy69P+/EyV4dnuaYcfJ8lYyo6uKPzvtB4LWG/mFERPIsBI8uAVwQ1QuOSobrnHYm1 gasEZJyY2oD4x3XgtAifRp7ZfYCapA+yWILfPO2Di8wNU+YYMMT3NoAvSm/erKmEMPNM cmvA9mo+c7ObpP/QftDrZasiXJxSJn+lxNm2vm3sl4NlCGIgv/MA9y3kvkjpl6eiIx77 oczA== X-Gm-Message-State: AOJu0Yyg5mK5T2veEiF8f1y6zrvAjFpV3PajorivqnF2kQL084ApMBcR iWrYbOibWQKAgaJGgRqE3oH752Q/RFFrawG7pWJC3YnpNpFFH+LRQ1lIsSADKjXSocwL2Sp+nBd IMmJZ X-Gm-Gg: ASbGncsCGJJQxtEObOsQKzVTKMW7FmCd802qrQt/y4V8NFO8QRlrH27qRNlmu7UY5Lg XA5BDwOC+VYntSNC8AmQSgwR+yLz+/h/O02N+J766c0FBQXAUbbR3D6ex0d9iEwEqINvMhk7rZH XiXtr9AOi/yQz06cG2X96w4psgJSyAWlgnz81UX6j7OQMMkbLtmgDNGLYUFudCV10XdwbKRY08W Dfq8JJ0ga8DzqrB8mmoKSaAeJyd40aC+7NrFEEqW6caKQFf8s+/zkFBAYWhv/Sxze0hhzsweDpq ee+YY75+tOdgrMeMfWBLG39IJNGKS5ELj33Rp5M7bHyf+g2IctnmTEd5HxteWxaw4tsUZnONzp6 baHi5VSMsD78O99lY6Z/hSDWkIf849L4ehjCGxMJh X-Google-Smtp-Source: AGHT+IG/dnMiX0uON1aC6uVJjxGOv669cfHteECQ1MNzB7CXV9EWo1d+70NpW6ec5RvrconHLky93g== X-Received: by 2002:a05:6000:2308:b0:3a4:e6c6:b8bf with SMTP id ffacd0b85a97d-3a6d1325a45mr2054719f8f.52.1750417896284; Fri, 20 Jun 2025 04:11:36 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v2 2/8] kconfig: turn PDX compression into a choice Date: Fri, 20 Jun 2025 13:11:24 +0200 Message-ID: <20250620111130.29057-3-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417924392116600 Rename the current CONFIG_PDX_COMPRESSION to CONFIG_PDX_MASK_COMPRESSION, and make it part of the PDX compression choice block, in preparation for adding further PDX compression algorithms. No functional change intended as the PDX compression defaults should still be the same for all architectures, however the choice block cannot be protected under EXPERT and still have a default choice being unconditionally selected. As a result, the new "PDX (Page inDeX) compression" item will be unconditionally visible in Kconfig. As part of this preparation work to introduce new PDX compressions, adjust some of the comments on pdx.h to note they apply to a specific PDX compression. Also shuffle function prototypes and dummy implementations around to make it easier to introduce a new PDX compression. Note all PDX compression implementations are expected to provide a pdx_is_region_compressible() that takes the same set of arguments. Signed-off-by: Roger Pau Monn=C3=A9 Acked-by: Jan Beulich --- xen/common/Kconfig | 18 +++++++++++++++--- xen/common/pdx.c | 4 ++-- xen/include/xen/pdx.h | 32 +++++++++++++++++++------------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 867710134ae5..de3e01d6320e 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -52,9 +52,10 @@ config EVTCHN_FIFO =20 If unsure, say Y. =20 -config PDX_COMPRESSION - bool "PDX (Page inDeX) compression" if EXPERT && !X86 && !RISCV - default ARM || PPC +choice + prompt "PDX (Page inDeX) compression" + default PDX_MASK_COMPRESSION if !X86 && !RISCV + default PDX_NONE help PDX compression is a technique designed to reduce the memory overhead of physical memory management on platforms with sparse RAM @@ -67,6 +68,17 @@ config PDX_COMPRESSION If your platform does not have sparse RAM banks, do not enable PDX compression. =20 +config PDX_MASK_COMPRESSION + bool "Mask compression" + help + Compression relying on all RAM addresses sharing a zeroed bit region. + +config PDX_NONE + bool "None" + help + No compression +endchoice + config ALTERNATIVE_CALL bool =20 diff --git a/xen/common/pdx.c b/xen/common/pdx.c index b8384e6189df..00aa7e43006d 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -34,7 +34,7 @@ bool __mfn_valid(unsigned long mfn) { bool invalid =3D mfn >=3D max_page; =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifdef CONFIG_PDX_MASK_COMPRESSION invalid |=3D mfn & pfn_hole_mask; #endif =20 @@ -55,7 +55,7 @@ void set_pdx_range(unsigned long smfn, unsigned long emfn) __set_bit(idx, pdx_group_valid); } =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifdef CONFIG_PDX_MASK_COMPRESSION =20 /* * Diagram to make sense of the following variables. The masks and shifts diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index c1423d64a95b..8e373cac8b87 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -25,7 +25,7 @@ * this by keeping a bitmap of the ranges in the frame table containing * invalid entries and not allocating backing memory for them. * - * ## PDX compression + * ## PDX mask compression * * This is a technique to avoid wasting memory on machines known to have * split their machine address space in several big discontinuous and high= ly @@ -101,22 +101,13 @@ bool __mfn_valid(unsigned long mfn); #define paddr_to_pdx(pa) pfn_to_pdx(paddr_to_pfn(pa)) #define pdx_to_paddr(px) pfn_to_paddr(pdx_to_pfn(px)) =20 -#ifdef CONFIG_PDX_COMPRESSION +#ifdef CONFIG_PDX_MASK_COMPRESSION =20 extern unsigned long pfn_pdx_bottom_mask, ma_va_bottom_mask; extern unsigned int pfn_pdx_hole_shift; extern unsigned long pfn_hole_mask; extern unsigned long pfn_top_mask, ma_top_mask; =20 -/** - * Validate a region's compatibility with the current compression runtime - * - * @param base Base address of the region - * @param npages Number of PAGE_SIZE-sized pages in the region - * @return True iff the region can be used with the current compression - */ -bool pdx_is_region_compressible(paddr_t base, unsigned long npages); - /** * Calculates a mask covering "moving" bits of all addresses of a region * @@ -209,7 +200,9 @@ static inline paddr_t directmapoff_to_maddr(unsigned lo= ng offset) */ void pfn_pdx_hole_setup(unsigned long mask); =20 -#else /* !CONFIG_PDX_COMPRESSION */ +#endif /* CONFIG_PDX_MASK_COMPRESSION */ + +#ifdef CONFIG_PDX_NONE =20 /* Without PDX compression we can skip some computations */ =20 @@ -241,7 +234,20 @@ static inline void pfn_pdx_hole_setup(unsigned long ma= sk) { } =20 -#endif /* CONFIG_PDX_COMPRESSION */ +#else /* !CONFIG_PDX_NONE */ + +/* Shared functions implemented by all PDX compressions. */ + +/** + * Validate a region's compatibility with the current compression runtime + * + * @param base Base address of the region + * @param npages Number of PAGE_SIZE-sized pages in the region + * @return True iff the region can be used with the current compression + */ +bool pdx_is_region_compressible(paddr_t base, unsigned long npages); + +#endif /* !CONFIG_PDX_NONE */ #endif /* __XEN_PDX_H__ */ =20 /* --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417925; cv=none; d=zohomail.com; s=zohoarc; b=GFwouhPVE1F06+xneJyEK1ZWGiOuSx2oC0k7hu8BwunQ5T4eQs69S2KNZm52sHYtv40r5r02TiCVuao0zAf9C4MxlEWBrt77OB8F4ffcYPp7Yh7QvW2ekY4bn+ul8xmBFLirHKYASev7cgJHuCtMi/VBlvfrlxJr4PzWvWWmTw0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417925; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=EfCl0bVnbKZAPh4wG7ZBEoxiS0taRAfJCBHz8dGUrQQ=; b=ibw0OjtML7Bib8nzz0taMRZdrvtTN+1JE37tbcxwA3VnBVxQPkXjQnFzjk0x++wojexqz33WvxhVkQkgNS65K3huRm8PWAmtSE6rCfD6liKIJSvLYj1QcCRX3ec5VBEX85rS2W5JFBnPQI0AmYy9yqE+62URHCrpwJRAgGHekUQ= ARC-Authentication-Results: i=1; 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; 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 1750417925799368.69903833812623; Fri, 20 Jun 2025 04:12:05 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020847.1396988 (Exim 4.92) (envelope-from ) id 1uSZen-0005vR-Iy; Fri, 20 Jun 2025 11:11:41 +0000 Received: by outflank-mailman (output) from mailman id 1020847.1396988; Fri, 20 Jun 2025 11:11:41 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZen-0005vC-CD; Fri, 20 Jun 2025 11:11:41 +0000 Received: by outflank-mailman (input) for mailman id 1020847; Fri, 20 Jun 2025 11:11:40 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZem-0005XV-JK for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:40 +0000 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [2a00:1450:4864:20::32a]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 55fac604-4dc7-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 13:11:38 +0200 (CEST) Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-453066fad06so10939205e9.2 for ; Fri, 20 Jun 2025 04:11:38 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a6d2236452sm1507187f8f.59.2025.06.20.04.11.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:37 -0700 (PDT) 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" X-Inumbo-ID: 55fac604-4dc7-11f0-b894-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417898; x=1751022698; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EfCl0bVnbKZAPh4wG7ZBEoxiS0taRAfJCBHz8dGUrQQ=; b=S6zgN7YOfpB3RhCy6Icso9EgPQtjspRHxG6c09gX/glxvX4L2wP88QZ3S9v2wxaQvw TExx0POaUQ9dsm9WeAvPchp17c770+KhAvm/VNQhMg6cUPGeB0N7bG0R7WaVU5jkqHao gAiJogVnWV7TaOWvNZ+qoY9EFCyV8SRzzDQS8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417898; x=1751022698; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EfCl0bVnbKZAPh4wG7ZBEoxiS0taRAfJCBHz8dGUrQQ=; b=dKr8HutL+ZuP0qRGZRtPZ1DC8dNhQ8VAUJqaEdGYdO/fvL3ZuPL8WochO2ArWTQfeG Xd9Ybec6XmbfAN5k297r8ewWJYZi0enxDVTj1G/tMOgrM0ZVpCkbC9JXblUH5dWC3M4y rgs+ipxDwWlnEptXcz8UpcWSoWBXMRONjsKfDgj59uHc1gMEgD+z0Hbd9TH89tkrozHG XhcIK3RPdzHrIP0UD3BBwofL4MoWZqnApksTqyDQUCtdF7sbzOhrV+tsM3WQ13vldzV4 /F3mI+mUBjZVaivqVcAUj1OqXEJwEA2b/6WiOeZHweV85Tm7ad2CSFj8OHQzBiVIjSDo 92NQ== X-Gm-Message-State: AOJu0Yz82QEkUxPa7aoodrqj38lND0ajcTlBTtRcl+41S/kM5OKr9STU GRz7drvlnRkX65/xuhEiu7aQp3Sg20CPf5To9YNkxq5O/xsu0QS1wpHrwt0LOD30LETx7ZnmMUA ZIlb/ X-Gm-Gg: ASbGncu5F/lhQIu78Zqxwi57l5g8ESludafV+DXffsU/yaj3ZeSY30fugT6tzMBF638 ZJxwnV0Aqia092iGQrcX3Tb0qSYBbbjl4YkkZn9isaMa1KyVx0MXUsUupc7EdgD2xRyJVMd1O4m Tx7T/9Bk7tzO2Rb9eFbM5BIcgI9Ugud/k5am9WFvWMJB88i4LnINk/x4nA4Em/jUhBXKgW8vqn6 koxVfPwCu7+EKzTjtRPDmycZP+ph53k3xTe1jrwQUvkCpJ0MSLjyydq7RU0EtHZuxXHgyVszf2j FmCccb7mbpYYdQY/ApXf+vZTL/zGDyfIwhcfzV+rXt3DF6fjgvq5ML+KKnZyyTF5GswCjsIsoow QlLPs/pGQVfz7uFgwlnTTTo/f6vTQ9A== X-Google-Smtp-Source: AGHT+IE/yCA3Rc2UNsyEtwRt8BYVm1vUP2PBgdDehSFU1I5t56tvb56e9J9NOCFbp6RRn4HBRjbN9g== X-Received: by 2002:a05:600c:820e:b0:43c:e478:889 with SMTP id 5b1f17b1804b1-4536478ecd2mr26387755e9.0.1750417897603; Fri, 20 Jun 2025 04:11:37 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich Subject: [PATCH v2 3/8] pdx: provide a unified set of unit functions Date: Fri, 20 Jun 2025 13:11:25 +0200 Message-ID: <20250620111130.29057-4-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417926600116600 The current setup (pdx_init_mask() and pdx_region_mask()) and init (pfn_pdx_hole_setup()) PDX compression functions are tailored to the existing PDX compression algorithm. In preparation for introducing a new compression algorithm convert the setup and init functions to more generic interfaces that aren't tied to the compression in-use. To accomplish this introduce a function that registers all the PFN RAM ranges, plus an init function. This has the downside of requiring a static array to store such ranges ahead of being processed by the setup function, however it's the only way to pass all the possible information to the different compression setup functions without using per-compression specific setup functions. Per-arch compression setup also need to be adjusted to use the new interface. There's a slight ordering adjustment, in that after PDX compression setup the caller will check whether all the RAM regions are properly covered by the newly setup compression, otherwise compression is disabled by resetting to the initial values. No functional change intended in the resulting PDX compression values. Signed-off-by: Roger Pau Monn=C3=A9 --- Changes since v1: - s/nr/nr_ranges/ --- xen/arch/arm/setup.c | 34 ++++++------ xen/arch/x86/srat.c | 28 ++++++---- xen/common/pdx.c | 122 ++++++++++++++++++++++++++++++++++++------ xen/include/xen/pdx.h | 73 +++++++++---------------- 4 files changed, 166 insertions(+), 91 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index ed72317af3c5..c9ad6bbab6a2 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -255,6 +255,10 @@ void __init init_pdx(void) { const struct membanks *mem =3D bootinfo_get_mem(); paddr_t bank_start, bank_size, bank_end; + unsigned int bank; + + for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) + pfn_pdx_add_region(mem->bank[bank].start, mem->bank[bank].size); =20 /* * Arm does not have any restrictions on the bits to compress. Pass 0 = to @@ -263,28 +267,24 @@ void __init init_pdx(void) * If the logic changes in pfn_pdx_hole_setup we might have to * update this function too. */ - uint64_t mask =3D pdx_init_mask(0x0); - int bank; + pfn_pdx_compression_setup(0); =20 for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) { - bank_start =3D mem->bank[bank].start; - bank_size =3D mem->bank[bank].size; - - mask |=3D bank_start | pdx_region_mask(bank_start, bank_size); - } - - for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) - { - bank_start =3D mem->bank[bank].start; - bank_size =3D mem->bank[bank].size; - - if (~mask & pdx_region_mask(bank_start, bank_size)) - mask =3D 0; + if ( !pdx_is_region_compressible(mem->bank[bank].start, + PFN_UP(mem->bank[bank].start + mem->bank[bank].size) - + PFN_DOWN(mem->bank[bank].start)) ) + { + pfn_pdx_compression_reset(); + printk(XENLOG_WARNING + "PFN compression disabled, RAM region [%#" PRIpaddr ", = %#" + PRIpaddr "] not covered\n", + mem->bank[bank].start, + mem->bank[bank].start + mem->bank[bank].size - 1); + break; + } } =20 - pfn_pdx_hole_setup(mask >> PAGE_SHIFT); - for ( bank =3D 0 ; bank < mem->nr_banks; bank++ ) { bank_start =3D mem->bank[bank].start; diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 688f410287d4..2a678e744e7c 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -261,8 +261,6 @@ acpi_numa_memory_affinity_init(const struct acpi_srat_m= em_affinity *ma) =20 void __init acpi_numa_arch_fixup(void) {} =20 -static uint64_t __initdata srat_region_mask; - static int __init cf_check srat_parse_region( struct acpi_subtable_header *header, const unsigned long end) { @@ -282,15 +280,13 @@ static int __init cf_check srat_parse_region( printk(KERN_INFO "SRAT: %013"PRIx64"-%013"PRIx64"\n", ma->base_address, ma->base_address + ma->length - 1); =20 - srat_region_mask |=3D ma->base_address | - pdx_region_mask(ma->base_address, ma->length); + pfn_pdx_add_region(ma->base_address, ma->length); =20 return 0; } =20 void __init srat_parse_regions(paddr_t addr) { - u64 mask; unsigned int i; =20 if (acpi_disabled || acpi_numa < 0 || @@ -299,19 +295,29 @@ void __init srat_parse_regions(paddr_t addr) =20 /* Set "PXM" as early as feasible. */ numa_fw_nid_name =3D "PXM"; - srat_region_mask =3D pdx_init_mask(addr); acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, srat_parse_region, 0); =20 - for (mask =3D srat_region_mask, i =3D 0; mask && i < e820.nr_map; i++) { + pfn_pdx_compression_setup(addr); + + /* Ensure all RAM ranges in the e820 are covered. */ + for (i =3D 0; i < e820.nr_map; i++) { if (e820.map[i].type !=3D E820_RAM) continue; =20 - if (~mask & pdx_region_mask(e820.map[i].addr, e820.map[i].size)) - mask =3D 0; + if (!pdx_is_region_compressible(e820.map[i].addr, + PFN_UP(e820.map[i].addr + e820.map[i].size) - + PFN_DOWN(e820.map[i].addr))) + { + pfn_pdx_compression_reset(); + printk(XENLOG_WARNING + "PFN compression disabled, RAM region [%#" PRIx64 + ", %#" PRIx64 "] not covered\n", + e820.map[i].addr, + e820.map[i].addr + e820.map[i].size - 1); + return; + } } - - pfn_pdx_hole_setup(mask >> PAGE_SHIFT); } =20 unsigned int numa_node_to_arch_nid(nodeid_t n) diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 00aa7e43006d..6f488366e5a9 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include =20 /** @@ -55,6 +56,44 @@ void set_pdx_range(unsigned long smfn, unsigned long emf= n) __set_bit(idx, pdx_group_valid); } =20 +#ifndef CONFIG_PDX_NONE + +#ifdef CONFIG_X86 +# include +# define MAX_PFN_RANGES E820MAX +#elif defined(CONFIG_HAS_DEVICE_TREE) +# include +# define MAX_PFN_RANGES NR_MEM_BANKS +#endif + +#ifndef MAX_PFN_RANGES +# error "Missing architecture maximum number of RAM ranges" +#endif + +/* Generic PFN compression helpers. */ +static struct pfn_range { + unsigned long base, size; +} ranges[MAX_PFN_RANGES] __initdata; +static unsigned int __initdata nr_ranges; + +void __init pfn_pdx_add_region(paddr_t base, paddr_t size) +{ + if ( !size ) + return; + + if ( nr_ranges >=3D ARRAY_SIZE(ranges) ) + { + ASSERT((nr_ranges + 1) > nr_ranges); + nr_ranges++; + return; + } + + ranges[nr_ranges].base =3D PFN_DOWN(base); + ranges[nr_ranges++].size =3D PFN_UP(base + size) - PFN_DOWN(base); +} + +#endif /* !CONFIG_PDX_NONE */ + #ifdef CONFIG_PDX_MASK_COMPRESSION =20 /* @@ -115,20 +154,25 @@ static uint64_t fill_mask(uint64_t mask) return mask; } =20 -bool pdx_is_region_compressible(paddr_t base, unsigned long npages) -{ - return !(paddr_to_pfn(base) & pfn_hole_mask) && - !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); -} - -/* We don't want to compress the low MAX_ORDER bits of the addresses. */ -uint64_t __init pdx_init_mask(uint64_t base_addr) -{ - return fill_mask(max(base_addr, - (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); -} - -uint64_t pdx_region_mask(uint64_t base, uint64_t len) +/** + * Calculates a mask covering "moving" bits of all addresses of a region + * + * The i-th bit of the mask must be set if there's 2 different addresses + * in the region that have different j-th bits. where j >=3D i. + * + * e.g: + * base=3D0x1B00000000 + * len+base=3D0x1B00042000 + * + * ought to return 0x000007FFFF, which implies that every bit position + * with a zero in the mask remains unchanged in every address of the + * region. + * + * @param base Base address of the region + * @param len Size in octets of the region + * @return Mask of moving bits at the bottom of all the region addresses + */ +static uint64_t pdx_region_mask(uint64_t base, uint64_t len) { /* * We say a bit "moves" in a range if there exist 2 addresses in that @@ -143,9 +187,45 @@ uint64_t pdx_region_mask(uint64_t base, uint64_t len) return fill_mask(base ^ (base + len - 1)); } =20 -void __init pfn_pdx_hole_setup(unsigned long mask) +bool pdx_is_region_compressible(paddr_t base, unsigned long npages) +{ + return !(paddr_to_pfn(base) & pfn_hole_mask) && + !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); +} + +/** + * Creates the mask to start from when calculating non-compressible bits + * + * This function is intimately related to pdx_region_mask(), and together + * they are meant to calculate the mask of non-compressible bits given the + * current memory map. + * + * @param base_addr Address of the first maddr in the system + * @return An integer of the form 2^n - 1 + */ +static uint64_t __init pdx_init_mask(uint64_t base_addr) +{ + return fill_mask(max(base_addr, + /* Don't compress the low MAX_ORDER bits. */ + (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); +} + +void __init pfn_pdx_compression_setup(paddr_t base) { unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; + unsigned long mask =3D pdx_init_mask(base) >> PAGE_SHIFT; + + if ( nr_ranges > ARRAY_SIZE(ranges) ) + { + printk(XENLOG_WARNING + "Too many PFN ranges (%u > %zu), not attempting PFN compres= sion\n", + nr_ranges, ARRAY_SIZE(ranges)); + return; + } + + for ( i =3D 0; i < nr_ranges; i++ ) + mask |=3D ranges[i].base | + pdx_region_mask(ranges[i].base, ranges[i].size); =20 /* * We skip the first MAX_ORDER bits, as we never want to compress them. @@ -184,6 +264,18 @@ void __init pfn_pdx_hole_setup(unsigned long mask) ma_top_mask =3D pfn_top_mask << PAGE_SHIFT; } =20 +void __init pfn_pdx_compression_reset(void) +{ + pfn_pdx_bottom_mask =3D ~0UL; + ma_va_bottom_mask =3D ~0UL; + pfn_top_mask =3D 0; + ma_top_mask =3D 0; + pfn_hole_mask =3D 0; + pfn_pdx_hole_shift =3D 0; + + nr_ranges =3D 0; +} + #endif /* CONFIG_PDX_COMPRESSION */ =20 /* diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 8e373cac8b87..10153da98bf1 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -108,38 +108,6 @@ extern unsigned int pfn_pdx_hole_shift; extern unsigned long pfn_hole_mask; extern unsigned long pfn_top_mask, ma_top_mask; =20 -/** - * Calculates a mask covering "moving" bits of all addresses of a region - * - * The i-th bit of the mask must be set if there's 2 different addresses - * in the region that have different j-th bits. where j >=3D i. - * - * e.g: - * base=3D0x1B00000000 - * len+base=3D0x1B00042000 - * - * ought to return 0x000007FFFF, which implies that every bit position - * with a zero in the mask remains unchanged in every address of the - * region. - * - * @param base Base address of the region - * @param len Size in octets of the region - * @return Mask of moving bits at the bottom of all the region addresses - */ -uint64_t pdx_region_mask(uint64_t base, uint64_t len); - -/** - * Creates the mask to start from when calculating non-compressible bits - * - * This function is intimately related to pdx_region_mask(), and together - * they are meant to calculate the mask of non-compressible bits given the - * current memory map. - * - * @param base_addr Address of the first maddr in the system - * @return An integer of the form 2^n - 1 - */ -uint64_t pdx_init_mask(uint64_t base_addr); - /** * Map pfn to its corresponding pdx * @@ -189,17 +157,6 @@ static inline paddr_t directmapoff_to_maddr(unsigned l= ong offset) (offset & ma_va_bottom_mask)); } =20 -/** - * Initializes global variables with information about the compressible - * range of the current memory regions. - * - * @param mask This mask is the biggest pdx_mask of every region in the - * system ORed with all base addresses of every region in the - * system. This results in a mask where every zero in a bit - * position marks a potentially compressible bit. - */ -void pfn_pdx_hole_setup(unsigned long mask); - #endif /* CONFIG_PDX_MASK_COMPRESSION */ =20 #ifdef CONFIG_PDX_NONE @@ -220,17 +177,15 @@ static inline bool pdx_is_region_compressible(paddr_t= base, return true; } =20 -static inline uint64_t pdx_init_mask(uint64_t base_addr) +static inline void pfn_pdx_add_region(paddr_t base, paddr_t size) { - return 0; } =20 -static inline uint64_t pdx_region_mask(uint64_t base, uint64_t len) +static inline void pfn_pdx_compression_setup(paddr_t base) { - return 0; } =20 -static inline void pfn_pdx_hole_setup(unsigned long mask) +static inline void pfn_pdx_compression_reset(void) { } =20 @@ -247,6 +202,28 @@ static inline void pfn_pdx_hole_setup(unsigned long ma= sk) */ bool pdx_is_region_compressible(paddr_t base, unsigned long npages); =20 +/** + * Register a RAM region with the PFN compression logic. + * + * @param base Start of the region in bytes. + * @param size Length of the region in bytes. + */ +void pfn_pdx_add_region(paddr_t base, paddr_t size); + +/** + * Initializes global variables with information about the compressible + * range of the current memory regions. + * + * @param base address to start compression from. + */ +void pfn_pdx_compression_setup(paddr_t base); + +/** + * Reset the global variables to it's default values, thus disabling PFN + * compression. + */ +void pfn_pdx_compression_reset(void); + #endif /* !CONFIG_PDX_NONE */ #endif /* __XEN_PDX_H__ */ =20 --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417928; cv=none; d=zohomail.com; s=zohoarc; b=X16pQ+oWZvJJaZYrhiwVdGB/lCszcuNA87JLPqx4xQbj1mKBxH470la+QFsk/D8XI14hkMVxosn+apHUDR4y99ToYIck0jphuhvctbINbz0Ea3xC9iAiLWu+Ub6f144xQZnU3cJzKLBxFweXWTYTv82gqoF5j2OCv7zyS+732Bs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417928; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=m8xArolHoZlQzAD7nGBeNXqPQFb+qxrfyquO2phQrQ8=; b=gqduN6ZN9Jryuj6LVgFXnYaRDqmklESalHscZdodVZAIdY2X22KIJmuCSwg5piRNsXuUaZ+OufhV9s0WGCVP3XgkHXrlULjPIHkOk+YgZAM+Oy0xgPDjmRq+PUygCAHTEgBBCBxW1s0R6P17CA4h0onvtqH/96nADBXT1m7JmDo= ARC-Authentication-Results: i=1; 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; 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 17504179281251011.4322480592955; Fri, 20 Jun 2025 04:12:08 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020848.1397005 (Exim 4.92) (envelope-from ) id 1uSZeo-0006R8-UF; Fri, 20 Jun 2025 11:11:42 +0000 Received: by outflank-mailman (output) from mailman id 1020848.1397005; Fri, 20 Jun 2025 11:11:42 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZeo-0006Qt-Qb; Fri, 20 Jun 2025 11:11:42 +0000 Received: by outflank-mailman (input) for mailman id 1020848; Fri, 20 Jun 2025 11:11:41 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZen-0005XV-EN for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:41 +0000 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [2a00:1450:4864:20::435]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 56b05a14-4dc7-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 13:11:39 +0200 (CEST) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-3a50956e5d3so1410693f8f.1 for ; Fri, 20 Jun 2025 04:11:39 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a6d0f104bbsm1785278f8f.4.2025.06.20.04.11.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:38 -0700 (PDT) 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" X-Inumbo-ID: 56b05a14-4dc7-11f0-b894-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417899; x=1751022699; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=m8xArolHoZlQzAD7nGBeNXqPQFb+qxrfyquO2phQrQ8=; b=bQulBgTPf8YW3t9+6K7nhXx5cWMiPZ52zPeqsT7ivdaBKOxbnSVc8nnvjYdRbQc063 ZchXXkdB2xm/8Z6uv9det2mPFik7ejpx5AIX6IuoOkB2D8TDIq0nJkg0NLzzvi7QlCS6 UTFBXkNTtzOxGxTyaNq+kMIciOT5ZI5USg9hg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417899; x=1751022699; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=m8xArolHoZlQzAD7nGBeNXqPQFb+qxrfyquO2phQrQ8=; b=lsFSaUTG6Yx/4NapZyBFbX+tv3B6MpnKNazvUBXUWKmpMdjVI3p+6KIr4O6gkXImxB t609EqYCTOnPjjN+ya9pAyCL2Mu7JEWjYUFhvTyJxc8ETSCjTFF1rlO+CX0x4S9ByKAO NRGFl0CU1ehII4ap7mHh+mlp7AsjYLVsJx95/QhpWpXitt3O63WAPG48abEeeEIal493 LUWsl542WqULm0253mZd+NWdgENcecZud4w3q2DZ3wQ41mArlEeqThai7jaa0lZE0+XJ Y7Nj6+Q7aiBLfPpK0/3jE1ZjrD9LQdvaDEiW+HlNKCtK47T2w2R2bIwxIbH6JlbCrc4a iNfA== X-Gm-Message-State: AOJu0YzGIkSe7tsGAMjmoxgdIxhSH98KwqSAWaWCPDf6qAwciWMASRxD lgHIqdAdoOHe5wwfamvZs/MRIgdvCMsWSCE2h6aLMc23RRNkdVhbr8nP9PO0egA0/WZ/T8mTN0D 2Eoyo X-Gm-Gg: ASbGnct8IHwBSyhahC1eHm8TW0MUjz915AmP8lzBWmJ9tNF2akKnIB3y23N+tx+DYph NpAponotEk3LyAk2VMqol0WuK/DI2WN1G+qflzhFUn1aZzOT1fpHpOm3VdJj2YbrS/RadmNX8GS xsdXTG6Ubp1rlTz1njT7d37YuySgZ5At40vzS3YuJv4ecSB0Q0lB3sRPDa2kJhbD+chT36cNMHG wnjEWfjnXHpYgdlc+zz+ADUz3f5vIqjiGHS2wnpFGbSTa7jjBOUhewB74LaOOc9VevSfc0J0729 TXF9gpXVnmkGaCUqsU+cD14zvS4g63ORUlHnZl1CnsrcbeAN5PHqI7Njit40lrSvDqEe6SibKag VusR+9UtpjkDD+B3otM1hkIuCpTCVjgTdT2QBpH/O X-Google-Smtp-Source: AGHT+IFC3F/vZggfelvDlDElhNOdJ82GWozuNVzqytLAEaS0nI24HNALkgoj2kiO6E3Bf9w3uOgVWQ== X-Received: by 2002:a5d:5f4b:0:b0:3a1:fe77:9e1d with SMTP id ffacd0b85a97d-3a6d12c1848mr2047618f8f.16.1750417898844; Fri, 20 Jun 2025 04:11:38 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v2 4/8] pdx: introduce command line compression toggle Date: Fri, 20 Jun 2025 13:11:26 +0200 Message-ID: <20250620111130.29057-5-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417930393116600 Introduce a command line option to allow disabling PDX compression. The disabling is done by turning pfn_pdx_add_region() into a no-op, so when attempting to initialize the selected compression algorithm the array of ranges to compress is empty. Signed-off-by: Roger Pau Monn=C3=A9 Reviewed-by: Jan Beulich --- Changes since v1: - New in this version. --- docs/misc/xen-command-line.pandoc | 9 +++++++++ xen/common/pdx.c | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line= .pandoc index b0eadd2c5d58..c747a326be86 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -2072,6 +2072,15 @@ for all of them (`true`), only for those subject to = XPTI (`xpti`) or for those not subject to XPTI (`no-xpti`). The feature is used only in case INVPCID is supported and not disabled via `invpcid=3Dfalse`. =20 +###=C2=A0pdx-compress +> `=3D ` + +> Default: `true` if CONFIG_PDX_NONE is unset + +Only relevant when the hypervisor is build with PFN PDX compression. Contr= ols +whether Xen will engage in PFN compression. The algorithm used for PFN +compression is selected at build time from Kconfig. + ### ple_gap > `=3D ` =20 diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 6f488366e5a9..8c107676da59 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include =20 @@ -76,9 +77,13 @@ static struct pfn_range { } ranges[MAX_PFN_RANGES] __initdata; static unsigned int __initdata nr_ranges; =20 +static bool __initdata pdx_compress =3D true; +boolean_param("pdx-compress", pdx_compress); + void __init pfn_pdx_add_region(paddr_t base, paddr_t size) { - if ( !size ) + /* Without ranges there's no PFN compression. */ + if ( !size || !pdx_compress ) return; =20 if ( nr_ranges >=3D ARRAY_SIZE(ranges) ) @@ -215,6 +220,9 @@ void __init pfn_pdx_compression_setup(paddr_t base) unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; unsigned long mask =3D pdx_init_mask(base) >> PAGE_SHIFT; =20 + if ( !nr_ranges ) + return; + if ( nr_ranges > ARRAY_SIZE(ranges) ) { printk(XENLOG_WARNING --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417923; cv=none; d=zohomail.com; s=zohoarc; b=Era4odQWhRhhD/zRat/oT/ZGNQskecZKlfY0peKndzKXGadgJ9vUcpRkXBtm42D+RRLMy3iiBq4L1mi23HxFeDboC6xGupkyA7ucJv6ggQ+lYt0NoNxJKEgJeY8HmE/PYR0Oa+3P6ma9cXKCdzi50z99VSbNThveI+5TxkqNV5w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417923; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/5KdETCTr6PRNgEhyxor0tMVyilA2Hq7p2nHUt2X0SU=; b=iSHJbonUlISPpZB4Gee02tHfYvVbkszsyQUyJWGR3E8NW6aXXfXlHc4f3OwdLE9Rgf1VZ8JojQ+dLLe18RFzWaCOO98+AdammhNvvEXy3epL6X78XmCRUHA/qWedSs0euynKfoIsDWAoXMKH53gGBt28YrKDhvcF+7aGMSaimPg= ARC-Authentication-Results: i=1; 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; 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 1750417923282766.4112121307905; Fri, 20 Jun 2025 04:12:03 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020849.1397015 (Exim 4.92) (envelope-from ) id 1uSZer-0006hq-5A; Fri, 20 Jun 2025 11:11:45 +0000 Received: by outflank-mailman (output) from mailman id 1020849.1397015; Fri, 20 Jun 2025 11:11:45 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZer-0006hf-1c; Fri, 20 Jun 2025 11:11:45 +0000 Received: by outflank-mailman (input) for mailman id 1020849; Fri, 20 Jun 2025 11:11:43 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZeo-0005XV-UG for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:43 +0000 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [2a00:1450:4864:20::42c]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 576c161c-4dc7-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 13:11:41 +0200 (CEST) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-3a522224582so820948f8f.3 for ; Fri, 20 Jun 2025 04:11:41 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a6d1187e5fsm1749428f8f.70.2025.06.20.04.11.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:39 -0700 (PDT) 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" X-Inumbo-ID: 576c161c-4dc7-11f0-b894-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417900; x=1751022700; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/5KdETCTr6PRNgEhyxor0tMVyilA2Hq7p2nHUt2X0SU=; b=bQTySAe75cQhFYfIOVxCKef84TVSNnDzsg79dYEzLqJsf7wmKSwDjYN5tSWBhjZwpU 3PyNNhqo3vyyvxpZhD9tUadSk27y/p8i+5bTnE0z3lNO8WWMwhoXOPaNpETAQnqTtQLL yo5dygwMgpRUWxAyuAsVszPmXbxK7cfbgEtH4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417900; x=1751022700; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/5KdETCTr6PRNgEhyxor0tMVyilA2Hq7p2nHUt2X0SU=; b=EOyZazomngFAdVGrQ1cGTJ2IAK7jSS0qyn5pxbgIRXGaUZaaQNg1jc34OnHfuOIEQy 7b7MPZfHQiNvFiQ3w61UFrnFEbua9xZAkOVW3M3ij53HstXe+et9SR0UHKvhj6uUOfYF quAk3J6RK3mKNY8Dnsdi+2qEhCZC2Z3wbLAZSjig+pPjCUqHTt1yRnDtpWhklE72o22n mhTewlycX4Makngxt9oOePDmx5uHK/hIpj7+6i7IY98NYrv5/1NWTtfzBCANyDVhixbW m++MRzWE67yTYa70Krv92A/vYeQMC+BSttEnPjiRm/alskMkDMqozc9qXkwtDK1ezgHg lE6Q== X-Gm-Message-State: AOJu0YzCVK2jhlGdzZqeye3EMmTyyp8tfPG7Q01uqFvJuQRVvsZ+Qd2K Ykom7GP7SmjfAPWci8MzuBAzhLiNGpcc9PX2puldu3v1vbt2zSeNMM/7b0apYNSDr55VGClG6T0 23pwl X-Gm-Gg: ASbGncvfvuBIXZORmT+mala+q1kEQ8w1//iXTy7my3Qa5YZSeHUkUHxzjotrTnM8Rmh yrZv3C+jFP+vb9ys9sIuyq992yyZmTp1BvR9qoOAj9BbGVY9dxR9+/AJtmi7IpnTMv2wyZsBSEv EMgZcKqgQDzWCmpCh77POmqJJ9kItR1lAPRzBb9Ti2Uj2zXlYT8t5g4IWrvaSezeFVPIANuXcVI Ly7f6fzosnuUzJqNiIXwCUonJN1XcyDlD3FIZQm7M03g9lBE1cAjabZyMdXhiElL0sIcMp0bh6n vsGLi4sKhTfnIc25fSEFYXd6lE2NHWXYV1lSsvjLnNVqiTbM5fnESU+NP18R3Hw9GhRacSXSMbF +GGfEFvbpm99uTYnSogHPBikmN74MFA== X-Google-Smtp-Source: AGHT+IEcdioiZeMRZJQMd51MKKnDuVxbVQwjb1BqB5XRm7Ridt6pmpEChfDT9rjV/RtK5h+Nxc1I+g== X-Received: by 2002:a05:6000:4903:b0:3a4:dcb0:a5f with SMTP id ffacd0b85a97d-3a6d12a21d6mr2102448f8f.16.1750417900065; Fri, 20 Jun 2025 04:11:40 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , Shawn Anastasio , Alistair Francis , Bob Eshleman , Connor Davis , Oleksii Kurochko Subject: [PATCH v2 5/8] pdx: allow per-arch optimization of PDX conversion helpers Date: Fri, 20 Jun 2025 13:11:27 +0200 Message-ID: <20250620111130.29057-6-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417924659116600 There are four performance critical PDX conversion helpers that do the PFN to/from PDX and the physical addresses to/from directmap offsets translations. In the absence of an active PDX compression, those functions would still do the calculations needed, just to return the same input value as no translation is in place and hence PFN and PDX spaces are identity mapped. To reduce the overhead of having to do the pointless calculations allow architectures to implement the translation helpers in a per-arch header. Rename the existing conversion functions to add a trailing _xlate suffix, so that the per-arch headers can define the non suffixed versions. Currently only x86 implements meaningful custom handlers to short circuit the translation when not active, using asm goto. Other architectures use a generic header that maps the non-xlate to the xlate variants to keep the previous behavior. Signed-off-by: Roger Pau Monn=C3=A9 --- Changes since v1: - Pull return out of OPTIMIZE_PDX macro. - undef OPTIMIZE_PDX. --- Would it make sense to move the x86 implementation to the common pdx.h header and let architectures define PDX_ASM_GOTO_SKIP instead? --- xen/arch/arm/include/asm/Makefile | 1 + xen/arch/ppc/include/asm/Makefile | 1 + xen/arch/riscv/include/asm/Makefile | 1 + xen/arch/x86/include/asm/cpufeatures.h | 1 + xen/arch/x86/include/asm/pdx.h | 75 ++++++++++++++++++++++++++ xen/arch/x86/srat.c | 6 ++- xen/common/pdx.c | 10 ++-- xen/include/asm-generic/pdx.h | 24 +++++++++ xen/include/xen/pdx.h | 22 +++++--- 9 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 xen/arch/x86/include/asm/pdx.h create mode 100644 xen/include/asm-generic/pdx.h diff --git a/xen/arch/arm/include/asm/Makefile b/xen/arch/arm/include/asm/M= akefile index 87c882142148..6283307cb0c4 100644 --- a/xen/arch/arm/include/asm/Makefile +++ b/xen/arch/arm/include/asm/Makefile @@ -6,6 +6,7 @@ generic-y +=3D hardirq.h generic-y +=3D iocap.h generic-y +=3D irq-dt.h generic-y +=3D paging.h +generic-y +=3D pdx.h generic-y +=3D percpu.h generic-y +=3D random.h generic-y +=3D softirq.h diff --git a/xen/arch/ppc/include/asm/Makefile b/xen/arch/ppc/include/asm/M= akefile index c989a7f89b34..0ad45133baac 100644 --- a/xen/arch/ppc/include/asm/Makefile +++ b/xen/arch/ppc/include/asm/Makefile @@ -6,6 +6,7 @@ generic-y +=3D hardirq.h generic-y +=3D hypercall.h generic-y +=3D iocap.h generic-y +=3D paging.h +generic-y +=3D pdx.h generic-y +=3D percpu.h generic-y +=3D perfc_defn.h generic-y +=3D random.h diff --git a/xen/arch/riscv/include/asm/Makefile b/xen/arch/riscv/include/a= sm/Makefile index bfdf186c682f..de04daf68df3 100644 --- a/xen/arch/riscv/include/asm/Makefile +++ b/xen/arch/riscv/include/asm/Makefile @@ -7,6 +7,7 @@ generic-y +=3D hypercall.h generic-y +=3D iocap.h generic-y +=3D irq-dt.h generic-y +=3D paging.h +generic-y +=3D pdx.h generic-y +=3D percpu.h generic-y +=3D perfc_defn.h generic-y +=3D random.h diff --git a/xen/arch/x86/include/asm/cpufeatures.h b/xen/arch/x86/include/= asm/cpufeatures.h index 9e3ed21c026d..85e1a6f0a055 100644 --- a/xen/arch/x86/include/asm/cpufeatures.h +++ b/xen/arch/x86/include/asm/cpufeatures.h @@ -43,6 +43,7 @@ XEN_CPUFEATURE(XEN_IBT, X86_SYNTH(27)) /* Xen u= ses CET Indirect Branch XEN_CPUFEATURE(IBPB_ENTRY_PV, X86_SYNTH(28)) /* MSR_PRED_CMD used by X= en for PV */ XEN_CPUFEATURE(IBPB_ENTRY_HVM, X86_SYNTH(29)) /* MSR_PRED_CMD used by X= en for HVM */ XEN_CPUFEATURE(USE_VMCALL, X86_SYNTH(30)) /* Use VMCALL instead of = VMMCALL */ +XEN_CPUFEATURE(PDX_COMPRESSION, X86_SYNTH(31)) /* PDX compression */ =20 /* Bug words follow the synthetic words. */ #define X86_NR_BUG 1 diff --git a/xen/arch/x86/include/asm/pdx.h b/xen/arch/x86/include/asm/pdx.h new file mode 100644 index 000000000000..b09b44ceaf4a --- /dev/null +++ b/xen/arch/x86/include/asm/pdx.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef X86_PDX_H +#define X86_PDX_H + +#ifndef CONFIG_PDX_NONE + +#include + +/* + * Introduce a macro to avoid repeating the same asm goto block in each he= lper. + * Note the macro is strictly tied to the code in the helpers. + */ +#define PDX_ASM_GOTO_SKIP \ + asm_inline goto ( \ + ALTERNATIVE( \ + "", \ + "jmp %l[skip]", \ + ALT_NOT(X86_FEATURE_PDX_COMPRESSION)) \ + : : : : skip ) + +static inline unsigned long pfn_to_pdx(unsigned long pfn) +{ + PDX_ASM_GOTO_SKIP; + + return pfn_to_pdx_xlate(pfn); + + skip: + return pfn; +} + +static inline unsigned long pdx_to_pfn(unsigned long pdx) +{ + PDX_ASM_GOTO_SKIP; + + return pdx_to_pfn_xlate(pdx); + + skip: + return pdx; +} + +static inline unsigned long maddr_to_directmapoff(paddr_t ma) +{ + PDX_ASM_GOTO_SKIP; + + return maddr_to_directmapoff_xlate(ma); + + skip: + return ma; +} + +static inline paddr_t directmapoff_to_maddr(unsigned long offset) +{ + PDX_ASM_GOTO_SKIP; + + return directmapoff_to_maddr_xlate(offset); + + skip: + return offset; +} + +#undef PDX_ASM_GOTO_SKIP + +#endif /* !CONFIG_PDX_NONE */ + +#endif /* X86_PDX_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 2a678e744e7c..516db1b5bfa8 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -298,7 +298,8 @@ void __init srat_parse_regions(paddr_t addr) acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, srat_parse_region, 0); =20 - pfn_pdx_compression_setup(addr); + if (!pfn_pdx_compression_setup(addr)) + return; =20 /* Ensure all RAM ranges in the e820 are covered. */ for (i =3D 0; i < e820.nr_map; i++) { @@ -318,6 +319,9 @@ void __init srat_parse_regions(paddr_t addr) return; } } + + /* If we got this far compression is working as expected. */ + setup_force_cpu_cap(X86_FEATURE_PDX_COMPRESSION); } =20 unsigned int numa_node_to_arch_nid(nodeid_t n) diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 8c107676da59..86e2dc7c6bb6 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -215,20 +215,20 @@ static uint64_t __init pdx_init_mask(uint64_t base_ad= dr) (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); } =20 -void __init pfn_pdx_compression_setup(paddr_t base) +bool __init pfn_pdx_compression_setup(paddr_t base) { unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; unsigned long mask =3D pdx_init_mask(base) >> PAGE_SHIFT; =20 if ( !nr_ranges ) - return; + return false; =20 if ( nr_ranges > ARRAY_SIZE(ranges) ) { printk(XENLOG_WARNING "Too many PFN ranges (%u > %zu), not attempting PFN compres= sion\n", nr_ranges, ARRAY_SIZE(ranges)); - return; + return false; } =20 for ( i =3D 0; i < nr_ranges; i++ ) @@ -259,7 +259,7 @@ void __init pfn_pdx_compression_setup(paddr_t base) } } if ( !hole_shift ) - return; + return false; =20 printk(KERN_INFO "PFN compression on bits %u...%u\n", bottom_shift, bottom_shift + hole_shift - 1); @@ -270,6 +270,8 @@ void __init pfn_pdx_compression_setup(paddr_t base) pfn_hole_mask =3D ((1UL << hole_shift) - 1) << bottom_shift; pfn_top_mask =3D ~(pfn_pdx_bottom_mask | pfn_hole_mask); ma_top_mask =3D pfn_top_mask << PAGE_SHIFT; + + return true; } =20 void __init pfn_pdx_compression_reset(void) diff --git a/xen/include/asm-generic/pdx.h b/xen/include/asm-generic/pdx.h new file mode 100644 index 000000000000..4dea2b97c3e5 --- /dev/null +++ b/xen/include/asm-generic/pdx.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef GENERIC_PDX_H +#define GENERIC_PDX_H + +#ifndef CONFIG_PDX_NONE + +#define pdx_to_pfn pdx_to_pfn_xlate +#define pfn_to_pdx pfn_to_pdx_xlate +#define maddr_to_directmapoff maddr_to_directmapoff_xlate +#define directmapoff_to_maddr directmapoff_to_maddr_xlate + +#endif /* !CONFIG_PDX_NONE */ + +#endif /* GENERIC_PDX_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 10153da98bf1..91fc32370f21 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -114,7 +114,7 @@ extern unsigned long pfn_top_mask, ma_top_mask; * @param pfn Frame number * @return Obtained pdx after compressing the pfn */ -static inline unsigned long pfn_to_pdx(unsigned long pfn) +static inline unsigned long pfn_to_pdx_xlate(unsigned long pfn) { return (pfn & pfn_pdx_bottom_mask) | ((pfn & pfn_top_mask) >> pfn_pdx_hole_shift); @@ -126,7 +126,7 @@ static inline unsigned long pfn_to_pdx(unsigned long pf= n) * @param pdx Page index * @return Obtained pfn after decompressing the pdx */ -static inline unsigned long pdx_to_pfn(unsigned long pdx) +static inline unsigned long pdx_to_pfn_xlate(unsigned long pdx) { return (pdx & pfn_pdx_bottom_mask) | ((pdx << pfn_pdx_hole_shift) & pfn_top_mask); @@ -139,7 +139,7 @@ static inline unsigned long pdx_to_pfn(unsigned long pd= x) * @return Offset on the direct map where that * machine address can be accessed */ -static inline unsigned long maddr_to_directmapoff(paddr_t ma) +static inline unsigned long maddr_to_directmapoff_xlate(paddr_t ma) { return (((ma & ma_top_mask) >> pfn_pdx_hole_shift) | (ma & ma_va_bottom_mask)); @@ -151,7 +151,7 @@ static inline unsigned long maddr_to_directmapoff(paddr= _t ma) * @param offset Offset into the direct map * @return Corresponding machine address of that virtual location */ -static inline paddr_t directmapoff_to_maddr(unsigned long offset) +static inline paddr_t directmapoff_to_maddr_xlate(unsigned long offset) { return ((((paddr_t)offset << pfn_pdx_hole_shift) & ma_top_mask) | (offset & ma_va_bottom_mask)); @@ -159,6 +159,14 @@ static inline paddr_t directmapoff_to_maddr(unsigned l= ong offset) =20 #endif /* CONFIG_PDX_MASK_COMPRESSION */ =20 +/* + * Allow each architecture to define it's (possibly optimized) versions of= the + * translation functions. + * + * Do not use _xlate suffixed functions, always use the non _xlate variant= s. + */ +#include + #ifdef CONFIG_PDX_NONE =20 /* Without PDX compression we can skip some computations */ @@ -181,8 +189,9 @@ static inline void pfn_pdx_add_region(paddr_t base, pad= dr_t size) { } =20 -static inline void pfn_pdx_compression_setup(paddr_t base) +static inline bool pfn_pdx_compression_setup(paddr_t base) { + return false; } =20 static inline void pfn_pdx_compression_reset(void) @@ -215,8 +224,9 @@ void pfn_pdx_add_region(paddr_t base, paddr_t size); * range of the current memory regions. * * @param base address to start compression from. + * @return True if PDX compression has been enabled. */ -void pfn_pdx_compression_setup(paddr_t base); +bool pfn_pdx_compression_setup(paddr_t base); =20 /** * Reset the global variables to it's default values, thus disabling PFN --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417924; cv=none; d=zohomail.com; s=zohoarc; b=McDyTpBr+M88PZ6OveIFeGhYTssf6bKB3G2AVTjF3og0XFPjrGMUytWW/MC88u33YXX2YgJTuSe//4a2KhQJgcjIdt5IOkzNqTPvaGsD1y2K8au5t/9+6scgYPgddA/XJw/9Gb7g0IpA61F+IbTq/MJYWWrf9ibQ3Kopo6gJj5g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417924; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=EsCxSro0G0kDL5DT8H/ufk+WFItshO7wcFGLxBzt6rg=; b=GbQg+D18vvvHI/JFsYczTfuqfkGV25yWt67wW2OSI2PRvCAIE7dBLmF82oRNAkrXH6Dk3cSfSvEN6IcQYhciaMkXq+OPe8nuNTYJvDQYV2HVKnCON3+BbMimfjYlPh03taB6YtvU+fOIP9TmLdwgkbsl0iWVsIXFrXQuG2chNTQ= ARC-Authentication-Results: i=1; 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; 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 1750417924784183.05206552043035; Fri, 20 Jun 2025 04:12:04 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020851.1397028 (Exim 4.92) (envelope-from ) id 1uSZes-0006w3-3Y; Fri, 20 Jun 2025 11:11:46 +0000 Received: by outflank-mailman (output) from mailman id 1020851.1397028; Fri, 20 Jun 2025 11:11:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZer-0006uZ-RG; Fri, 20 Jun 2025 11:11:45 +0000 Received: by outflank-mailman (input) for mailman id 1020851; Fri, 20 Jun 2025 11:11:44 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZeq-0005XV-Am for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:44 +0000 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [2a00:1450:4864:20::32f]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 5845fd68-4dc7-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 13:11:42 +0200 (CEST) Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-450cf0120cdso14038345e9.2 for ; Fri, 20 Jun 2025 04:11:42 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-453646cb672sm22375835e9.6.2025.06.20.04.11.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:40 -0700 (PDT) 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" X-Inumbo-ID: 5845fd68-4dc7-11f0-b894-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417901; x=1751022701; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EsCxSro0G0kDL5DT8H/ufk+WFItshO7wcFGLxBzt6rg=; b=WslG60dSTAlpK/m9Gfqx+bNg7qSCGbMcECr955Ie1K7wsrghP4WypS/DHH3bPuG2OO e9jfSjBg+EEQ3Uacnx0JRu0OMfqqHb6Xen/tJExruFzmuhC4IfTkyE3KwSdYv5nkb9S1 LSlFwoPBfEBAGLd0GBc/TCh4qW7YXsXuOGI9w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417901; x=1751022701; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EsCxSro0G0kDL5DT8H/ufk+WFItshO7wcFGLxBzt6rg=; b=UcMOsb1kKyyUHax7hmNHM2zeLu+v/4NELclmYTCk4Zm4duyXMadxxcnefNuKBnOr1f SMD5IsxsNng2QB8VTi2VbBq2hZpaciw5sEgKI1isJZqql7XXqrVpzMpVrFw1ZLKI3dj1 AnctFyKoYIFXXgxuZsQn0PVozLBntUoPvbRjOr9dbKrG7bFeZC/WFQhgTOxs4hPea01a jnuLW8AkbGAYBbsVDCFm3SjCbd9VDGjW8zKkkJkcNm7qRKQDqiwrMxK82ugS9Sddcu3W q8iFp5OJbIhSOlfmauExtiEq1Hllyho1DzddBlOyGya8rIJ5/GvecbmlJIfbMqmK2d/N LLig== X-Gm-Message-State: AOJu0YyvPtE3eK+LN1Ab7+q2TWnRONicQvxqxrA0fWuoofr53mhmQXn7 somxHL1GlnZiWwQGA2clu3930YDDJL8JH13GVi5Nim5KCcsqbdM2TGhycvu4woAGMP3vOKVK8W2 ItAH9 X-Gm-Gg: ASbGncs0XGwI6afLLoVSsq0PfwdL/8K6gGqJMcrgpDbRYkZY6fr5L4tQSSQUTrx4Pn4 g/ZAFwrbWd4KcevKHCVUo7e4/kU77oQDo+Vh9PaRYgOTucYHvXtOl5Acr9hNSt81hjV448TR79W j2fJPvOTEnJWc/w9w4l6lzo6PW/xn96SQ2z2jeaDheOSJgvCA+vBCqTyHKLHZUmPx0WIL5YHnov b7HRDkijCzS9D1ic1GwIFYYg4h1Ur6Jkh6Mio+xA65iy1GpKxvYej9SE0eq/ru/AmVEU4quSDkB OLwX4lQvJ/oSDN9Go/z+1VNDORstox/KvdS1AtAD6zO3t9HN6KQMIrpGuUUru+C2dZVXmcsd8Es nCYik+gmlEy6vhKpkTxh2L++6NhdISg== X-Google-Smtp-Source: AGHT+IF6i1WhfFMFyhSmrPUes6Q3jZ77HAhhSPCYQfxYrKJeXFhYKfQou/CrlO18cgXG6ohBKLxNiA== X-Received: by 2002:a5d:64cc:0:b0:3a5:26fd:d450 with SMTP id ffacd0b85a97d-3a6d12eb3dfmr1939933f8f.47.1750417901384; Fri, 20 Jun 2025 04:11:41 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Anthony PERARD , Andrew Cooper , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v2 6/8] test/pdx: add PDX compression unit tests Date: Fri, 20 Jun 2025 13:11:28 +0200 Message-ID: <20250620111130.29057-7-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417926571116600 Introduce a set of unit tests for PDX compression. The unit tests contains both real and crafted memory maps that are then compressed using the selected PDX algorithm. Note the build system for the unit tests has been done in a way to support adding new compression algorithms easily. That requires generating a new test-pdx- executable that's build with the selected PDX compression enabled. Currently the only generated executable is test-pdx-mask that tests PDX mask compression. Signed-off-by: Roger Pau Monn=C3=A9 --- Changes since v1: - New in this version (partially pulled out from a different patch). --- tools/tests/Makefile | 1 + tools/tests/pdx/.gitignore | 2 + tools/tests/pdx/Makefile | 48 ++++++++ tools/tests/pdx/harness.h | 89 +++++++++++++++ tools/tests/pdx/test-pdx.c | 220 +++++++++++++++++++++++++++++++++++++ xen/common/pdx.c | 4 + 6 files changed, 364 insertions(+) create mode 100644 tools/tests/pdx/.gitignore create mode 100644 tools/tests/pdx/Makefile create mode 100644 tools/tests/pdx/harness.h create mode 100644 tools/tests/pdx/test-pdx.c diff --git a/tools/tests/Makefile b/tools/tests/Makefile index 36928676a666..97ba2a13894d 100644 --- a/tools/tests/Makefile +++ b/tools/tests/Makefile @@ -9,6 +9,7 @@ ifneq ($(clang),y) SUBDIRS-$(CONFIG_X86) +=3D x86_emulator endif SUBDIRS-y +=3D xenstore +SUBDIRS-y +=3D pdx SUBDIRS-y +=3D rangeset SUBDIRS-y +=3D vpci SUBDIRS-y +=3D paging-mempool diff --git a/tools/tests/pdx/.gitignore b/tools/tests/pdx/.gitignore new file mode 100644 index 000000000000..a32c7db4de79 --- /dev/null +++ b/tools/tests/pdx/.gitignore @@ -0,0 +1,2 @@ +/pdx.h +/test-pdx-mask diff --git a/tools/tests/pdx/Makefile b/tools/tests/pdx/Makefile new file mode 100644 index 000000000000..99867b71c438 --- /dev/null +++ b/tools/tests/pdx/Makefile @@ -0,0 +1,48 @@ +XEN_ROOT=3D$(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +TARGETS :=3D test-pdx-mask + +.PHONY: all +all: $(TARGETS) + +.PHONY: run +run: $(TARGETS) +ifeq ($(CC),$(HOSTCC)) + for test in $? ; do \ + ./$$test ; \ + done +else + $(warning HOSTCC !=3D CC, will not run test) +endif + +.PHONY: clean +clean: + $(RM) -- *.o $(TARGETS) $(DEPS_RM) pdx.c pdx.h + +.PHONY: distclean +distclean: clean + $(RM) -- *~ + +.PHONY: install +install: all + $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)/tests + $(INSTALL_PROG) $(TARGETS) $(DESTDIR)$(LIBEXEC)/tests + +.PHONY: uninstall +uninstall: + $(RM) -- $(patsubst %,$(DESTDIR)$(LIBEXEC)/tests/%,$(TARGETS)) + +pdx.h: $(XEN_ROOT)/xen/include/xen/pdx.h + sed -E -e '/^#[[:space:]]?include/d' <$< >$@ + +CFLAGS +=3D -D__XEN_TOOLS__ +CFLAGS +=3D $(APPEND_CFLAGS) +CFLAGS +=3D $(CFLAGS_xeninclude) + +test-pdx-mask: CFLAGS +=3D -DCONFIG_PDX_MASK_COMPRESSION + +test-pdx-%: test-pdx.c pdx.h + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -o $@ $< $(APPEND_CFLAGS) + +-include $(DEPS_INCLUDE) diff --git a/tools/tests/pdx/harness.h b/tools/tests/pdx/harness.h new file mode 100644 index 000000000000..64ec09f5e281 --- /dev/null +++ b/tools/tests/pdx/harness.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Unit tests for PDX compression. + * + * Copyright (C) 2025 Cloud Software Group + */ + +#ifndef _TEST_HARNESS_ +#define _TEST_HARNESS_ + +#include +#include +#include +#include +#include +#include + +#include + +#define __init +#define __initdata +#define __ro_after_init +#define cf_check + +#define printk printf +#define XENLOG_INFO +#define XENLOG_DEBUG +#define XENLOG_WARNING +#define KERN_INFO + +#define BITS_PER_LONG (sizeof(unsigned long) * 8) + +#define PAGE_SHIFT 12 +/* Some libcs define PAGE_SIZE in limits.h. */ +#undef PAGE_SIZE +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define MAX_ORDER 18 /* 2 * PAGETABLE_ORDER (9) */ + +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) + +#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT) +#define paddr_to_pfn(pa) ((unsigned long)((pa) >> PAGE_SHIFT)) + +#define MAX_RANGES 8 +#define MAX_PFN_RANGES MAX_RANGES + +#define ASSERT assert + +#define CONFIG_DEBUG + +static inline unsigned int find_next( + const unsigned long *addr, unsigned int size, unsigned int off, bool v= alue) +{ + unsigned int i; + + ASSERT(size <=3D BITS_PER_LONG); + + for ( i =3D off; i < size; i++ ) + if ( !!(*addr & (1UL << i)) =3D=3D value ) + return i; + + return size; +} + +#define find_next_zero_bit(a, s, o) find_next(a, s, o, false) +#define find_next_bit(a, s, o) find_next(a, s, o, true) + +#define boolean_param(name, func) + +#define pdx_to_pfn pdx_to_pfn_xlate +#define pfn_to_pdx pfn_to_pdx_xlate +#define maddr_to_directmapoff maddr_to_directmapoff_xlate +#define directmapoff_to_maddr directmapoff_to_maddr_xlate + +typedef uint64_t paddr_t; + +#include "pdx.h" + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/tests/pdx/test-pdx.c b/tools/tests/pdx/test-pdx.c new file mode 100644 index 000000000000..b717cae00711 --- /dev/null +++ b/tools/tests/pdx/test-pdx.c @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Unit tests for PDX compression. + * + * Copyright (C) 2025 Cloud Software Group + */ + +#include "harness.h" + +#include "../../xen/common/pdx.c" + +struct range { + /* Ranges are defined as [start, end). */ + unsigned long start, end; +}; + +static void print_ranges(const struct range *r) +{ + unsigned int i; + + printf("Ranges:\n"); + + for ( i =3D 0; i < MAX_RANGES; i++ ) + { + if ( !r[i].start && !r[i].end ) + break; + + printf(" %013lx-%013lx\n", r[i].start, r[i].end); + } +} + +int main(int argc, char **argv) +{ + static const struct { + struct range ranges[MAX_RANGES]; + bool compress; + } tests[] =3D { +#ifdef __LP64__ + /* + * Only for targets where unsigned long is 64bits, otherwise compi= ler + * will complain about truncation from 'long long' -> 'long' conve= rsion. + * + * Real memory map from a 4s Intel GNR. Not compressible using PDX + * mask compression. + */ + { + .ranges =3D { + { .start =3D 0, .end =3D 0x80000UL }, + { .start =3D 0x0100000UL, .end =3D 0x8080000UL }, + { .start =3D 0x63e80000UL, .end =3D 0x6be80000UL }, + { .start =3D 0xc7e80000UL, .end =3D 0xcfe80000UL }, + { .start =3D 0x12be80000UL, .end =3D 0x133e80000UL }, + }, + .compress =3D false, + }, + /* Simple hole. */ + { + .ranges =3D { + { .start =3D = 0, + .end =3D (1UL << MAX_ORDER)= * 1 }, + { .start =3D (1UL << (MAX_ORDER * 2)) | = 0, + .end =3D (1UL << (MAX_ORDER * 2)) | (1UL << MAX_ORDER)= * 1 }, + }, + .compress =3D true, + }, + /* Simple hole, unsorted ranges. */ + { + .ranges =3D { + { .start =3D (1UL << (MAX_ORDER * 2)) | = 0, + .end =3D (1UL << (MAX_ORDER * 2)) | (1UL << MAX_ORDER)= * 1 }, + { .start =3D = 0, + .end =3D (1UL << MAX_ORDER)= * 1 }, + }, + .compress =3D true, + }, + /* PDX compression, 2 ranges covered by the lower mask. */ + { + .ranges =3D { + { .start =3D 0, + .end =3D (1 << MAX_ORDER) * 1 }, + { .start =3D (1 << MAX_ORDER) * 2, + .end =3D (1 << MAX_ORDER) * 3 }, + { .start =3D (1 << MAX_ORDER) * 20, + .end =3D (1 << MAX_ORDER) * 22 }, + }, + .compress =3D true, + }, + /* Single range not starting at 0. */ + { + .ranges =3D { + { .start =3D (1 << MAX_ORDER) * 10, + .end =3D (1 << MAX_ORDER) * 11 }, + }, + .compress =3D true, + }, + /* Resulting PDX region size leads to no compression. */ + { + .ranges =3D { + { .start =3D 0, + .end =3D (1 << MAX_ORDER) * 1 }, + { .start =3D (1 << MAX_ORDER) * 2, + .end =3D (1 << MAX_ORDER) * 3 }, + { .start =3D (1 << MAX_ORDER) * 4, + .end =3D (1 << MAX_ORDER) * 7 }, + { .start =3D (1 << MAX_ORDER) * 8, + .end =3D (1 << MAX_ORDER) * 12 }, + }, + .compress =3D false, + }, +#endif + /* 2-node 2GB per-node QEMU layout. */ + { + .ranges =3D { + { .start =3D 0, .end =3D 0x80000UL }, + { .start =3D 0x100000UL, .end =3D 0x180000UL }, + }, + .compress =3D true, + }, + /* Not compressible, smaller than MAX_ORDER. */ + { + .ranges =3D { + { .start =3D 0, .end =3D 1 }, + { .start =3D 0x100UL, .end =3D 0x101UL }, + }, + .compress =3D false, + }, + /* Compressible, requires adjusting size to (1 << MAX_ORDER). */ + { + .ranges =3D { + { .start =3D 0, .end =3D 1 }, + { .start =3D 0x100000UL, .end =3D 0x100001UL }, + }, + .compress =3D true, + }, + /* 2s Intel CLX with contiguous ranges, no compression. */ + { + .ranges =3D { + { .start =3D 0 , .end =3D 0x180000UL }, + { .start =3D 0x180000UL, .end =3D 0x3040000UL }, + }, + .compress =3D false, + }, + }; + int ret_code =3D EXIT_SUCCESS; + + for ( unsigned int i =3D 0 ; i < ARRAY_SIZE(tests); i++ ) + { + unsigned int j; + + pfn_pdx_compression_reset(); + + for ( j =3D 0; j < ARRAY_SIZE(tests[i].ranges); j++ ) + { + unsigned long size =3D tests[i].ranges[j].end - + tests[i].ranges[j].start; + + if ( !tests[i].ranges[j].start && !tests[i].ranges[j].end ) + break; + + pfn_pdx_add_region(tests[i].ranges[j].start << PAGE_SHIFT, + size << PAGE_SHIFT); + } + + if ( pfn_pdx_compression_setup(0) !=3D tests[i].compress ) + { + printf("PFN compression diverge, expected %scompressible\n", + tests[i].compress ? "" : "un"); + print_ranges(tests[i].ranges); + + ret_code =3D EXIT_FAILURE; + continue; + } + + if ( !tests[i].compress ) + continue; + + for ( j =3D 0; j < ARRAY_SIZE(tests[i].ranges); j++ ) + { + unsigned long start =3D tests[i].ranges[j].start; + unsigned long end =3D tests[i].ranges[j].end; + + if ( !start && !end ) + break; + + if ( !pdx_is_region_compressible(start << PAGE_SHIFT, 1) || + !pdx_is_region_compressible((end - 1) << PAGE_SHIFT, 1) ) + { + printf( + "PFN compression invalid, pages %#lx and %#lx should be compressible\n= ", + start, end - 1); + print_ranges(tests[i].ranges); + ret_code =3D EXIT_FAILURE; + } + + if ( start !=3D pdx_to_pfn(pfn_to_pdx(start)) || + end - 1 !=3D pdx_to_pfn(pfn_to_pdx(end - 1)) ) + { + printf("Compression is not bi-directional:\n"); + printf(" PFN %#lx -> PDX %#lx -> PFN %#lx\n", + start, pfn_to_pdx(start), pdx_to_pfn(pfn_to_pdx(sta= rt))); + printf(" PFN %#lx -> PDX %#lx -> PFN %#lx\n", + end - 1, pfn_to_pdx(end - 1), + pdx_to_pfn(pfn_to_pdx(end - 1))); + print_ranges(tests[i].ranges); + ret_code =3D EXIT_FAILURE; + } + } + } + + return ret_code; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 86e2dc7c6bb6..5cfec591f993 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -15,6 +15,8 @@ * along with this program; If not, see . */ =20 +/* Trim content when built for the test harness. */ +#ifdef __XEN__ #include #include #include @@ -57,6 +59,8 @@ void set_pdx_range(unsigned long smfn, unsigned long emfn) __set_bit(idx, pdx_group_valid); } =20 +#endif /* __XEN__ */ + #ifndef CONFIG_PDX_NONE =20 #ifdef CONFIG_X86 --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417926; cv=none; d=zohomail.com; s=zohoarc; b=ZYFbr2RYwDv1xzRGjVCaFukDjVMijEWtxksk87LXIOFaGOssCOWoFoeJXKLoMODzosk1XQvav1Wn3WwneOqrO0ZA5PPSO8pRBNwOEFfMNEaWa3EuNgbcRmC4oo3FdnDfAwuzc2M74LKwAZZDUwp9f7PMbFBdNtEd9ETbWxxx140= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417926; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wldT8/hJRoQr9+P0tngsgZ2ttRe5059NLBS5IaMdmu4=; b=W5PvnuQNNCVOrK437XEaNUiTcIzWwvP5Bx7veFdIu4fylJNqui/3QWHTR5i9e0/Wn9j0rM6J6aFepLh+Ub22P3tQBTkbOWGO8MaoWIE3t6S+SuSOAb/DGANgItHVU/fyab9/7f9YbleeJHi25DyIzT8BEOfJCF1MeJ3QF8hYEXI= ARC-Authentication-Results: i=1; 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; 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 1750417926850373.2103998536238; Fri, 20 Jun 2025 04:12:06 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020850.1397021 (Exim 4.92) (envelope-from ) id 1uSZer-0006lP-HV; Fri, 20 Jun 2025 11:11:45 +0000 Received: by outflank-mailman (output) from mailman id 1020850.1397021; Fri, 20 Jun 2025 11:11:45 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZer-0006kj-B7; Fri, 20 Jun 2025 11:11:45 +0000 Received: by outflank-mailman (input) for mailman id 1020850; Fri, 20 Jun 2025 11:11:44 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZep-0005XW-V1 for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:43 +0000 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [2a00:1450:4864:20::335]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 58f86d06-4dc7-11f0-a30e-13f23c93f187; Fri, 20 Jun 2025 13:11:43 +0200 (CEST) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-451d41e1ad1so13059695e9.1 for ; Fri, 20 Jun 2025 04:11:43 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-453646cb57fsm22346425e9.1.2025.06.20.04.11.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:42 -0700 (PDT) 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" X-Inumbo-ID: 58f86d06-4dc7-11f0-a30e-13f23c93f187 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417903; x=1751022703; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wldT8/hJRoQr9+P0tngsgZ2ttRe5059NLBS5IaMdmu4=; b=UlQkcyCgzs/MRDx+r6F69Aq3z1GbQzWX6PrJsRxbcwEYYpx1hKaA/UCYfPEMkiEto0 z8Ud59mpKsxH3DsJ6VXaAyA6AadPehNelyapm7Z1VXRySGOXiwc8onkLOGM0814xUCLX G3LTlbdEPvyTL6SwELlQGsc58RalCCjGOgaro= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417903; x=1751022703; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wldT8/hJRoQr9+P0tngsgZ2ttRe5059NLBS5IaMdmu4=; b=aXQKJ3Ap7H/Uj19d4A/BN2diOUsozVa64gGC2jy3uSyQHSif1Fk5kVh0NIpQZcQPMZ BcsbbmvqKABGx7zR7CphkrKfc/bxxv4PzeULgC8lbKRSSx052pJt9hQscvQEZl3IBAbe z/eq9UiLVAQZ8ikIlpEq0NidICrQJ1u83/r3yBsea+oHUGa51LldZ9uMJZdFDfWG44Dg 4SBGgfJRXtwDyr9r1wUNGtsBPfnMINOT1hSBPOtHadQ9wEAqSYgPcZipodJMZUP8+jF3 bNG0it0cQaKDR068S4Jpw13azSxayMhpZFBPXH/39hczuUk7iEDSfmqODqebNaetYYIH Dwhg== X-Gm-Message-State: AOJu0YwD/0OL/+vsMz+agfKT6n8HSh65yucakFTHsk7nKS3+DDEyEed4 U7pybLqWq3Ge4Kt7aaJsGN7bYaQoPDSeymr8lwn1wztv7w0W92dUmxkEHsdDCh7+KJKPcqA/jRb b/CmK X-Gm-Gg: ASbGncu+SPmmhj3bnbE4Wvb5y0YGgFkwla1XpX+SdLWh5fBXi9lWby0hp9YHb9Zipib i0suybdH4k4TfPm1mTtSPW6l0nM2GFW9WZAiwi0sSjzyDi5zEK2bIMEXJg4EJWtirWy+KvE9A9W E5zmpjvXEJHHskx/+HWX+nQuUjFMpuLU0iTrwH8Yy/MZ2CzUbOQ9PN50tIq81Yr1pyRrbNaJDXy b7j3mauad+HURx0oM67/7rO3p5j5eLk+eBhgBE6i+qNSsD+ci90igSPrBGLiDJ6wQMSR3wZehfs 1sZ6r/doHPN/96hWLMgvcnOTX/1h9rHDY9Oy/F/GwASsCraaXiYniwMGvey/RVCiZTBUJKP2qHj k2+1DPeXrOOyx9qMrRZ+84jH+9ke8JA== X-Google-Smtp-Source: AGHT+IHJiQ62hFFpGk1dacP+iqYl/Dmt8h7STK8m9XWPRJGoeBlj0alEIF5MZ6oahkw+8FizzIXZgA== X-Received: by 2002:a05:6000:2807:b0:3a5:232c:6976 with SMTP id ffacd0b85a97d-3a6d12e3a8fmr1412325f8f.44.1750417902622; Fri, 20 Jun 2025 04:11:42 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v2 7/8] pdx: move some helpers in preparation for new compression Date: Fri, 20 Jun 2025 13:11:29 +0200 Message-ID: <20250620111130.29057-8-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417928521116600 Move fill_mask(), pdx_region_mask() and pdx_init_mask() to the !CONFIG_PDX_NONE section in preparation of them also being used by a newly added PDX compression. No functional change intended. Signed-off-by: Roger Pau Monn=C3=A9 Acked-by: Jan Beulich --- git is not very helpful when generating the diff here, and it ends up moving everything around the functions instead of the functions themselves. --- xen/common/pdx.c | 118 +++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/xen/common/pdx.c b/xen/common/pdx.c index 5cfec591f993..d5e469baffe2 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -101,59 +101,6 @@ void __init pfn_pdx_add_region(paddr_t base, paddr_t s= ize) ranges[nr_ranges++].size =3D PFN_UP(base + size) - PFN_DOWN(base); } =20 -#endif /* !CONFIG_PDX_NONE */ - -#ifdef CONFIG_PDX_MASK_COMPRESSION - -/* - * Diagram to make sense of the following variables. The masks and shifts - * are done on mfn values in order to convert to/from pdx: - * - * pfn_hole_mask - * pfn_pdx_hole_shift (mask bitsize) - * | - * |---------| - * | | - * V V - * -------------------------- - * |HHHHHHH|000000000|LLLLLL| <--- mfn - * -------------------------- - * ^ ^ ^ ^ - * | | |------| - * | | | - * | | pfn_pdx_bottom_mask - * | | - * |-------| - * | - * pfn_top_mask - * - * ma_{top,va_bottom}_mask is simply a shifted pfn_{top,pdx_bottom}_mask, - * where ma_top_mask has zeroes shifted in while ma_va_bottom_mask has - * ones. - */ - -/** Mask for the lower non-compressible bits of an mfn */ -unsigned long __ro_after_init pfn_pdx_bottom_mask =3D ~0UL; - -/** Mask for the lower non-compressible bits of an maddr or vaddr */ -unsigned long __ro_after_init ma_va_bottom_mask =3D ~0UL; - -/** Mask for the higher non-compressible bits of an mfn */ -unsigned long __ro_after_init pfn_top_mask =3D 0; - -/** Mask for the higher non-compressible bits of an maddr or vaddr */ -unsigned long __ro_after_init ma_top_mask =3D 0; - -/** - * Mask for a pdx compression bit slice. - * - * Invariant: valid(mfn) implies (mfn & pfn_hole_mask) =3D=3D 0 - */ -unsigned long __ro_after_init pfn_hole_mask =3D 0; - -/** Number of bits of the "compressible" bit slice of an mfn */ -unsigned int __ro_after_init pfn_pdx_hole_shift =3D 0; - /* Sets all bits from the most-significant 1-bit down to the LSB */ static uint64_t fill_mask(uint64_t mask) { @@ -196,12 +143,6 @@ static uint64_t pdx_region_mask(uint64_t base, uint64_= t len) return fill_mask(base ^ (base + len - 1)); } =20 -bool pdx_is_region_compressible(paddr_t base, unsigned long npages) -{ - return !(paddr_to_pfn(base) & pfn_hole_mask) && - !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); -} - /** * Creates the mask to start from when calculating non-compressible bits * @@ -219,6 +160,65 @@ static uint64_t __init pdx_init_mask(uint64_t base_add= r) (uint64_t)1 << (MAX_ORDER + PAGE_SHIFT)) - 1); } =20 +#endif /* !CONFIG_PDX_NONE */ + +#ifdef CONFIG_PDX_MASK_COMPRESSION + +/* + * Diagram to make sense of the following variables. The masks and shifts + * are done on mfn values in order to convert to/from pdx: + * + * pfn_hole_mask + * pfn_pdx_hole_shift (mask bitsize) + * | + * |---------| + * | | + * V V + * -------------------------- + * |HHHHHHH|000000000|LLLLLL| <--- mfn + * -------------------------- + * ^ ^ ^ ^ + * | | |------| + * | | | + * | | pfn_pdx_bottom_mask + * | | + * |-------| + * | + * pfn_top_mask + * + * ma_{top,va_bottom}_mask is simply a shifted pfn_{top,pdx_bottom}_mask, + * where ma_top_mask has zeroes shifted in while ma_va_bottom_mask has + * ones. + */ + +/** Mask for the lower non-compressible bits of an mfn */ +unsigned long __ro_after_init pfn_pdx_bottom_mask =3D ~0UL; + +/** Mask for the lower non-compressible bits of an maddr or vaddr */ +unsigned long __ro_after_init ma_va_bottom_mask =3D ~0UL; + +/** Mask for the higher non-compressible bits of an mfn */ +unsigned long __ro_after_init pfn_top_mask =3D 0; + +/** Mask for the higher non-compressible bits of an maddr or vaddr */ +unsigned long __ro_after_init ma_top_mask =3D 0; + +/** + * Mask for a pdx compression bit slice. + * + * Invariant: valid(mfn) implies (mfn & pfn_hole_mask) =3D=3D 0 + */ +unsigned long __ro_after_init pfn_hole_mask =3D 0; + +/** Number of bits of the "compressible" bit slice of an mfn */ +unsigned int __ro_after_init pfn_pdx_hole_shift =3D 0; + +bool pdx_is_region_compressible(paddr_t base, unsigned long npages) +{ + return !(paddr_to_pfn(base) & pfn_hole_mask) && + !(pdx_region_mask(base, npages * PAGE_SIZE) & ~ma_va_bottom_mas= k); +} + bool __init pfn_pdx_compression_setup(paddr_t base) { unsigned int i, j, bottom_shift =3D 0, hole_shift =3D 0; --=20 2.49.0 From nobody Fri Oct 31 03:54:05 2025 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1750417931; cv=none; d=zohomail.com; s=zohoarc; b=P5zMNA2wBQi2ZcrmBk54m4Sb2M1e0siRz8DIi7OdNBs0ibbbS+kgt/DY5kZATUQ4OWOG5gg6lq/sgS47uhomkCgNBL/8X1ZgagArNFT/m4ivZJkzt1Wr6gI0Qr9Q0hEjJPycc/2ib+FJA4wTxzQjIjc7Kfs4ofO7Cg6DimkhqtU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750417931; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=0EppsXevlN8t9Gr9z9XeGe/QocwyvsD0c3ipo1S2G3o=; b=FaNnu1g+3zfXEweUIKuhuF0pmU2bQjs2j7SIiTIb4rOkrV1MGlBZeFbQggzfmvla5x520EUu2kKMcRxgB0ajNp+CYN9lr9DRjvyMRw507iyxTZFERTlzjkSEohIP6bCDxc3z1vEmDFXTGGbbLIm3os6XZNHq/c38o41eHZsFGsc= ARC-Authentication-Results: i=1; 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; 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 1750417931760432.131960622934; Fri, 20 Jun 2025 04:12:11 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1020852.1397046 (Exim 4.92) (envelope-from ) id 1uSZev-0007Xa-CN; Fri, 20 Jun 2025 11:11:49 +0000 Received: by outflank-mailman (output) from mailman id 1020852.1397046; Fri, 20 Jun 2025 11:11:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZev-0007XI-5P; Fri, 20 Jun 2025 11:11:49 +0000 Received: by outflank-mailman (input) for mailman id 1020852; Fri, 20 Jun 2025 11:11:47 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uSZet-0005XV-Ac for xen-devel@lists.xenproject.org; Fri, 20 Jun 2025 11:11:47 +0000 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [2a00:1450:4864:20::331]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 59dcd9af-4dc7-11f0-b894-0df219b8e170; Fri, 20 Jun 2025 13:11:45 +0200 (CEST) Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-450ce3a2dd5so16034065e9.3 for ; Fri, 20 Jun 2025 04:11:45 -0700 (PDT) Received: from localhost (112.pool92-178-7.dynamic.orange.es. [92.178.7.112]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a6d117bf84sm1799740f8f.52.2025.06.20.04.11.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 04:11:43 -0700 (PDT) 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" X-Inumbo-ID: 59dcd9af-4dc7-11f0-b894-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1750417904; x=1751022704; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0EppsXevlN8t9Gr9z9XeGe/QocwyvsD0c3ipo1S2G3o=; b=v77PPkKLFkd0FhahMzY5fthx3M7oJbuzU/TQfe94GYFS4V0woo5yb8AmhHD11n0SzH bGi9yQDfv6uXSJfVDjXfkIcT1Oh/uZYFCwpUEpwOjy4RUCW8pYxHZqyXo/7s7mOpYebr HpeiIDpy/EZnXPhS4zVNqiBVUcqwxRTLuFp4I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750417904; x=1751022704; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0EppsXevlN8t9Gr9z9XeGe/QocwyvsD0c3ipo1S2G3o=; b=KhnyY+ehv8PckgFv1DWt+shU5oEzxiv3hvw0vkU98OtYlAa5WX8emx7NO28H/mc4Ei Nir3v9lKsLkgqRvwkGePzInVm36oZ0fbwToaM7JJT9i7WorPnkqMhM8vaP9om8O168HY LgABqOKamuuWQVZW6b926FZm9PAnd7v+CiBeqb14mbV8mHnPYoVoFLX5QkpAp2HjdkPs dz0ZZyEcBr3Qe6TnyPjl59yaP9kVj+sQk3uF75TdMIHQBtpVw0OTdBhoR4jJRXmamLhr uQARdGfCo4SOecGsvgwQiDU2P55mSKAW4hVrk9K9ojINW7JSFVEDT271Mvq6AeqsUuQj Yw1g== X-Gm-Message-State: AOJu0YyaF1YzMZiYaMuvPWIDuxtfsJDQYDO4oWOenQklAfzYJSE2FcJJ z1TOXJP2T07Gr4cV6wUt6LwsOx7MgF2CfbXdN3uS9qBfLDGQLEzXrbqbGzHaCvFdJAHNC6duC+i HiU4F X-Gm-Gg: ASbGncsuIUuy/IvmyxMJapMO+VtgU5wByEKnAQ8Prktt3PYM7Toa2QHRXlsRHZRqU5G ZlET22tSwO5Gh6xTGmVe77cq7la36T1agX3jejBb26Sf215wYJMnyq4jdvdMpF/ir4ijskPdo8j G3NrOWsNx/1K2IIZh0+TKzKUNdfLBc91AnwRu0aS1jJNCgQe5nWb5HPMX8FlmR8Dx6VGsjr/e42 H0GloT4a0HK5GdJ3tKOUBl+EzVEqVwgAzIYgue/9ETfRyRZRG2dF5aoqsrOABmRgb4txhC6AkNf QufmwEi81byuQO2j/IuUgAixoENSSsw3AFADU0+VM4PWL7EZDvSWmiIuFFUi+GmJ9XKldWvAzek hr8qobRLZSjWC4vZ/0tXOqeR/g7N5Xg== X-Google-Smtp-Source: AGHT+IHH4E8k77+piYjiOuRyGh86QQCIMgfRjfInHrK0vvRWK5fzMQEJ5BPi30ToGUQQYUL1Mv4DEg== X-Received: by 2002:a05:6000:4203:b0:3a4:fea6:d49f with SMTP id ffacd0b85a97d-3a6d12eb49emr1750944f8f.49.1750417903822; Fri, 20 Jun 2025 04:11:43 -0700 (PDT) From: Roger Pau Monne To: xen-devel@lists.xenproject.org Cc: Roger Pau Monne , Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v2 8/8] pdx: introduce a new compression algorithm based on region offsets Date: Fri, 20 Jun 2025 13:11:30 +0200 Message-ID: <20250620111130.29057-9-roger.pau@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250620111130.29057-1-roger.pau@citrix.com> References: <20250620111130.29057-1-roger.pau@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1750417932624116600 With the appearance of Intel Sierra Forest and Granite Rapids it's now possible to get a production x86 host with the following memory map: SRAT: Node 0 PXM 0 [0000000000000000, 000000007fffffff] SRAT: Node 0 PXM 0 [0000000100000000, 000000807fffffff] SRAT: Node 1 PXM 1 [0000063e80000000, 000006be7fffffff] SRAT: Node 2 PXM 2 [00000c7e80000000, 00000cfe7fffffff] SRAT: Node 3 PXM 3 [000012be80000000, 0000133e7fffffff] This is from a four socket Granite Rapids system, with each node having 512GB of memory. The total amount of RAM on the system is 2TB, but without enabling CONFIG_BIGMEM the last range is not accessible, as it's above the 16TB boundary covered by the frame table. Sierra Forest and Granite Rapids are socket compatible, however Sierra Forest only supports 2 socket configurations, while Granite Rapids can go up to 8 sockets. Note that while the memory map is very sparse, it couldn't be compressed using the current PDX_MASK compression algorithm, which relies on all ranges having a shared zeroed region of bits that can be removed. The memory map presented above has the property of all regions being similarly spaced between each other, and all having also a similar size. Use a lookup table to store the offsets to translate from/to PFN and PDX spaces. Such table is indexed based on the input PFN or PDX to translated. The example PFN layout about would get compressed using the following: PFN compression using PFN lookup table shift 29 and PDX region size 0x10000= 000 range 0 [0000000000000, 0x0000807ffff] PFN IDX 0 : 0000000000000 range 1 [0x00063e80000, 0x0006be7ffff] PFN IDX 3 : 0x00053e80000 range 2 [0x000c7e80000, 0x000cfe7ffff] PFN IDX 6 : 0x000a7e80000 range 3 [0x0012be80000, 0x00133e7ffff] PFN IDX 9 : 0x000fbe80000 Note how the tow ranges belonging to node 0 get merged into a single PDX region by the compression algorithm. The default size of lookup tables currently set in Kconfig is 64 entries, and the example memory map consumes 10 entries. Such memory map is from a 4 socket Granite Rapids host, which in theory supports up to 8 sockets according to Intel documentation. Assuming the layout of a 8 socket system is similar to the 4 socket one, it would require 21 lookup table entries to support it, way below the current default of 64 entries. The valid range of lookup table size is currently restricted from 1 to 512 elements in Kconfig. Unused lookup table entries are set to all ones (~0UL), so that we can detect whether a pfn or pdx is valid just by checking whether its translation is bi-directional. The saturated offsets will prevent the translation from being bidirectional if the lookup table entry is not valid. Introduce __init_or_pdx_mask and use it on some shared functions between PDX mask and offset compression, as otherwise some code becomes unreachable after boot if PDX offset compression is used. Mark the code as __init in that case, so it's pruned after boot. Signed-off-by: Roger Pau Monn=C3=A9 --- Changes since v1: - Use a lookup table with the offsets. - Split the adding of the test to a pre-patch. - Amend diagram to also show possible padding after compression. --- CHANGELOG.md | 3 + tools/tests/pdx/.gitignore | 1 + tools/tests/pdx/Makefile | 3 +- tools/tests/pdx/harness.h | 10 ++ tools/tests/pdx/test-pdx.c | 4 + xen/common/Kconfig | 21 +++- xen/common/pdx.c | 209 ++++++++++++++++++++++++++++++++++++- xen/include/xen/pdx.h | 85 ++++++++++++++- 8 files changed, 330 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f31ca08fe3f..7023820b38c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ The format is based on [Keep a Changelog](https://keepach= angelog.com/en/1.0.0/) grant table or foreign memory. =20 ### Added + - Introduce new PDX compression algorithm to cope with Intel Sapphire and + Granite Rapids having sparse memory maps. + - On x86: - Option to attempt to fixup p2m page-faults on PVH dom0. - Resizable BARs is supported for PVH dom0. diff --git a/tools/tests/pdx/.gitignore b/tools/tests/pdx/.gitignore index a32c7db4de79..1202a531a7fd 100644 --- a/tools/tests/pdx/.gitignore +++ b/tools/tests/pdx/.gitignore @@ -1,2 +1,3 @@ /pdx.h /test-pdx-mask +/test-pdx-offset diff --git a/tools/tests/pdx/Makefile b/tools/tests/pdx/Makefile index 99867b71c438..ba1724bb6616 100644 --- a/tools/tests/pdx/Makefile +++ b/tools/tests/pdx/Makefile @@ -1,7 +1,7 @@ XEN_ROOT=3D$(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk =20 -TARGETS :=3D test-pdx-mask +TARGETS :=3D test-pdx-mask test-pdx-offset =20 .PHONY: all all: $(TARGETS) @@ -41,6 +41,7 @@ CFLAGS +=3D $(APPEND_CFLAGS) CFLAGS +=3D $(CFLAGS_xeninclude) =20 test-pdx-mask: CFLAGS +=3D -DCONFIG_PDX_MASK_COMPRESSION +test-pdx-offset: CFLAGS +=3D -DCONFIG_PDX_OFFSET_COMPRESSION =20 test-pdx-%: test-pdx.c pdx.h $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_$*.o) -o $@ $< $(APPEND_CFLAGS) diff --git a/tools/tests/pdx/harness.h b/tools/tests/pdx/harness.h index 64ec09f5e281..c58a6f27ad03 100644 --- a/tools/tests/pdx/harness.h +++ b/tools/tests/pdx/harness.h @@ -44,8 +44,10 @@ =20 #define MAX_RANGES 8 #define MAX_PFN_RANGES MAX_RANGES +#define CONFIG_PDX_OFFSET_TLB_ORDER 6 =20 #define ASSERT assert +#define ASSERT_UNREACHABLE() assert(0); =20 #define CONFIG_DEBUG =20 @@ -66,6 +68,8 @@ static inline unsigned int find_next( #define find_next_zero_bit(a, s, o) find_next(a, s, o, false) #define find_next_bit(a, s, o) find_next(a, s, o, true) =20 +#define flsl(x) ((x) ? BITS_PER_LONG - __builtin_clzl(x) : 0) + #define boolean_param(name, func) =20 #define pdx_to_pfn pdx_to_pfn_xlate @@ -75,6 +79,12 @@ static inline unsigned int find_next( =20 typedef uint64_t paddr_t; =20 +#define sort(elem, nr, size, cmp, swp) { \ + /* Consume swp() so compiler doesn't complain it's unused. */ \ + (void)swp; \ + qsort(elem, nr, size, cmp); \ +} + #include "pdx.h" =20 #endif diff --git a/tools/tests/pdx/test-pdx.c b/tools/tests/pdx/test-pdx.c index b717cae00711..5041228a383c 100644 --- a/tools/tests/pdx/test-pdx.c +++ b/tools/tests/pdx/test-pdx.c @@ -51,7 +51,11 @@ int main(int argc, char **argv) { .start =3D 0xc7e80000UL, .end =3D 0xcfe80000UL }, { .start =3D 0x12be80000UL, .end =3D 0x133e80000UL }, }, +#ifdef CONFIG_PDX_OFFSET_COMPRESSION + .compress =3D true, +#else .compress =3D false, +#endif }, /* Simple hole. */ { diff --git a/xen/common/Kconfig b/xen/common/Kconfig index de3e01d6320e..6d49ef535f0c 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -54,7 +54,8 @@ config EVTCHN_FIFO =20 choice prompt "PDX (Page inDeX) compression" - default PDX_MASK_COMPRESSION if !X86 && !RISCV + default PDX_OFFSET_COMPRESSION if X86 + default PDX_MASK_COMPRESSION if !RISCV default PDX_NONE help PDX compression is a technique designed to reduce the memory @@ -73,12 +74,30 @@ config PDX_MASK_COMPRESSION help Compression relying on all RAM addresses sharing a zeroed bit region. =20 +config PDX_OFFSET_COMPRESSION + bool "Offset compression" + help + Compression relying on size and distance between RAM regions being + compressible using an offset lookup table. + config PDX_NONE bool "None" help No compression endchoice =20 +config PDX_OFFSET_TLB_ORDER + int "PDX offset compression lookup table order" if EXPERT + depends on PDX_OFFSET_COMPRESSION + default 6 + range 0 9 + help + Order of the PFN to PDX and PDX to PFN translation lookup tables. + Number of table entries is calculated as 2^N. + + Size of the tables can be adjusted from 1 entry (order 0) to 512 + entries (order 9). + config ALTERNATIVE_CALL bool =20 diff --git a/xen/common/pdx.c b/xen/common/pdx.c index d5e469baffe2..ff3534122c72 100644 --- a/xen/common/pdx.c +++ b/xen/common/pdx.c @@ -24,6 +24,7 @@ #include #include #include +#include =20 /** * Maximum (non-inclusive) usable pdx. Must be @@ -40,6 +41,8 @@ bool __mfn_valid(unsigned long mfn) =20 #ifdef CONFIG_PDX_MASK_COMPRESSION invalid |=3D mfn & pfn_hole_mask; +#elif defined(CONFIG_PDX_OFFSET_COMPRESSION) + invalid |=3D mfn ^ pdx_to_pfn(pfn_to_pdx(mfn)); #endif =20 if ( unlikely(evaluate_nospec(invalid)) ) @@ -75,6 +78,13 @@ void set_pdx_range(unsigned long smfn, unsigned long emf= n) # error "Missing architecture maximum number of RAM ranges" #endif =20 +/* Some functions should be init when not using PDX mask compression. */ +#ifndef CONFIG_PDX_MASK_COMPRESSION +# define __init_or_pdx_mask __init +#else +# define __init_or_pdx_mask +#endif + /* Generic PFN compression helpers. */ static struct pfn_range { unsigned long base, size; @@ -102,7 +112,7 @@ void __init pfn_pdx_add_region(paddr_t base, paddr_t si= ze) } =20 /* Sets all bits from the most-significant 1-bit down to the LSB */ -static uint64_t fill_mask(uint64_t mask) +static uint64_t __init_or_pdx_mask fill_mask(uint64_t mask) { while (mask & (mask + 1)) mask |=3D mask + 1; @@ -128,7 +138,7 @@ static uint64_t fill_mask(uint64_t mask) * @param len Size in octets of the region * @return Mask of moving bits at the bottom of all the region addresses */ -static uint64_t pdx_region_mask(uint64_t base, uint64_t len) +static uint64_t __init_or_pdx_mask pdx_region_mask(uint64_t base, uint64_t= len) { /* * We say a bit "moves" in a range if there exist 2 addresses in that @@ -290,7 +300,200 @@ void __init pfn_pdx_compression_reset(void) nr_ranges =3D 0; } =20 -#endif /* CONFIG_PDX_COMPRESSION */ +#elif defined(CONFIG_PDX_OFFSET_COMPRESSION) /* CONFIG_PDX_MASK_COMPRESSIO= N */ + +unsigned long __ro_after_init pfn_pdx_lookup[CONFIG_PDX_NR_LOOKUP]; +unsigned int __ro_after_init pfn_index_shift; + +unsigned long __ro_after_init pdx_pfn_lookup[CONFIG_PDX_NR_LOOKUP]; +unsigned int __ro_after_init pdx_index_shift; + +bool pdx_is_region_compressible(paddr_t base, unsigned long npages) +{ + unsigned long pfn =3D PFN_DOWN(base); + + return pdx_to_pfn(pfn_to_pdx(pfn) + npages - 1) =3D=3D (pfn + npages -= 1); +} + +static int __init cf_check cmp_node(const void *a, const void *b) +{ + const struct pfn_range *l =3D a; + const struct pfn_range *r =3D b; + + if ( l->base > r->base ) + return 1; + if ( l->base < r->base ) + return -1; + + return 0; +} + +static void __init cf_check swp_node(void *a, void *b, size_t size) +{ + struct pfn_range *l =3D a; + struct pfn_range *r =3D b; + struct pfn_range tmp =3D *l; + + *l =3D *r; + *r =3D tmp; +} + +static bool __init pfn_offset_sanitize_ranges(void) +{ + unsigned int i =3D 0; + + if ( nr_ranges =3D=3D 1 ) + { + ASSERT(PFN_TBL_IDX_VALID(ranges[0].base)); + ASSERT(PFN_TBL_IDX(ranges[0].base) =3D=3D + PFN_TBL_IDX(ranges[0].base + ranges[0].size - 1)); + return true; + } + + /* Sort nodes by start address. */ + sort(ranges, nr_ranges, sizeof(struct pfn_range), cmp_node, swp_node); + + /* Sanitize and merge ranges if possible. */ + while ( i + 1 < nr_ranges ) + { + /* No overlap between ranges. */ + if ( ranges[i].base + ranges[i].size > ranges[i + 1].base ) + { + printk(XENLOG_WARNING +"Invalid ranges for PDX compression: [%#lx, %#lx] overlaps [%#lx, %#lx]\n", + ranges[i].base, ranges[i].base + ranges[i].size - 1, + ranges[i + 1].base, + ranges[i + 1].base + ranges[i + 1].size - 1); + return false; + } + + /* Ensure lookup indexes don't overflow table size. */ + if ( !PFN_TBL_IDX_VALID(ranges[i].base) || + !PFN_TBL_IDX_VALID(ranges[i].base + ranges[i].size - 1) || + !PFN_TBL_IDX_VALID(ranges[i + 1].base) || + !PFN_TBL_IDX_VALID(ranges[i + 1].base + ranges[i + 1].size - = 1) ) + return false; + + /* + * Ensure ranges [start, end] use the same offset table index. Sh= ould + * be guaranteed by the logic that calculates the pfn shift. + */ + if ( PFN_TBL_IDX(ranges[i].base) !=3D + PFN_TBL_IDX(ranges[i].base + ranges[i].size - 1) || + PFN_TBL_IDX(ranges[i + 1].base) !=3D + PFN_TBL_IDX(ranges[i + 1].base + ranges[i + 1].size - 1) ) + { + ASSERT_UNREACHABLE(); + return false; + } + + if ( PFN_TBL_IDX(ranges[i].base) !=3D PFN_TBL_IDX(ranges[i + 1].ba= se) ) + { + i++; + continue; + } + + /* Merge ranges with the same table index. */ + ranges[i].size =3D ranges[i + 1].base + ranges[i + 1].size - + ranges[i].base; + memmove(&ranges[i + 1], &ranges[i + 2], + (nr_ranges - (i + 2)) * sizeof(ranges[0])); + nr_ranges--; + } + + return true; +} + +bool __init pfn_pdx_compression_setup(paddr_t base) +{ + unsigned long size =3D 0, mask =3D PFN_DOWN(pdx_init_mask(base)); + unsigned int i; + + if ( !nr_ranges ) + return false; + + if ( nr_ranges > ARRAY_SIZE(ranges) ) + { + printk(XENLOG_WARNING + "Too many PFN ranges (%u > %zu), not attempting PFN compres= sion\n", + nr_ranges, ARRAY_SIZE(ranges)); + return false; + } + + for ( i =3D 0; i < nr_ranges; i++ ) + mask |=3D pdx_region_mask(ranges[i].base, ranges[i].size); + + pfn_index_shift =3D flsl(mask); + + /* + * Increase the shift as much as possible, removing bits that are equa= l in + * all regions, as this allows the usage of smaller indexes, and in tu= rn + * smaller lookup tables. + */ + for ( pfn_index_shift =3D flsl(mask); pfn_index_shift < sizeof(mask) *= 8 - 1; + pfn_index_shift++ ) + { + const unsigned long bit =3D ranges[0].base & (1UL << pfn_index_shi= ft); + + for ( i =3D 1; i < nr_ranges; i++ ) + if ( bit !=3D (ranges[i].base & (1UL << pfn_index_shift)) ) + break; + if ( i !=3D nr_ranges ) + break; + } + + /* Sort and sanitize ranges. */ + if ( !pfn_offset_sanitize_ranges() ) + return false; + + /* Calculate PDX region size. */ + for ( i =3D 0; i < nr_ranges; i++ ) + size =3D max(size, ranges[i].size); + + mask =3D PFN_DOWN(pdx_init_mask(size << PAGE_SHIFT)); + pdx_index_shift =3D flsl(mask); + + /* Avoid compression if there's no gain. */ + if ( (mask + 1) * (nr_ranges - 1) >=3D ranges[nr_ranges - 1].base ) + return false; + + /* Poison all lookup table entries ahead of setting them. */ + memset(pfn_pdx_lookup, ~0, sizeof(pfn_pdx_lookup)); + memset(pdx_pfn_lookup, ~0, sizeof(pfn_pdx_lookup)); + + for ( i =3D 0; i < nr_ranges; i++ ) + { + unsigned int idx =3D PFN_TBL_IDX(ranges[i].base); + + pfn_pdx_lookup[idx] =3D ranges[i].base - (mask + 1) * i; + pdx_pfn_lookup[i] =3D pfn_pdx_lookup[idx]; + } + + printk(XENLOG_INFO + "PFN compression using PFN lookup table shift %u and PDX region= size %#lx\n", + pfn_index_shift, mask + 1); + + for ( i =3D 0; i < nr_ranges; i++ ) + printk(XENLOG_DEBUG + " range %u [%#013lx, %#013lx] PFN IDX %3lu : %#013lx\n", + i, ranges[i].base, ranges[i].base + ranges[i].size - 1, + PFN_TBL_IDX(ranges[i].base), + pfn_pdx_lookup[PFN_TBL_IDX(ranges[i].base)]); + + return true; +} + +void __init pfn_pdx_compression_reset(void) +{ + memset(pfn_pdx_lookup, 0, sizeof(pfn_pdx_lookup)); + memset(pdx_pfn_lookup, 0, sizeof(pfn_pdx_lookup)); + pfn_index_shift =3D 0; + pdx_index_shift =3D 0; + + nr_ranges =3D 0; +} + +#endif /* CONFIG_PDX_OFFSET_COMPRESSION */ =20 /* * Local variables: diff --git a/xen/include/xen/pdx.h b/xen/include/xen/pdx.h index 91fc32370f21..450e07de2764 100644 --- a/xen/include/xen/pdx.h +++ b/xen/include/xen/pdx.h @@ -65,6 +65,43 @@ * This scheme also holds for multiple regions, where HHHHHHH acts as * the region identifier and LLLLLL fully contains the span of every * region involved. + * + * ##=C2=A0PDX offset compression + * + * Alternative compression mechanism that relies on RAM ranges having a si= milar + * size and offset between them: + * + * PFN address space: + * =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90= =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 + * =E2=94=82 RAM 0 =E2=94=82 =E2=94=82 RAM 1 =E2=94=82 = =E2=94=82...=E2=94=82 RAM N =E2=94=82 =E2=94=82 + * =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98= =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 + * =E2=94=82<------>=E2=94=82 =E2=94=82 + * =E2=94=82 size =E2=94=82 + * =E2=94=82<----------------->=E2=94=82 + * offset + * + * The compression reduces the holes between RAM regions: + * + * PDX address space: + * =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=AC=E2=94=80=E2= =94=80=E2=94=80=E2=94=90 =E2=94=8C=E2=94=80=E2=94=AC=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=90 + * =E2=94=82 RAM 0 =E2=94=82 =E2=94=82 RAM 1 =E2=94=82 =E2=94=82...= =E2=94=82 =E2=94=82 RAM N =E2=94=82 + * =E2=94=9C=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2=94=80=E2=94=BC=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=B4=E2=94=80=E2= =94=80=E2=94=80=E2=94=98 =E2=94=94=E2=94=80=E2=94=B4=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=98 + * =E2=94=82<---------->=E2=94=82 + * pdx region size + * + * The offsets to convert from PFN to PDX and from PDX to PFN are stored i= n a + * pair of lookup tables, and the index into those tables to find the offs= et + * for each PFN or PDX is obtained by shifting the to be translated addres= s by + * a specific value calculated at boot: + * + * pdx =3D pfn - pfn_lookup_table[pfn >> pfn_shift] + * pfn =3D pdx + pdx_lookup_table[pdx >> pdx_shift] + * + * This compression requires the PFN ranges to contain a non-equal most + * significant part that's smaller than the lookup table size, so that a v= alid + * shift value can be found to differentiate between PFN regions. The set= up + * algorithm might merge otherwise separate PFN ranges to use the same loo= kup + * table entry. */ =20 extern unsigned long max_pdx; @@ -157,7 +194,53 @@ static inline paddr_t directmapoff_to_maddr_xlate(unsi= gned long offset) (offset & ma_va_bottom_mask)); } =20 -#endif /* CONFIG_PDX_MASK_COMPRESSION */ +#elif defined(CONFIG_PDX_OFFSET_COMPRESSION) /* CONFIG_PDX_MASK_COMPRESSIO= N */ + +#include + +#define CONFIG_PDX_NR_LOOKUP (1UL << CONFIG_PDX_OFFSET_TLB_ORDER) +#define PDX_TBL_MASK (CONFIG_PDX_NR_LOOKUP - 1) + +#define PFN_TBL_IDX_VALID(pfn) \ + !(((pfn) >> pfn_index_shift) & ~PDX_TBL_MASK) + +#define PFN_TBL_IDX(pfn) \ + (((pfn) >> pfn_index_shift) & PDX_TBL_MASK) +#define PDX_TBL_IDX(pdx) \ + (((pdx) >> pdx_index_shift) & PDX_TBL_MASK) +#define MADDR_TBL_IDX(ma) \ + (((ma) >> (pfn_index_shift + PAGE_SHIFT)) & PDX_TBL_MASK) +#define DMAPOFF_TBL_IDX(off) \ + (((off) >> (pdx_index_shift + PAGE_SHIFT)) & PDX_TBL_MASK) + +extern unsigned long pfn_pdx_lookup[]; +extern unsigned int pfn_index_shift; + +extern unsigned long pdx_pfn_lookup[]; +extern unsigned int pdx_index_shift; + +static inline unsigned long pfn_to_pdx_xlate(unsigned long pfn) +{ + return pfn - pfn_pdx_lookup[PFN_TBL_IDX(pfn)]; +} + +static inline unsigned long pdx_to_pfn_xlate(unsigned long pdx) +{ + return pdx + pdx_pfn_lookup[PDX_TBL_IDX(pdx)]; +} + +static inline unsigned long maddr_to_directmapoff_xlate(paddr_t ma) +{ + return ma - ((paddr_t)pfn_pdx_lookup[MADDR_TBL_IDX(ma)] << PAGE_SHIFT); +} + +static inline paddr_t directmapoff_to_maddr_xlate(unsigned long offset) +{ + return offset + ((paddr_t)pdx_pfn_lookup[DMAPOFF_TBL_IDX(offset)] << + PAGE_SHIFT); +} + +#endif /* CONFIG_PDX_OFFSET_COMPRESSION */ =20 /* * Allow each architecture to define it's (possibly optimized) versions of= the --=20 2.49.0