From nobody Wed Feb 11 10:35:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1770720792; cv=none; d=zohomail.com; s=zohoarc; b=iw80OjyyWmsuTm/Fk5YIekmyfdPz0pn3Gie9ZHklyy5EXSGImOX+cwDqouOHvkq0jpR+YWeIZgWhAILmTSV5+xfv9B/s2P4rdOBrLWNzg5fxw8svJQAZ54RctvOkiOBpR4XHCHmZER75tEkarkVly5HyAoCziYDyEj+nZhwtlOk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770720792; 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=eJHKitDbZ1B8kzKIjRTpmb8+1aYuXto+6m6ltPFsdaA=; b=c6y/erdL6qRUcvS/PVRD5b+0xAMimxzwx3oe+fnrMkanW0QZakAqJNXU/LrD1L7Yt2ffP4vG6ScaGUoKkRvSps5yiszlSOexBoMqlEdoOKcseVXspVfkTTEEQTO1vt2tdikL8YIbUM+zXnOeACrMsOwh/xYbjS5hVUA/o1S6tO8= 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=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770720792373778.0819087867566; Tue, 10 Feb 2026 02:53:12 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1226233.1532766 (Exim 4.92) (envelope-from ) id 1vplMT-0004ju-A2; Tue, 10 Feb 2026 10:52:53 +0000 Received: by outflank-mailman (output) from mailman id 1226233.1532766; Tue, 10 Feb 2026 10:52:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vplMT-0004jn-6v; Tue, 10 Feb 2026 10:52:53 +0000 Received: by outflank-mailman (input) for mailman id 1226233; Tue, 10 Feb 2026 10:52:52 +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 1vplMS-0004jf-8L for xen-devel@lists.xenproject.org; Tue, 10 Feb 2026 10:52:52 +0000 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [2a00:1450:4864:20::42e]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id a522676b-066e-11f1-b162-2bf370ae4941; Tue, 10 Feb 2026 11:52:51 +0100 (CET) Received: by mail-wr1-x42e.google.com with SMTP id ffacd0b85a97d-436e87589e8so1971499f8f.3 for ; Tue, 10 Feb 2026 02:52:51 -0800 (PST) Received: from [10.156.60.236] (ip-037-024-206-209.um08.pools.vodafone-ip.de. [37.24.206.209]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4362974b230sm37056571f8f.36.2026.02.10.02.52.50 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Feb 2026 02:52:50 -0800 (PST) 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: a522676b-066e-11f1-b162-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1770720771; x=1771325571; darn=lists.xenproject.org; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=eJHKitDbZ1B8kzKIjRTpmb8+1aYuXto+6m6ltPFsdaA=; b=Jq1Fz/wgwMc8jbYcv5HMTV4DIwNX0sZUNSK1itQ4iVrIo0kHPNug2ZW/lOMjcApMyU w68ZpQPd/mzgHSpDzZzuTayJXdRffXvzc9nUe1S0AI2szGR4vtqQ0f2zAVaOJ/o5AsEY i1X0tKt+2SB5Ih8plYogqLCnzYWMbzZvPLkmGAiwSCH6mrYZZocMDafSVbmVAZf5yR/B OvRF//9FYrJKwQzT2ezWO7A8xoU6ZoWCmg+z6uhFQBrUxuLBgLS4+sq+amuD2yUkdBTz L+hXk4M75mOHR2AhKYnX8lEDDqk26HTFmSUXVle6aITcRIwNs7tC2PWG/DoZZWsQdqa+ G8yg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770720771; x=1771325571; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=eJHKitDbZ1B8kzKIjRTpmb8+1aYuXto+6m6ltPFsdaA=; b=AwHMoQi8VYDKRrYmtXsiMjukN9xBq6khM2mcQ/9NIvWyILx7FwyS64pOyoMJ0MdfGH OCbR6r+FpMdfDqljkF6FX0r5CfPZBCWdPNqxNk/L3b0bU2zxcjgODVBfM8pEjAQ+SBjb 6Cv7wS7j2083fGeZGS3okxF+nQ1knL/iCwoYd46xTDRlrevc4E9HzXMaHiQulMwMS2Ee hHctB4nTxmkTBcPuBbd+gBBwclBuvfj6iIjFWQGCDhe66S3Iofv1I89+TgyoGEKSMbnH I+BOVp2ByrbHYdfpznQDzsFeixXhP4B5REZPf/V1CMbQYunxvuBa+AZ5D17MYodjsSau BszQ== X-Gm-Message-State: AOJu0YxfWi8x4ZWj3vAzpquerkCWOQSasr0QyuGC3i2H49q4pRnr2vbM f5KalVZhrZY8FfwtEzWxHZUVcNzKCtWTCrsG8aZ5Q2KupEjaHs1vq83XJ6k1RjEOR8v4OcGRhL7 /Ga0= X-Gm-Gg: AZuq6aLKzEMOULbzYrEV7XeA46L43TBC8N/vznCs1WHUM6SLXacHHR4qXSlf52y/1xB N/ZvBcCY/etC++H+OfH7hpRVtUzsSPRkBmqwqRzhyD5Fhfp5kjwwlZokytVyOa+PQh8AsuQFLdx sl3p0hmu20QDykSEVbT7DaJVUVigrU+eONW4oUFTrl6rNClfGzHvGTrFhE0surpxUoWdnfojpOc JO0AeqRvl6wYFwgIWQG5qGrpoKyUw2tvrVrJs3rXbHe81SyqHuyP5JL4/oZgvy9pomVLtI/7mCH imx3QbzNA7k+A/UqaJFcZyQ3mR4x2FEPds1qrdr6DRvV/wrr2SjJCPOqRyQElvurnKmyqv58ujG e0GnqQsfIbmLHm0Qp/E72m1l+GzyqmsBkik8HPMFQivY+f2dtBJ1DZCzPKNSb3BVh3V6u75Ipwm cf4vymbkoRNApGaXBIJW+2q3ebv0D8fcxZKQuTUslBk+usBNE5+pgTQV0LveVK04oEVylj0Kl/x EWKdwaoz43J63Y= X-Received: by 2002:a05:6000:144f:b0:431:9dd:2cca with SMTP id ffacd0b85a97d-4377a503d26mr2412970f8f.7.1770720770561; Tue, 10 Feb 2026 02:52:50 -0800 (PST) Message-ID: Date: Tue, 10 Feb 2026 11:52:49 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v4 1/5] x86/PCI: avoid re-evaluation of extended config space accessibility From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand References: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Language: en-US Autocrypt: addr=jbeulich@suse.com; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL In-Reply-To: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1770720794889154100 When, during boot, we have already correctly determined availability of the MMCFG access method for a given bus range, there's then no need to invoke pci_check_extcfg() again for every of the devices. This in particular avoids ->ext_cfg to transiently indicate the wrong state. Switch to using Xen style on lines being touched and immediately adjacent ones. Signed-off-by: Jan Beulich Acked-by: Roger Pau Monn=C3=A9 Reviewed-by: Stewart Hildebrand --- v4: Don't bypass mcfg_ioremap(cfg, idx, 0) in pci_mmcfg_arch_disable(). v3: New. --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -528,6 +528,8 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H if ( !ret ) ret =3D pci_segment_iterate(info.segment, physdev_check_pci_ex= tcfg, &info); + else if ( ret > 0 ) /* Indication of "no change". */ + ret =3D 0; =20 if ( !ret && has_vpci(currd) && (info.flags & XEN_PCI_MMCFG_RESERV= ED) ) { --- a/xen/arch/x86/x86_64/mmconfig.h +++ b/xen/arch/x86/x86_64/mmconfig.h @@ -74,6 +74,6 @@ int pci_mmcfg_reserved(uint64_t address, unsigned int flags); int pci_mmcfg_arch_init(void); int pci_mmcfg_arch_enable(unsigned int idx); -void pci_mmcfg_arch_disable(unsigned int idx); +int pci_mmcfg_arch_disable(unsigned int idx); =20 #endif /* X86_64_MMCONFIG_H */ --- a/xen/arch/x86/x86_64/mmconfig-shared.c +++ b/xen/arch/x86/x86_64/mmconfig-shared.c @@ -388,8 +388,9 @@ static bool __init pci_mmcfg_reject_brok (unsigned int)cfg->start_bus_number, (unsigned int)cfg->end_bus_number); =20 - if (!is_mmconf_reserved(addr, size, i, cfg) || - pci_mmcfg_arch_enable(i)) { + if ( !is_mmconf_reserved(addr, size, i, cfg) || + pci_mmcfg_arch_enable(i) < 0 ) + { pci_mmcfg_arch_disable(i); valid =3D 0; } @@ -417,8 +418,8 @@ void __init acpi_mmcfg_init(void) unsigned int i; =20 pci_mmcfg_arch_init(); - for (i =3D 0; i < pci_mmcfg_config_num; ++i) - if (pci_mmcfg_arch_enable(i)) + for ( i =3D 0; i < pci_mmcfg_config_num; ++i ) + if ( pci_mmcfg_arch_enable(i) < 0 ) valid =3D 0; } else { acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); @@ -458,10 +459,11 @@ int pci_mmcfg_reserved(uint64_t address, segment, start_bus, end_bus, address, cfg->address); return -EIO; } - if (flags & XEN_PCI_MMCFG_RESERVED) + + if ( flags & XEN_PCI_MMCFG_RESERVED ) return pci_mmcfg_arch_enable(i); - pci_mmcfg_arch_disable(i); - return 0; + + return pci_mmcfg_arch_disable(i); } } =20 --- a/xen/arch/x86/x86_64/mmconfig_64.c +++ b/xen/arch/x86/x86_64/mmconfig_64.c @@ -138,8 +138,9 @@ int pci_mmcfg_arch_enable(unsigned int i const typeof(pci_mmcfg_config[0]) *cfg =3D pci_mmcfg_virt[idx].cfg; unsigned long start_mfn, end_mfn; =20 - if (pci_mmcfg_virt[idx].virt) - return 0; + if ( pci_mmcfg_virt[idx].virt ) + return 1; + pci_mmcfg_virt[idx].virt =3D mcfg_ioremap(cfg, idx, PAGE_HYPERVISOR_UC= ); if (!pci_mmcfg_virt[idx].virt) { printk(KERN_ERR "PCI: Cannot map MCFG aperture for segment %04x\n", @@ -160,9 +161,10 @@ int pci_mmcfg_arch_enable(unsigned int i return 0; } =20 -void pci_mmcfg_arch_disable(unsigned int idx) +int pci_mmcfg_arch_disable(unsigned int idx) { const typeof(pci_mmcfg_config[0]) *cfg =3D pci_mmcfg_virt[idx].cfg; + int ret =3D !pci_mmcfg_virt[idx].virt; =20 pci_mmcfg_virt[idx].virt =3D NULL; /* @@ -173,6 +175,8 @@ void pci_mmcfg_arch_disable(unsigned int mcfg_ioremap(cfg, idx, 0); printk(KERN_WARNING "PCI: Not using MCFG for segment %04x bus %02x-%02= x\n", cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number); + + return ret; } =20 bool pci_mmcfg_decode(unsigned long mfn, unsigned int *seg, unsigned int *= bdf) From nobody Wed Feb 11 10:35:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1770720850; cv=none; d=zohomail.com; s=zohoarc; b=Qvp8Im295P4eykMts6OD/RHHw34y3d/MLkpkx5X/ZPjdqjlGn8shC7YgKKtjRn/PpQZ2xDijHpDAU1wi0FbGdhUoWUJonAkhofv/i+rQVkfiH1L/X4ta04e2Yi30JOEqhILHdI7eUliSY/BaW8TPIPeGWQHVInjVhEQ0TfNAqvk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770720850; 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=UqWY/OHj/E7vo6rEZ7e1xZN5PDQeyG/GwojCyOGrDlE=; b=iizyyTDaeuLnJW/LDhl9ZFUE00zHMuTRpEU9XKpfSPaZAKURYceHH3H0MFv/hEtcYoN5mYmmNUZaBOHEugzchHI9YBaBOCPvtkugNCvcE5F7P2xjX/515LTqVcpAUt/LfPW4D5vCPe+NapjY18bcXYAG+Os4KNEWZUm0i7ydOcI= 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=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770720850305210.13040260383673; Tue, 10 Feb 2026 02:54:10 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1226242.1532775 (Exim 4.92) (envelope-from ) id 1vplNT-0005IF-Lx; Tue, 10 Feb 2026 10:53:55 +0000 Received: by outflank-mailman (output) from mailman id 1226242.1532775; Tue, 10 Feb 2026 10:53:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vplNT-0005I8-Iw; Tue, 10 Feb 2026 10:53:55 +0000 Received: by outflank-mailman (input) for mailman id 1226242; Tue, 10 Feb 2026 10:53:54 +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 1vplNS-0004jf-Ax for xen-devel@lists.xenproject.org; Tue, 10 Feb 2026 10:53:54 +0000 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [2a00:1450:4864:20::32e]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id c9f9ac04-066e-11f1-b162-2bf370ae4941; Tue, 10 Feb 2026 11:53:53 +0100 (CET) Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-482f2599980so7818395e9.0 for ; Tue, 10 Feb 2026 02:53:53 -0800 (PST) Received: from [10.156.60.236] (ip-037-024-206-209.um08.pools.vodafone-ip.de. [37.24.206.209]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43629754c62sm30715414f8f.38.2026.02.10.02.53.51 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Feb 2026 02:53:52 -0800 (PST) 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: c9f9ac04-066e-11f1-b162-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1770720832; x=1771325632; darn=lists.xenproject.org; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=UqWY/OHj/E7vo6rEZ7e1xZN5PDQeyG/GwojCyOGrDlE=; b=QAeSFrOGJd1kWJpj7JYvhOu7M5OEaeiVZu+wx8Xj/D/4DhbBbRBECUdROlb8AbcZTz 7Xsop8CUU2WqCzQV4B0z58N0k//WW1TrDbbYgxOa6B5xZ5RbzkaT1LPKaKVUDeRflf1O xKEWe4Q1J5UwkjM6l0teDY55kkiFr3YVfRLbJ0fqfbjSM5eWTBAogkF3egmNCkpbalxL BdI8tCss4WykSvz+h6r6lzuSMommUvSrEczv9W9SHnziJnO79W9hmBGcmLEQRDEEApJH FSzE8gGE7UtrGK8tVz23SeUON5MzJN/fqcYc9QwuzdhDAuKxGZl8ulFvqvULDKMCIlbQ PnjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770720832; x=1771325632; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=UqWY/OHj/E7vo6rEZ7e1xZN5PDQeyG/GwojCyOGrDlE=; b=w81RlMG5S2neZTxFbwl05nfRUUhhVmYFsb6Hz9lnvtvY0hKi0SYLFkb2cB8XM5nxtB pGuIRVWOdli5SexV57oGVCJUcv6wMcHDI7rTIBv3r/uvQnAkyZu59DcDHTCICO2VnGVK DIZmNSkaeJIJr+A4Kov3NVkf+u8s4hK9MXLXo5ALCYHwVyg2hJi6PtVD4FItmVLRF2C0 z8vVfZH5lQvD9vIGxIsTk8jf6Fy51k63E7fj0wBH6ORb0nE3vQSP9tc4XtItO2hZBxdL PiOVNNNOdrc6Ud9lkOsAcoSZAMP3GcVDq+Z+fzl7YQjjpcmkvsyI6Z5p7cpl4GHtqJ/E jBIg== X-Gm-Message-State: AOJu0YwJDUBcTj+c7hojf1NqVl3+fxu5j54kTHlJgjA+WUBAMJzwKGmf PrbuCY8f2ZxMriWBK3eidCPjq9CPeVlnuMJz/3xnFnXLgNcvTO2AJl1T0A/w6X3iHUpSwtf+U/b Z3gY= X-Gm-Gg: AZuq6aL1q04fjIvG17wcJCbqpaAlOOBY/uoXXIj338sx0XjuNsm5jVvAdATIzp3gaE0 vDDCih3mQhjT5ZTs49J5ZXKJVXrpbchbn/e2hmt687JJfBcoIN5TbfR5e+FF/0Jpn79Qov6JavI r94LDZYrhDHeDTqu6agemPVwzfkpWKh0t1kpUbwUfIpIObpip/0+RI7oZLngn2H5aIpx44ouiZc 5r2Qcgnyc6jbu9sbd2Lgw4OjvF4jLukffRCnnMkdnMLWv7m+3CPnm0FzIrdmxtyAxfyHRQ6QghS J+NXJyEa8cIV7rC5s7JEmiurm5iSUBNnE2br7JWkkATxXkmjbmaUGn5WFkP6jR1W4HK56jLQyMF 2jnm4mcQYqcV10kfoJEeR5x3XdOX0baBBylJ9SQOL6hQeYLWIJYIY1mFrpieajXNQCWQgKoeo68 /u1I0NjAgxPmoyRBwBbCn16g1c3Y74nKcq3fHBSDgl81T2QYf0MGWxpIk94wXtMnKAJ74MujFpn Bw2AsdeZBpFhSQFu1TQtvuf2A== X-Received: by 2002:a05:600c:19c7:b0:477:9814:6882 with SMTP id 5b1f17b1804b1-483201dd0afmr188048785e9.5.1770720832284; Tue, 10 Feb 2026 02:53:52 -0800 (PST) Message-ID: <4fda7acb-e1a4-4a24-982e-4cae90048018@suse.com> Date: Tue, 10 Feb 2026 11:53:51 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v4 2/5] vPCI: introduce private header From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , Julien Grall , Stefano Stabellini , Anthony PERARD , Michal Orzel , =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand , Bertrand Marquis , Volodymyr Babchuk References: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Language: en-US Autocrypt: addr=jbeulich@suse.com; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL In-Reply-To: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1770720851705158500 Content-Type: text/plain; charset="utf-8" Before adding more private stuff to xen/vpci.h, split it up. In order to be able to include the private header first in a CU, the per-arch struct decls also need to move (to new asm/vpci.h files). While adjusting the test harness'es Makefile, also switch the pre-existing header symlink-ing rule to a pattern one. Apart from in the test harness code, things only move; no functional change intended. Signed-off-by: Jan Beulich --- Subsequently, at least on x86 more stuff may want moving into asm/vpci.h. --- v4: New. --- a/tools/tests/vpci/Makefile +++ b/tools/tests/vpci/Makefile @@ -14,8 +14,8 @@ else $(warning HOSTCC !=3D CC, will not run test) endif =20 -$(TARGET): vpci.c vpci.h list.h main.c emul.h - $(CC) $(CFLAGS_xeninclude) -g -o $@ vpci.c main.c +$(TARGET): vpci.c vpci.h list.h private.h main.c emul.h + $(CC) $(CFLAGS_xeninclude) -include emul.h -g -o $@ vpci.c main.c =20 .PHONY: clean clean: @@ -34,10 +34,10 @@ uninstall: $(RM) -- $(DESTDIR)$(LIBEXEC)/tests/$(TARGET) =20 vpci.c: $(XEN_ROOT)/xen/drivers/vpci/vpci.c - # Remove includes and add the test harness header - sed -e '/#include/d' -e '1s/^/#include "emul.h"/' <$< >$@ + sed -e '/#include/d' <$< >$@ + +private.h: %.h: $(XEN_ROOT)/xen/drivers/vpci/%.h + sed -e '/#include/d' <$< >$@ =20 -list.h: $(XEN_ROOT)/xen/include/xen/list.h -vpci.h: $(XEN_ROOT)/xen/include/xen/vpci.h -list.h vpci.h: +list.h vpci.h: %.h: $(XEN_ROOT)/xen/include/xen/%.h sed -e '/#include/d' <$< >$@ --- a/tools/tests/vpci/emul.h +++ b/tools/tests/vpci/emul.h @@ -86,6 +86,7 @@ typedef union { =20 #define CONFIG_HAS_VPCI #include "vpci.h" +#include "private.h" =20 #define __hwdom_init =20 --- a/xen/arch/arm/include/asm/pci.h +++ b/xen/arch/arm/include/asm/pci.h @@ -31,14 +31,6 @@ struct arch_pci_dev { struct device dev; }; =20 -/* Arch-specific MSI data for vPCI. */ -struct vpci_arch_msi { -}; - -/* Arch-specific MSI-X entry data for vPCI. */ -struct vpci_arch_msix_entry { -}; - /* * Because of the header cross-dependencies, e.g. we need both * struct pci_dev and struct arch_pci_dev at the same time, this cannot be --- /dev/null +++ b/xen/arch/arm/include/asm/vpci.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef ARM_VPCI_H +#define ARM_VPCI_H + +/* Arch-specific MSI data for vPCI. */ +struct vpci_arch_msi { +}; + +/* Arch-specific MSI-X entry data for vPCI. */ +struct vpci_arch_msix_entry { +}; + +#endif /* ARM_VPCI_H */ --- a/xen/arch/x86/include/asm/hvm/io.h +++ b/xen/arch/x86/include/asm/hvm/io.h @@ -97,17 +97,6 @@ void msixtbl_init(struct domain *d); static inline void msixtbl_init(struct domain *d) {} #endif =20 -/* Arch-specific MSI data for vPCI. */ -struct vpci_arch_msi { - int pirq; - bool bound; -}; - -/* Arch-specific MSI-X entry data for vPCI. */ -struct vpci_arch_msix_entry { - int pirq; -}; - void stdvga_init(struct domain *d); =20 extern void hvm_dpci_msi_eoi(struct domain *d, int vector); --- /dev/null +++ b/xen/arch/x86/include/asm/vpci.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef X86_VPCI_H +#define X86_VPCI_H + +#include + +/* Arch-specific MSI data for vPCI. */ +struct vpci_arch_msi { + int pirq; + bool bound; +}; + +/* Arch-specific MSI-X entry data for vPCI. */ +struct vpci_arch_msix_entry { + int pirq; +}; + +#endif /* X86_VPCI_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -17,11 +17,12 @@ * License along with this program; If not, see . */ =20 +#include "private.h" + #include #include #include #include -#include =20 #include =20 --- a/xen/drivers/vpci/msi.c +++ b/xen/drivers/vpci/msi.c @@ -16,9 +16,10 @@ * License along with this program; If not, see . */ =20 +#include "private.h" + #include #include -#include =20 #include =20 --- a/xen/drivers/vpci/msix.c +++ b/xen/drivers/vpci/msix.c @@ -17,10 +17,11 @@ * License along with this program; If not, see . */ =20 +#include "private.h" + #include #include #include -#include =20 #include #include --- /dev/null +++ b/xen/drivers/vpci/private.h @@ -0,0 +1,124 @@ +#ifndef VPCI_PRIVATE_H +#define VPCI_PRIVATE_H + +#include + +typedef uint32_t vpci_read_t(const struct pci_dev *pdev, unsigned int reg, + void *data); + +typedef void vpci_write_t(const struct pci_dev *pdev, unsigned int reg, + uint32_t val, void *data); + +typedef struct { + unsigned int id; + bool is_ext; + int (* init)(struct pci_dev *pdev); + int (* cleanup)(const struct pci_dev *pdev, bool hide); +} vpci_capability_t; + +#define REGISTER_VPCI_CAPABILITY(cap, name, finit, fclean, ext) \ + static const vpci_capability_t name##_entry \ + __used_section(".data.rel.ro.vpci") =3D { \ + .id =3D (cap), \ + .init =3D (finit), \ + .cleanup =3D (fclean), \ + .is_ext =3D (ext), \ + } + +#define REGISTER_VPCI_CAP(name, finit, fclean) \ + REGISTER_VPCI_CAPABILITY(PCI_CAP_ID_##name, name, finit, fclean, false) +#define REGISTER_VPCI_EXTCAP(name, finit, fclean) \ + REGISTER_VPCI_CAPABILITY(PCI_EXT_CAP_ID_##name, name, finit, fclean, t= rue) + +/* Add/remove a register handler. */ +int __must_check vpci_add_register_mask(struct vpci *vpci, + vpci_read_t *read_handler, + vpci_write_t *write_handler, + unsigned int offset, unsigned int = size, + void *data, uint32_t ro_mask, + uint32_t rw1c_mask, uint32_t rsvdp= _mask, + uint32_t rsvdz_mask); +int __must_check vpci_add_register(struct vpci *vpci, + vpci_read_t *read_handler, + vpci_write_t *write_handler, + unsigned int offset, unsigned int size, + void *data); + +int vpci_remove_registers(struct vpci *vpci, unsigned int start, + unsigned int size); + +/* Helper to return the value passed in data. */ +uint32_t cf_check vpci_read_val( + const struct pci_dev *pdev, unsigned int reg, void *data); + +/* Passthrough handlers. */ +uint32_t cf_check vpci_hw_read8( + const struct pci_dev *pdev, unsigned int reg, void *data); +uint32_t cf_check vpci_hw_read16( + const struct pci_dev *pdev, unsigned int reg, void *data); +uint32_t cf_check vpci_hw_read32( + const struct pci_dev *pdev, unsigned int reg, void *data); +void cf_check vpci_hw_write8( + const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data= ); +void cf_check vpci_hw_write16( + const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data= ); + +#ifdef __XEN__ +/* Make sure there's a hole in the p2m for the MSIX mmio areas. */ +int vpci_make_msix_hole(const struct pci_dev *pdev); + +/* + * Helper functions to fetch MSIX related data. They are used by both the + * emulated MSIX code and the BAR handlers. + */ +static inline paddr_t vmsix_table_host_base(const struct vpci *vpci, + unsigned int nr) +{ + return vpci->header.bars[vpci->msix->tables[nr] & PCI_MSIX_BIRMASK].ad= dr; +} + +static inline paddr_t vmsix_table_host_addr(const struct vpci *vpci, + unsigned int nr) +{ + return vmsix_table_host_base(vpci, nr) + + (vpci->msix->tables[nr] & ~PCI_MSIX_BIRMASK); +} + +static inline paddr_t vmsix_table_base(const struct vpci *vpci, unsigned i= nt nr) +{ + return vpci->header.bars[vpci->msix->tables[nr] & + PCI_MSIX_BIRMASK].guest_addr; +} + +static inline paddr_t vmsix_table_addr(const struct vpci *vpci, unsigned i= nt nr) +{ + return vmsix_table_base(vpci, nr) + + (vpci->msix->tables[nr] & ~PCI_MSIX_BIRMASK); +} + +/* + * Note regarding the size calculation of the PBA: the spec mentions "The = last + * QWORD will not necessarily be fully populated", so it implies that the = PBA + * size is 64-bit aligned. + */ +static inline size_t vmsix_table_size(const struct vpci *vpci, unsigned in= t nr) +{ + return + (nr =3D=3D VPCI_MSIX_TABLE) ? vpci->msix->max_entries * PCI_MSIX_E= NTRY_SIZE + : ROUNDUP(DIV_ROUND_UP(vpci->msix->max_ent= ries, + 8), 8); +} + +#endif /* __XEN__ */ + +#endif /* VPCI_PRIVATE_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ --- a/xen/drivers/vpci/rebar.c +++ b/xen/drivers/vpci/rebar.c @@ -5,8 +5,9 @@ * Author: Jiqian Chen */ =20 +#include "private.h" + #include -#include =20 static void cf_check rebar_ctrl_write(const struct pci_dev *pdev, unsigned int reg, --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -17,8 +17,9 @@ * License along with this program; If not, see . */ =20 +#include "private.h" + #include -#include #include =20 /* Internal struct to store the emulated PCI registers. */ --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -7,18 +7,7 @@ #include #include =20 -typedef uint32_t vpci_read_t(const struct pci_dev *pdev, unsigned int reg, - void *data); - -typedef void vpci_write_t(const struct pci_dev *pdev, unsigned int reg, - uint32_t val, void *data); - -typedef struct { - unsigned int id; - bool is_ext; - int (* init)(struct pci_dev *pdev); - int (* cleanup)(const struct pci_dev *pdev, bool hide); -} vpci_capability_t; +#include =20 #define VPCI_ECAM_BDF(addr) (((addr) & 0x0ffff000) >> 12) =20 @@ -30,20 +19,6 @@ typedef struct { */ #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1) =20 -#define REGISTER_VPCI_CAPABILITY(cap, name, finit, fclean, ext) \ - static const vpci_capability_t name##_entry \ - __used_section(".data.rel.ro.vpci") =3D { \ - .id =3D (cap), \ - .init =3D (finit), \ - .cleanup =3D (fclean), \ - .is_ext =3D (ext), \ - } - -#define REGISTER_VPCI_CAP(name, finit, fclean) \ - REGISTER_VPCI_CAPABILITY(PCI_CAP_ID_##name, name, finit, fclean, false) -#define REGISTER_VPCI_EXTCAP(name, finit, fclean) \ - REGISTER_VPCI_CAPABILITY(PCI_EXT_CAP_ID_##name, name, finit, fclean, t= rue) - int __must_check vpci_init_header(struct pci_dev *pdev); =20 /* Assign vPCI to device by adding handlers. */ @@ -52,44 +27,11 @@ int __must_check vpci_assign_device(stru /* Remove all handlers and free vpci related structures. */ void vpci_deassign_device(struct pci_dev *pdev); =20 -/* Add/remove a register handler. */ -int __must_check vpci_add_register_mask(struct vpci *vpci, - vpci_read_t *read_handler, - vpci_write_t *write_handler, - unsigned int offset, unsigned int = size, - void *data, uint32_t ro_mask, - uint32_t rw1c_mask, uint32_t rsvdp= _mask, - uint32_t rsvdz_mask); -int __must_check vpci_add_register(struct vpci *vpci, - vpci_read_t *read_handler, - vpci_write_t *write_handler, - unsigned int offset, unsigned int size, - void *data); - -int vpci_remove_registers(struct vpci *vpci, unsigned int start, - unsigned int size); - /* Generic read/write handlers for the PCI config space. */ uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size); void vpci_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size, uint32_t data); =20 -/* Helper to return the value passed in data. */ -uint32_t cf_check vpci_read_val( - const struct pci_dev *pdev, unsigned int reg, void *data); - -/* Passthrough handlers. */ -uint32_t cf_check vpci_hw_read8( - const struct pci_dev *pdev, unsigned int reg, void *data); -uint32_t cf_check vpci_hw_read16( - const struct pci_dev *pdev, unsigned int reg, void *data); -uint32_t cf_check vpci_hw_read32( - const struct pci_dev *pdev, unsigned int reg, void *data); -void cf_check vpci_hw_write8( - const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data= ); -void cf_check vpci_hw_write16( - const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data= ); - /* * Check for pending vPCI operations on this vcpu. Returns true if the vcpu * should not run. @@ -213,9 +155,6 @@ struct vpci_vcpu { #ifdef __XEN__ void vpci_dump_msi(void); =20 -/* Make sure there's a hole in the p2m for the MSIX mmio areas. */ -int vpci_make_msix_hole(const struct pci_dev *pdev); - /* Arch-specific vPCI MSI helpers. */ void vpci_msi_arch_mask(struct vpci_msi *msi, const struct pci_dev *pdev, unsigned int entry, bool mask); @@ -238,48 +177,6 @@ int __must_check vpci_msix_arch_disable_ void vpci_msix_arch_init_entry(struct vpci_msix_entry *entry); int vpci_msix_arch_print(const struct vpci_msix *msix); =20 -/* - * Helper functions to fetch MSIX related data. They are used by both the - * emulated MSIX code and the BAR handlers. - */ -static inline paddr_t vmsix_table_host_base(const struct vpci *vpci, - unsigned int nr) -{ - return vpci->header.bars[vpci->msix->tables[nr] & PCI_MSIX_BIRMASK].ad= dr; -} - -static inline paddr_t vmsix_table_host_addr(const struct vpci *vpci, - unsigned int nr) -{ - return vmsix_table_host_base(vpci, nr) + - (vpci->msix->tables[nr] & ~PCI_MSIX_BIRMASK); -} - -static inline paddr_t vmsix_table_base(const struct vpci *vpci, unsigned i= nt nr) -{ - return vpci->header.bars[vpci->msix->tables[nr] & - PCI_MSIX_BIRMASK].guest_addr; -} - -static inline paddr_t vmsix_table_addr(const struct vpci *vpci, unsigned i= nt nr) -{ - return vmsix_table_base(vpci, nr) + - (vpci->msix->tables[nr] & ~PCI_MSIX_BIRMASK); -} - -/* - * Note regarding the size calculation of the PBA: the spec mentions "The = last - * QWORD will not necessarily be fully populated", so it implies that the = PBA - * size is 64-bit aligned. - */ -static inline size_t vmsix_table_size(const struct vpci *vpci, unsigned in= t nr) -{ - return - (nr =3D=3D VPCI_MSIX_TABLE) ? vpci->msix->max_entries * PCI_MSIX_E= NTRY_SIZE - : ROUNDUP(DIV_ROUND_UP(vpci->msix->max_ent= ries, - 8), 8); -} - static inline unsigned int vmsix_entry_nr(const struct vpci_msix *msix, const struct vpci_msix_entry *en= try) { From nobody Wed Feb 11 10:35:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1770720880; cv=none; d=zohomail.com; s=zohoarc; b=NFDLqHuMmhuo2UYqN4pJzfbVm5+kTB2lwASgaiZ+1uwbiUFHdcVSpI9SPFYbCNaPf4ycuj6bKpSXgW+owufGEc1401BkP6hhf02mLt2F0a502pnRbAS5m2oScqyMNoKVS2m3VRZeCFfGTyxFCL2YlK/lhwjG/Xo0LUuuljvE8vo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770720880; 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=j/dEX2kKzzmAnt1Zegeuwsix6l/RE3FSLEbF5w2fmL0=; b=j7Qt8lssh+BHiQPO4di8aNvBjhWqeiNiRl7fjP1qf3D+gdaJSrOZMpT+VkUm/yJQVO5qZ9LAUBx5MHxyUt1bpvn7Jihy/tMYKXzNe2CJACUcqAq1WXkIpOLTDuiIXDvXRzn+MmUXzvRzg15UF/9gWtGXCsasOKZsatEKDnakZCw= 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=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770720880498515.5889568367124; Tue, 10 Feb 2026 02:54:40 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1226249.1532786 (Exim 4.92) (envelope-from ) id 1vplNv-0005mc-TV; Tue, 10 Feb 2026 10:54:23 +0000 Received: by outflank-mailman (output) from mailman id 1226249.1532786; Tue, 10 Feb 2026 10:54:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vplNv-0005mV-QV; Tue, 10 Feb 2026 10:54:23 +0000 Received: by outflank-mailman (input) for mailman id 1226249; Tue, 10 Feb 2026 10:54:21 +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 1vplNt-0004jf-Kd for xen-devel@lists.xenproject.org; Tue, 10 Feb 2026 10:54:21 +0000 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [2a00:1450:4864:20::336]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id da7965a1-066e-11f1-b162-2bf370ae4941; Tue, 10 Feb 2026 11:54:20 +0100 (CET) Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-4801eb2c0a5so51890865e9.3 for ; Tue, 10 Feb 2026 02:54:20 -0800 (PST) Received: from [10.156.60.236] (ip-037-024-206-209.um08.pools.vodafone-ip.de. [37.24.206.209]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4832096c438sm197308905e9.3.2026.02.10.02.54.19 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Feb 2026 02:54:19 -0800 (PST) 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: da7965a1-066e-11f1-b162-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1770720860; x=1771325660; darn=lists.xenproject.org; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=j/dEX2kKzzmAnt1Zegeuwsix6l/RE3FSLEbF5w2fmL0=; b=GH1gfZAP6BIdiBmwRzePRkLmuMuCXtsTmnsZsT1pxgxKBrhqoJ1QShilf1K/CQb50R nAPOADpjC1138amQR5T1vYHsUxBxOG48orp+AxcdyG+XPjVxfK207qEkGyV1G9RTFC5m 6QJrgZ7DjPrq7UMBLlFEbdDnNqAZbcVqVAPM4uNXlh8128Tzs1F3SjTVdyuhT+c1ksDA aPSMwzqAKIK+C02iRNoUoE+l+pwCld2hdjVgb3i+JCcPaoFk9Rttd7645dOTYl4S8AeV BMU1kxpep7GKWmShyBHa8rsnEPWTb9X6Dkkng7PqSPYo5CUHEXIzkSVRDTQdzlJ7puXX ZSHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770720860; x=1771325660; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=j/dEX2kKzzmAnt1Zegeuwsix6l/RE3FSLEbF5w2fmL0=; b=Td9Cf8Gve6O8QCShTaJiIhER5ERgdSO3/RjiA8d3Q8ZjwstiB78zmLKy0xNMbqKseG 4F2iySOltQfFjfsDM82NqSbYmTVQ4ai2QzRA40r3hbjN5qAnODwdIM8AQFgu+bCaPfth UQkXpNrliuHM+T+kmzcYiqg5NQrcVk5nEH6VWosCsel5sGhMoMWAf3sRtEDt4STe7KtH uXKMVBm2hQbGpZg2AC/a+Xves0OALAMLi1g8Ab77u1L/MF7YrVyqcAzJwHkQVcqCCJOe KhzOPKTw67h2U9wvyd7UOFx6+klYnJIuguvnxLfCPivqyKoApT+8AGzhEcqgV9brtbGl pvzA== X-Gm-Message-State: AOJu0YwqIZsyvYBpfNdYACgmzRHn+uq3jgTWYcQds8PByqUSGvu25pf3 Tg5HXjxa0dW4UzUuynekO+tasgTm4jr0d33wQSU6cJLQBk4wGTG5+gQgZUH6melhbfYCYROsyM/ dBjI= X-Gm-Gg: AZuq6aL6bkm5OQ9KebhLwzmNPSpXGokPha6dCoOPKRNJJn9uTpxJShZAkDu/KuTHPE5 OQ/KvkjsowQvHxJzRLz7Qc8iymiT+aGAuqb4cihkeJl8TSJXsphnjoaDEolf9w/wQP6YzVHzwcX OOlttMcLE5r/S47X+jMnen8qJ+8YbatyUhw8NQ+p0hsK2M10D4hc+EfopwA/WxoCzKRxJzZe6sP gYR4WuVL1JRILWFpZ7ct1GjCngKaodRhIDMHM5Iwx0DtI9F5LmWUkWKf9wxB0jWnDMSzAnDYcdD UxyyaO37PgWvHuZEHaFDE2BD+KbkJyn/Xp3K5w+NwhMck5QI9LZ343f9yYaTvKX8JDoW9wpRDJG 5JpzU807HZJ8DG5ShPynEXNNElaMm5EWDUFJsTTgcd4cSe87dA5uwmbGFRixtjQlEEmJE0j9mDu 5VVYpf9lB07qmMCXLLpocjCdGElf4pkWkpDmndOrIRdhqm22EMoRWzaKoEzieO9azewxS0qotVv EUaI+NVWt4vXLg= X-Received: by 2002:a05:600c:4e8b:b0:477:7bca:8b2b with SMTP id 5b1f17b1804b1-483507f2bb3mr22749045e9.15.1770720859895; Tue, 10 Feb 2026 02:54:19 -0800 (PST) Message-ID: Date: Tue, 10 Feb 2026 11:54:18 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v4 3/5] vPCI: move vpci_init_capabilities() to a separate file From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand References: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Language: en-US Autocrypt: addr=jbeulich@suse.com; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL In-Reply-To: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1770720882056154100 Content-Type: text/plain; charset="utf-8" Let's keep capability handling together. Start with moving vpci_init_capabilities() and its helpers, plus splitting out of its cleanup counterpart. Signed-off-by: Jan Beulich --- vpci_get_register(), while now only used by cap.c, didn't look like it would want moving there. --- v4: New. --- a/xen/drivers/vpci/Makefile +++ b/xen/drivers/vpci/Makefile @@ -1,2 +1,3 @@ +obj-y +=3D cap.o obj-y +=3D vpci.o header.o rebar.o obj-$(CONFIG_HAS_PCI_MSI) +=3D msi.o msix.o --- /dev/null +++ b/xen/drivers/vpci/cap.c @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Capability handling for guest PCI configuration space. + */ + +#include "private.h" + +#include + +extern const vpci_capability_t __start_vpci_array[]; +extern const vpci_capability_t __end_vpci_array[]; +#define NUM_VPCI_INIT (__end_vpci_array - __start_vpci_array) + +static struct vpci_register *vpci_get_previous_cap_register( + const struct vpci *vpci, unsigned int offset) +{ + unsigned int next; + struct vpci_register *r; + + if ( offset < 0x40 ) + { + ASSERT_UNREACHABLE(); + return NULL; + } + + for ( r =3D vpci_get_register(vpci, PCI_CAPABILITY_LIST, 1); r; + r =3D next >=3D 0x40 ? vpci_get_register(vpci, + next + PCI_CAP_LIST_NEXT, 1) + : NULL ) + { + next =3D (unsigned int)(uintptr_t)r->private; + ASSERT(next =3D=3D (uintptr_t)r->private); + if ( next =3D=3D offset ) + break; + } + + return r; +} + +static int vpci_capability_hide(const struct pci_dev *pdev, unsigned int c= ap) +{ + const unsigned int offset =3D pci_find_cap_offset(pdev->sbdf, cap); + struct vpci_register *prev_r, *next_r; + struct vpci *vpci =3D pdev->vpci; + + if ( !offset ) + { + ASSERT_UNREACHABLE(); + return 0; + } + + spin_lock(&vpci->lock); + prev_r =3D vpci_get_previous_cap_register(vpci, offset); + next_r =3D vpci_get_register(vpci, offset + PCI_CAP_LIST_NEXT, 1); + if ( !prev_r || !next_r ) + { + spin_unlock(&vpci->lock); + return -ENODEV; + } + + prev_r->private =3D next_r->private; + /* + * Not calling vpci_remove_registers() here is to avoid redoing + * the register search. + */ + list_del(&next_r->node); + spin_unlock(&vpci->lock); + xfree(next_r); + + if ( !is_hardware_domain(pdev->domain) ) + return vpci_remove_registers(vpci, offset + PCI_CAP_LIST_ID, 1); + + return 0; +} + +static struct vpci_register *vpci_get_previous_ext_cap_register( + const struct vpci *vpci, unsigned int offset) +{ + unsigned int pos =3D PCI_CFG_SPACE_SIZE; + struct vpci_register *r; + + if ( offset <=3D PCI_CFG_SPACE_SIZE ) + { + ASSERT_UNREACHABLE(); + return NULL; + } + + for ( r =3D vpci_get_register(vpci, pos, 4); r; + r =3D pos > PCI_CFG_SPACE_SIZE ? vpci_get_register(vpci, pos, 4) + : NULL ) + { + uint32_t header =3D (uint32_t)(uintptr_t)r->private; + + ASSERT(header =3D=3D (uintptr_t)r->private); + + pos =3D PCI_EXT_CAP_NEXT(header); + if ( pos =3D=3D offset ) + break; + } + + return r; +} + +static int vpci_ext_capability_hide( + const struct pci_dev *pdev, unsigned int cap) +{ + const unsigned int offset =3D pci_find_ext_capability(pdev, cap); + struct vpci_register *r, *prev_r; + struct vpci *vpci =3D pdev->vpci; + uint32_t header, pre_header; + + if ( offset < PCI_CFG_SPACE_SIZE ) + { + ASSERT_UNREACHABLE(); + return 0; + } + + spin_lock(&vpci->lock); + r =3D vpci_get_register(vpci, offset, 4); + if ( !r ) + { + spin_unlock(&vpci->lock); + return -ENODEV; + } + + header =3D (uint32_t)(uintptr_t)r->private; + if ( offset =3D=3D PCI_CFG_SPACE_SIZE ) + { + if ( PCI_EXT_CAP_NEXT(header) <=3D PCI_CFG_SPACE_SIZE ) + r->private =3D (void *)0; + else + /* + * The first extended capability (0x100) can not be removed fr= om + * the linked list, so instead mask its capability ID to retur= n 0 + * hopefully forcing OSes to skip it. + */ + r->private =3D (void *)(uintptr_t)(header & ~PCI_EXT_CAP_ID(he= ader)); + + spin_unlock(&vpci->lock); + return 0; + } + + prev_r =3D vpci_get_previous_ext_cap_register(vpci, offset); + if ( !prev_r ) + { + spin_unlock(&vpci->lock); + return -ENODEV; + } + + pre_header =3D (uint32_t)(uintptr_t)prev_r->private; + pre_header &=3D ~PCI_EXT_CAP_NEXT_MASK; + pre_header |=3D header & PCI_EXT_CAP_NEXT_MASK; + prev_r->private =3D (void *)(uintptr_t)pre_header; + + list_del(&r->node); + spin_unlock(&vpci->lock); + xfree(r); + + return 0; +} + +int vpci_init_capabilities(struct pci_dev *pdev) +{ + for ( unsigned int i =3D 0; i < NUM_VPCI_INIT; i++ ) + { + const vpci_capability_t *capability =3D &__start_vpci_array[i]; + const unsigned int cap =3D capability->id; + const bool is_ext =3D capability->is_ext; + unsigned int pos =3D 0; + int rc; + + if ( !is_ext ) + pos =3D pci_find_cap_offset(pdev->sbdf, cap); + else if ( is_hardware_domain(pdev->domain) ) + pos =3D pci_find_ext_capability(pdev, cap); + + if ( !pos ) + continue; + + rc =3D capability->init(pdev); + if ( rc ) + { + const char *type =3D is_ext ? "extended" : "legacy"; + + printk(XENLOG_WARNING + "%pd %pp: init %s cap %u fail rc=3D%d, mask it\n", + pdev->domain, &pdev->sbdf, type, cap, rc); + + if ( capability->cleanup ) + { + rc =3D capability->cleanup(pdev, true); + if ( rc ) + { + printk(XENLOG_ERR "%pd %pp: clean %s cap %u fail rc=3D= %d\n", + pdev->domain, &pdev->sbdf, type, cap, rc); + if ( !is_hardware_domain(pdev->domain) ) + return rc; + } + } + + if ( !is_ext ) + rc =3D vpci_capability_hide(pdev, cap); + else + rc =3D vpci_ext_capability_hide(pdev, cap); + if ( rc ) + { + printk(XENLOG_ERR "%pd %pp: hide %s cap %u fail rc=3D%d\n", + pdev->domain, &pdev->sbdf, type, cap, rc); + return rc; + } + } + } + + return 0; +} + +void vpci_cleanup_capabilities(struct pci_dev *pdev) +{ + for ( unsigned int i =3D 0; i < NUM_VPCI_INIT; i++ ) + { + const vpci_capability_t *capability =3D &__start_vpci_array[i]; + const unsigned int cap =3D capability->id; + unsigned int pos =3D 0; + + if ( !capability->cleanup ) + continue; + + if ( !capability->is_ext ) + pos =3D pci_find_cap_offset(pdev->sbdf, cap); + else if ( is_hardware_domain(pdev->domain) ) + pos =3D pci_find_ext_capability(pdev, cap); + if ( pos ) + { + int rc =3D capability->cleanup(pdev, false); + + if ( rc ) + printk(XENLOG_ERR "%pd %pp: clean %s cap %u fail rc=3D%d\n= ", + pdev->domain, &pdev->sbdf, + capability->is_ext ? "extended" : "legacy", cap, rc= ); + } + } +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ --- a/xen/drivers/vpci/private.h +++ b/xen/drivers/vpci/private.h @@ -9,6 +9,20 @@ typedef uint32_t vpci_read_t(const struc typedef void vpci_write_t(const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data); =20 +/* Internal struct to store the emulated PCI registers. */ +struct vpci_register { + vpci_read_t *read; + vpci_write_t *write; + unsigned int size; + unsigned int offset; + void *private; + struct list_head node; + uint32_t ro_mask; + uint32_t rw1c_mask; + uint32_t rsvdp_mask; + uint32_t rsvdz_mask; +}; + typedef struct { unsigned int id; bool is_ext; @@ -30,6 +44,9 @@ typedef struct { #define REGISTER_VPCI_EXTCAP(name, finit, fclean) \ REGISTER_VPCI_CAPABILITY(PCI_EXT_CAP_ID_##name, name, finit, fclean, t= rue) =20 +int vpci_init_capabilities(struct pci_dev *pdev); +void vpci_cleanup_capabilities(struct pci_dev *pdev); + /* Add/remove a register handler. */ int __must_check vpci_add_register_mask(struct vpci *vpci, vpci_read_t *read_handler, @@ -47,6 +64,10 @@ int __must_check vpci_add_register(struc int vpci_remove_registers(struct vpci *vpci, unsigned int start, unsigned int size); =20 +struct vpci_register *vpci_get_register(const struct vpci *vpci, + unsigned int offset, + unsigned int size); + /* Helper to return the value passed in data. */ uint32_t cf_check vpci_read_val( const struct pci_dev *pdev, unsigned int reg, void *data); --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -22,24 +22,7 @@ #include #include =20 -/* Internal struct to store the emulated PCI registers. */ -struct vpci_register { - vpci_read_t *read; - vpci_write_t *write; - unsigned int size; - unsigned int offset; - void *private; - struct list_head node; - uint32_t ro_mask; - uint32_t rw1c_mask; - uint32_t rsvdp_mask; - uint32_t rsvdz_mask; -}; - #ifdef __XEN__ -extern const vpci_capability_t __start_vpci_array[]; -extern const vpci_capability_t __end_vpci_array[]; -#define NUM_VPCI_INIT (__end_vpci_array - __start_vpci_array) =20 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT static int assign_virtual_sbdf(struct pci_dev *pdev) @@ -84,9 +67,9 @@ static int assign_virtual_sbdf(struct pc =20 #endif /* CONFIG_HAS_VPCI_GUEST_SUPPORT */ =20 -static struct vpci_register *vpci_get_register(const struct vpci *vpci, - unsigned int offset, - unsigned int size) +struct vpci_register *vpci_get_register(const struct vpci *vpci, + unsigned int offset, + unsigned int size) { struct vpci_register *r; =20 @@ -104,209 +87,6 @@ static struct vpci_register *vpci_get_re return NULL; } =20 -static struct vpci_register *vpci_get_previous_cap_register( - const struct vpci *vpci, unsigned int offset) -{ - unsigned int next; - struct vpci_register *r; - - if ( offset < 0x40 ) - { - ASSERT_UNREACHABLE(); - return NULL; - } - - for ( r =3D vpci_get_register(vpci, PCI_CAPABILITY_LIST, 1); r; - r =3D next >=3D 0x40 ? vpci_get_register(vpci, - next + PCI_CAP_LIST_NEXT, 1) - : NULL ) - { - next =3D (unsigned int)(uintptr_t)r->private; - ASSERT(next =3D=3D (uintptr_t)r->private); - if ( next =3D=3D offset ) - break; - } - - return r; -} - -static int vpci_capability_hide(const struct pci_dev *pdev, unsigned int c= ap) -{ - const unsigned int offset =3D pci_find_cap_offset(pdev->sbdf, cap); - struct vpci_register *prev_r, *next_r; - struct vpci *vpci =3D pdev->vpci; - - if ( !offset ) - { - ASSERT_UNREACHABLE(); - return 0; - } - - spin_lock(&vpci->lock); - prev_r =3D vpci_get_previous_cap_register(vpci, offset); - next_r =3D vpci_get_register(vpci, offset + PCI_CAP_LIST_NEXT, 1); - if ( !prev_r || !next_r ) - { - spin_unlock(&vpci->lock); - return -ENODEV; - } - - prev_r->private =3D next_r->private; - /* - * Not calling vpci_remove_registers() here is to avoid redoing - * the register search. - */ - list_del(&next_r->node); - spin_unlock(&vpci->lock); - xfree(next_r); - - if ( !is_hardware_domain(pdev->domain) ) - return vpci_remove_registers(vpci, offset + PCI_CAP_LIST_ID, 1); - - return 0; -} - -static struct vpci_register *vpci_get_previous_ext_cap_register( - const struct vpci *vpci, unsigned int offset) -{ - unsigned int pos =3D PCI_CFG_SPACE_SIZE; - struct vpci_register *r; - - if ( offset <=3D PCI_CFG_SPACE_SIZE ) - { - ASSERT_UNREACHABLE(); - return NULL; - } - - for ( r =3D vpci_get_register(vpci, pos, 4); r; - r =3D pos > PCI_CFG_SPACE_SIZE ? vpci_get_register(vpci, pos, 4) - : NULL ) - { - uint32_t header =3D (uint32_t)(uintptr_t)r->private; - - ASSERT(header =3D=3D (uintptr_t)r->private); - - pos =3D PCI_EXT_CAP_NEXT(header); - if ( pos =3D=3D offset ) - break; - } - - return r; -} - -static int vpci_ext_capability_hide( - const struct pci_dev *pdev, unsigned int cap) -{ - const unsigned int offset =3D pci_find_ext_capability(pdev, cap); - struct vpci_register *r, *prev_r; - struct vpci *vpci =3D pdev->vpci; - uint32_t header, pre_header; - - if ( offset < PCI_CFG_SPACE_SIZE ) - { - ASSERT_UNREACHABLE(); - return 0; - } - - spin_lock(&vpci->lock); - r =3D vpci_get_register(vpci, offset, 4); - if ( !r ) - { - spin_unlock(&vpci->lock); - return -ENODEV; - } - - header =3D (uint32_t)(uintptr_t)r->private; - if ( offset =3D=3D PCI_CFG_SPACE_SIZE ) - { - if ( PCI_EXT_CAP_NEXT(header) <=3D PCI_CFG_SPACE_SIZE ) - r->private =3D (void *)0; - else - /* - * The first extended capability (0x100) can not be removed fr= om - * the linked list, so instead mask its capability ID to retur= n 0 - * hopefully forcing OSes to skip it. - */ - r->private =3D (void *)(uintptr_t)(header & ~PCI_EXT_CAP_ID(he= ader)); - - spin_unlock(&vpci->lock); - return 0; - } - - prev_r =3D vpci_get_previous_ext_cap_register(vpci, offset); - if ( !prev_r ) - { - spin_unlock(&vpci->lock); - return -ENODEV; - } - - pre_header =3D (uint32_t)(uintptr_t)prev_r->private; - pre_header &=3D ~PCI_EXT_CAP_NEXT_MASK; - pre_header |=3D header & PCI_EXT_CAP_NEXT_MASK; - prev_r->private =3D (void *)(uintptr_t)pre_header; - - list_del(&r->node); - spin_unlock(&vpci->lock); - xfree(r); - - return 0; -} - -static int vpci_init_capabilities(struct pci_dev *pdev) -{ - for ( unsigned int i =3D 0; i < NUM_VPCI_INIT; i++ ) - { - const vpci_capability_t *capability =3D &__start_vpci_array[i]; - const unsigned int cap =3D capability->id; - const bool is_ext =3D capability->is_ext; - unsigned int pos =3D 0; - int rc; - - if ( !is_ext ) - pos =3D pci_find_cap_offset(pdev->sbdf, cap); - else if ( is_hardware_domain(pdev->domain) ) - pos =3D pci_find_ext_capability(pdev, cap); - - if ( !pos ) - continue; - - rc =3D capability->init(pdev); - if ( rc ) - { - const char *type =3D is_ext ? "extended" : "legacy"; - - printk(XENLOG_WARNING - "%pd %pp: init %s cap %u fail rc=3D%d, mask it\n", - pdev->domain, &pdev->sbdf, type, cap, rc); - - if ( capability->cleanup ) - { - rc =3D capability->cleanup(pdev, true); - if ( rc ) - { - printk(XENLOG_ERR "%pd %pp: clean %s cap %u fail rc=3D= %d\n", - pdev->domain, &pdev->sbdf, type, cap, rc); - if ( !is_hardware_domain(pdev->domain) ) - return rc; - } - } - - if ( !is_ext ) - rc =3D vpci_capability_hide(pdev, cap); - else - rc =3D vpci_ext_capability_hide(pdev, cap); - if ( rc ) - { - printk(XENLOG_ERR "%pd %pp: hide %s cap %u fail rc=3D%d\n", - pdev->domain, &pdev->sbdf, type, cap, rc); - return rc; - } - } - } - - return 0; -} - void vpci_deassign_device(struct pci_dev *pdev) { unsigned int i; @@ -322,29 +102,7 @@ void vpci_deassign_device(struct pci_dev &pdev->domain->vpci_dev_assigned_map); #endif =20 - for ( i =3D 0; i < NUM_VPCI_INIT; i++ ) - { - const vpci_capability_t *capability =3D &__start_vpci_array[i]; - const unsigned int cap =3D capability->id; - unsigned int pos =3D 0; - - if ( !capability->cleanup ) - continue; - - if ( !capability->is_ext ) - pos =3D pci_find_cap_offset(pdev->sbdf, cap); - else if ( is_hardware_domain(pdev->domain) ) - pos =3D pci_find_ext_capability(pdev, cap); - if ( pos ) - { - int rc =3D capability->cleanup(pdev, false); - - if ( rc ) - printk(XENLOG_ERR "%pd %pp: clean %s cap %u fail rc=3D%d\n= ", - pdev->domain, &pdev->sbdf, - capability->is_ext ? "extended" : "legacy", cap, rc= ); - } - } + vpci_cleanup_capabilities(pdev); =20 spin_lock(&pdev->vpci->lock); while ( !list_empty(&pdev->vpci->handlers) ) From nobody Wed Feb 11 10:35:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1770720910; cv=none; d=zohomail.com; s=zohoarc; b=GzjoJ3v0is6ZNIRGP5LKYLx2zOjxgoSPwDiszrdmT7V8R3uFgPjJjRUbvh5U273/PsnomzDMSXwc/InIVBhPvq43G3pH0lmry7b35XW4E6nSQZAEeEt2KzITXluAhUGNVLUxN2V0mlWDM4EAYzV2JgedUoER+aUdk7fcPjyiAXg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770720910; 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=FOSPNY7vKiGWPUFz/egRdpkAkGRnRZF4cn2NSZ0vM9g=; b=JhjLy1+Ke0PkiYz7U2M9OR0xwZlkHeVLtZ/rOKNo3Ex0yv93XlPMWR44lfyB8fNAljR2GzOpevf1YI8aXYj18rwv4UsX5/qCwBP4cjye2kOfyb6QJH0qfYAq0y3d5I7iU0A4jmxbQVikomiMgaZEyhRl6gZgQzfLBA7oSyzRcj8= 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=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770720910506164.96571780177396; Tue, 10 Feb 2026 02:55:10 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1226256.1532796 (Exim 4.92) (envelope-from ) id 1vplOT-0006Kc-AX; Tue, 10 Feb 2026 10:54:57 +0000 Received: by outflank-mailman (output) from mailman id 1226256.1532796; Tue, 10 Feb 2026 10:54:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vplOT-0006KV-75; Tue, 10 Feb 2026 10:54:57 +0000 Received: by outflank-mailman (input) for mailman id 1226256; Tue, 10 Feb 2026 10:54:56 +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 1vplOS-0004jf-J3 for xen-devel@lists.xenproject.org; Tue, 10 Feb 2026 10:54:56 +0000 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [2a00:1450:4864:20::433]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id ef32cb16-066e-11f1-b162-2bf370ae4941; Tue, 10 Feb 2026 11:54:55 +0100 (CET) Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-43622089851so636762f8f.3 for ; Tue, 10 Feb 2026 02:54:55 -0800 (PST) Received: from [10.156.60.236] (ip-037-024-206-209.um08.pools.vodafone-ip.de. [37.24.206.209]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-436296bd1c9sm32720398f8f.15.2026.02.10.02.54.54 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Feb 2026 02:54:54 -0800 (PST) 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: ef32cb16-066e-11f1-b162-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1770720895; x=1771325695; darn=lists.xenproject.org; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=FOSPNY7vKiGWPUFz/egRdpkAkGRnRZF4cn2NSZ0vM9g=; b=Su7M40oVbHSuUh/NHNx9in/JrTsjvJSkQg7hKFkhf2EEyqaY5OIRPLfkvEe98NSAh2 e3ziVXO6mZSBVlhd2ZNYZXClEW9zl1kUAgod3CUTagBbbDAyzjocWXWYxT2QtZm1fmgA g2VJPdXhaYJlG5hSzy8h10ZNvuUoUyZuU7OwXhTiVm0Hq9XRiwGFtgdboXXzOVFE0ImU CkENHpLfSkESBxF315z69M+CEtYNIELOdTm4r2dB+tdPaoahRecvk8wzUkZMvQAo3PpL EPQ7qCib1bDHkTmdni8Yt/6rH8vEfNJrIm77ShWrl5yrZAwRC3cSzIfQYkxl2JIVCRLY nHfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770720895; x=1771325695; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=FOSPNY7vKiGWPUFz/egRdpkAkGRnRZF4cn2NSZ0vM9g=; b=GqFJN2MSm0qdssUarFJzgw0Y2rCB01PPdrMeFSXHJevFEXZzHaiEG/dOW+IfquhBO+ qfbVSe4fgvux9yFrQk3f09EXGpZGgvPNomy3XuLBFzJWiUCdTDMVlECcdNRHVLJ12sj2 pHJdwKcGs7lAsggys4kTYVrjie7yFPAkfoRA4eCEDeKUh7p4fZmAPELl7uTY8FvB/F3s SZ1y4OpqYIfGU07ghpggkQk4NM1Jt1Dy/mtOexWEVi5Bs4/XwcQ5luOhlqtYhSwxwx7H MeF7x4Q/zO7NJk9MKpm3/krVy4srDArLshEQeqlpjKBBQ5tJPHN6QF7MXTA0Bo/k7aKX 54rw== X-Gm-Message-State: AOJu0YzLmPrXIK7Yvyb1gdw8zIt6LWTH9JMKvsGma6lnrUlk8z73JAN8 PNl7dX9vbk0U1E07ZaWoHaRF4gI7ntrqwRxWnZkL8M7Ydv0xYZcFUWnWrI5GkEESnMkUHl30pEl flZQ= X-Gm-Gg: AZuq6aLwXPjYGMl7R2J1Qox7TTudZOBKEx0tSgaR5U9xm7N7lFypQ88e8DP4DN/5IOt GeQymaVKVrh4QockLsCaxR4CXaIhCBCJXoGvZ7efpSY5RItyGhtDb+kGBHX5fdlY6XSf9m/VTjU Z7T8X74NsOo8ubc6UQIGCK2sP/MlZ6r6eWtVS563JntaAZjKJEilPtVo0jmF05sGI1tC4vU8MPi 6jICzBIBPHicl9g/mhATfsPj6Cwf7y5L9MViXDC1Ja6egQ1kCmoVIa5FiyYr+I8fAFWCofGW3/9 u2LlFo4/eBG1Ii8Gp/1NadDeSJP4mTFqZpK4i8tPzLekF0o4gdk+FABFRx2coDVI04MmTG7r85s I6miV4pnbtwgaWn6RYhvElLOv7KON/DlUZ5GZ71ayxlfNYY57eOZI6s6eF9fApTxgIn/SohqMNV 5tL5ym+Iws4H69BxpqBf/MB9Rf5HOq8pPVo6/IN5MnslU3HItOr7GRXsxBA1fJnzx2I48B0RpR4 bYLIQa5NiyiLaM= X-Received: by 2002:a5d:5f88:0:b0:435:f29d:8c41 with SMTP id ffacd0b85a97d-436293a91aemr23179448f8f.62.1770720894688; Tue, 10 Feb 2026 02:54:54 -0800 (PST) Message-ID: Date: Tue, 10 Feb 2026 11:54:53 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v4 4/5] vPCI: move capability-list init From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand References: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Language: en-US Autocrypt: addr=jbeulich@suse.com; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL In-Reply-To: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1770720912587154100 ... both for when the functions are invoked and where they live in source. Don't invoke them directly in vpci_init_header(), but instead first thing in vpci_init_capabilities(). Suggested-by: Roger Pau Monn=C3=A9 Signed-off-by: Jan Beulich --- v4: New. --- a/xen/drivers/vpci/cap.c +++ b/xen/drivers/vpci/cap.c @@ -159,15 +159,150 @@ static int vpci_ext_capability_hide( return 0; } =20 +static int vpci_init_capability_list(struct pci_dev *pdev) +{ + int rc; + bool mask_cap_list =3D false; + bool is_hwdom =3D is_hardware_domain(pdev->domain); + + if ( pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST ) + { + /* Only expose capabilities to the guest that vPCI can handle. */ + unsigned int next, ttl =3D 48; + static const unsigned int supported_caps[] =3D { + PCI_CAP_ID_MSI, + PCI_CAP_ID_MSIX, + }; + /* + * For dom0, we should expose all capabilities instead of a fixed + * capabilities array, so setting n to 0 here is to get the next + * capability position directly in pci_find_next_cap_ttl. + */ + const unsigned int n =3D is_hwdom ? 0 : ARRAY_SIZE(supported_caps); + + next =3D pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST, + supported_caps, n, &ttl); + + rc =3D vpci_add_register(pdev->vpci, vpci_read_val, + is_hwdom ? vpci_hw_write8 : NULL, + PCI_CAPABILITY_LIST, 1, + (void *)(uintptr_t)next); + if ( rc ) + return rc; + + next &=3D ~3; + + if ( !next && !is_hwdom ) + /* + * If we don't have any supported capabilities to expose to the + * guest, mask the PCI_STATUS_CAP_LIST bit in the status + * register. + */ + mask_cap_list =3D true; + + while ( next && ttl ) + { + unsigned int pos =3D next; + + next =3D pci_find_next_cap_ttl(pdev->sbdf, + pos + PCI_CAP_LIST_NEXT, + supported_caps, n, &ttl); + + if ( !is_hwdom ) + { + rc =3D vpci_add_register(pdev->vpci, vpci_hw_read8, NULL, + pos + PCI_CAP_LIST_ID, 1, NULL); + if ( rc ) + return rc; + } + + rc =3D vpci_add_register(pdev->vpci, vpci_read_val, + is_hwdom ? vpci_hw_write8 : NULL, + pos + PCI_CAP_LIST_NEXT, 1, + (void *)(uintptr_t)next); + if ( rc ) + return rc; + + next &=3D ~3; + } + } + + /* Return early for the hw domain, no masking of PCI_STATUS. */ + if ( is_hwdom ) + return 0; + + /* Utilize rsvdp_mask to hide PCI_STATUS_CAP_LIST from the guest. */ + return vpci_add_register_mask(pdev->vpci, vpci_hw_read16, vpci_hw_writ= e16, + PCI_STATUS, 2, NULL, + PCI_STATUS_RO_MASK & + ~(mask_cap_list ? PCI_STATUS_CAP_LIST = : 0), + PCI_STATUS_RW1C_MASK, + mask_cap_list ? PCI_STATUS_CAP_LIST : 0, + PCI_STATUS_RSVDZ_MASK); +} + +static int vpci_init_ext_capability_list(const struct pci_dev *pdev) +{ + unsigned int pos =3D PCI_CFG_SPACE_SIZE; + + if ( !pdev->ext_cfg ) + return 0; + + if ( !is_hardware_domain(pdev->domain) ) + /* Extended capabilities read as zero, write ignore for DomU */ + return vpci_add_register(pdev->vpci, vpci_read_val, NULL, + pos, 4, (void *)0); + + do + { + uint32_t header =3D pci_conf_read32(pdev->sbdf, pos); + int rc; + + if ( header =3D=3D 0xffffffffU ) + { + printk(XENLOG_WARNING + "%pd %pp: broken extended cap list, offset %#x\n", + pdev->domain, &pdev->sbdf, pos); + return 0; + } + + rc =3D vpci_add_register(pdev->vpci, vpci_read_val, NULL, + pos, 4, (void *)(uintptr_t)header); + if ( rc =3D=3D -EEXIST ) + { + printk(XENLOG_WARNING + "%pd %pp: overlap in extended cap list, offset %#x\n", + pdev->domain, &pdev->sbdf, pos); + return 0; + } + + if ( rc ) + return rc; + + pos =3D PCI_EXT_CAP_NEXT(header); + } while ( pos >=3D PCI_CFG_SPACE_SIZE ); + + return 0; +} + int vpci_init_capabilities(struct pci_dev *pdev) { + int rc; + + rc =3D vpci_init_capability_list(pdev); + if ( rc ) + return rc; + + rc =3D vpci_init_ext_capability_list(pdev); + if ( rc ) + return rc; + for ( unsigned int i =3D 0; i < NUM_VPCI_INIT; i++ ) { const vpci_capability_t *capability =3D &__start_vpci_array[i]; const unsigned int cap =3D capability->id; const bool is_ext =3D capability->is_ext; unsigned int pos =3D 0; - int rc; =20 if ( !is_ext ) pos =3D pci_find_cap_offset(pdev->sbdf, cap); --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -744,132 +744,6 @@ static int bar_add_rangeset(const struct return !bar->mem ? -ENOMEM : 0; } =20 -static int vpci_init_capability_list(struct pci_dev *pdev) -{ - int rc; - bool mask_cap_list =3D false; - bool is_hwdom =3D is_hardware_domain(pdev->domain); - - if ( pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST ) - { - /* Only expose capabilities to the guest that vPCI can handle. */ - unsigned int next, ttl =3D 48; - static const unsigned int supported_caps[] =3D { - PCI_CAP_ID_MSI, - PCI_CAP_ID_MSIX, - }; - /* - * For dom0, we should expose all capabilities instead of a fixed - * capabilities array, so setting n to 0 here is to get the next - * capability position directly in pci_find_next_cap_ttl. - */ - const unsigned int n =3D is_hwdom ? 0 : ARRAY_SIZE(supported_caps); - - next =3D pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST, - supported_caps, n, &ttl); - - rc =3D vpci_add_register(pdev->vpci, vpci_read_val, - is_hwdom ? vpci_hw_write8 : NULL, - PCI_CAPABILITY_LIST, 1, - (void *)(uintptr_t)next); - if ( rc ) - return rc; - - next &=3D ~3; - - if ( !next && !is_hwdom ) - /* - * If we don't have any supported capabilities to expose to the - * guest, mask the PCI_STATUS_CAP_LIST bit in the status - * register. - */ - mask_cap_list =3D true; - - while ( next && ttl ) - { - unsigned int pos =3D next; - - next =3D pci_find_next_cap_ttl(pdev->sbdf, - pos + PCI_CAP_LIST_NEXT, - supported_caps, n, &ttl); - - if ( !is_hwdom ) - { - rc =3D vpci_add_register(pdev->vpci, vpci_hw_read8, NULL, - pos + PCI_CAP_LIST_ID, 1, NULL); - if ( rc ) - return rc; - } - - rc =3D vpci_add_register(pdev->vpci, vpci_read_val, - is_hwdom ? vpci_hw_write8 : NULL, - pos + PCI_CAP_LIST_NEXT, 1, - (void *)(uintptr_t)next); - if ( rc ) - return rc; - - next &=3D ~3; - } - } - - /* Return early for the hw domain, no masking of PCI_STATUS. */ - if ( is_hwdom ) - return 0; - - /* Utilize rsvdp_mask to hide PCI_STATUS_CAP_LIST from the guest. */ - return vpci_add_register_mask(pdev->vpci, vpci_hw_read16, vpci_hw_writ= e16, - PCI_STATUS, 2, NULL, - PCI_STATUS_RO_MASK & - ~(mask_cap_list ? PCI_STATUS_CAP_LIST = : 0), - PCI_STATUS_RW1C_MASK, - mask_cap_list ? PCI_STATUS_CAP_LIST : 0, - PCI_STATUS_RSVDZ_MASK); -} - -static int vpci_init_ext_capability_list(const struct pci_dev *pdev) -{ - unsigned int pos =3D PCI_CFG_SPACE_SIZE; - - if ( !pdev->ext_cfg ) - return 0; - - if ( !is_hardware_domain(pdev->domain) ) - /* Extended capabilities read as zero, write ignore for DomU */ - return vpci_add_register(pdev->vpci, vpci_read_val, NULL, - pos, 4, (void *)0); - - do - { - uint32_t header =3D pci_conf_read32(pdev->sbdf, pos); - int rc; - - if ( header =3D=3D 0xffffffffU ) - { - printk(XENLOG_WARNING - "%pd %pp: broken extended cap list, offset %#x\n", - pdev->domain, &pdev->sbdf, pos); - return 0; - } - - rc =3D vpci_add_register(pdev->vpci, vpci_read_val, NULL, - pos, 4, (void *)(uintptr_t)header); - if ( rc =3D=3D -EEXIST ) - { - printk(XENLOG_WARNING - "%pd %pp: overlap in extended cap list, offset %#x\n", - pdev->domain, &pdev->sbdf, pos); - return 0; - } - - if ( rc ) - return rc; - - pos =3D PCI_EXT_CAP_NEXT(header); - } while ( pos >=3D PCI_CFG_SPACE_SIZE ); - - return 0; -} - int vpci_init_header(struct pci_dev *pdev) { uint16_t cmd; @@ -918,14 +792,6 @@ int vpci_init_header(struct pci_dev *pde if ( rc ) return rc; =20 - rc =3D vpci_init_capability_list(pdev); - if ( rc ) - return rc; - - rc =3D vpci_init_ext_capability_list(pdev); - if ( rc ) - return rc; - if ( pdev->ignore_bars ) return 0; =20 From nobody Wed Feb 11 10:35:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1770720954; cv=none; d=zohomail.com; s=zohoarc; b=j3YspFJJRdiHHXeJam0OdzZ1r8HMW3+QkJLG0ntcuM6fcU+qBOwpR+6LzfNoreBC4IEXNAfWxHRw1g9l82F9Nw5zUG1ieUoeO48brvXjvwy/IobhKn85V4pEPhby84Nd0ROPr9tKRZQQUVtw2wmMI5sC8VS1dzBjG+VA+8wRcLM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770720954; 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=GNpIj6jaNl2LxIucX2SnvqUjVuHy9Wt9ulv9NB3hNFo=; b=iUauZNqgDl/XBccDeJRKo7Gw5GpBSj8hC1K1VtdZgyZkYN869v/0GOopYymRrQqNeXxqg4btFJjyp7m3k0K19kGpHi9tTVEiHy8uZsO0/h1pMaz7jYOd7HQg7K6Rb0PDHso9ZgKH4E4olm5DH7RjmMet0QDfTaGEt97U2FRESiY= 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=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770720954049546.452651520046; Tue, 10 Feb 2026 02:55:54 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1226264.1532806 (Exim 4.92) (envelope-from ) id 1vplP8-0006pp-I8; Tue, 10 Feb 2026 10:55:38 +0000 Received: by outflank-mailman (output) from mailman id 1226264.1532806; Tue, 10 Feb 2026 10:55:38 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vplP8-0006pi-Ev; Tue, 10 Feb 2026 10:55:38 +0000 Received: by outflank-mailman (input) for mailman id 1226264; Tue, 10 Feb 2026 10:55:37 +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 1vplP7-0006pN-7L for xen-devel@lists.xenproject.org; Tue, 10 Feb 2026 10:55:37 +0000 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [2a00:1450:4864:20::433]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 078fcdc6-066f-11f1-b162-2bf370ae4941; Tue, 10 Feb 2026 11:55:36 +0100 (CET) Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-4359a302794so2557449f8f.1 for ; Tue, 10 Feb 2026 02:55:36 -0800 (PST) Received: from [10.156.60.236] (ip-037-024-206-209.um08.pools.vodafone-ip.de. [37.24.206.209]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4362972fa4csm31979410f8f.26.2026.02.10.02.55.35 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Feb 2026 02:55:35 -0800 (PST) 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: 078fcdc6-066f-11f1-b162-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1770720936; x=1771325736; darn=lists.xenproject.org; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=GNpIj6jaNl2LxIucX2SnvqUjVuHy9Wt9ulv9NB3hNFo=; b=R25tQqfVaBK6/gSGqclZ2F0CFFT0IN4jd91VW/2nmRZ+eBe5JFC9AQlc+nciODVHD7 D2EjTqud88xEU214WvyE2vWC4s+rH72i85JMsyrxLYqGBlUuE4tWwfm10Jsyfmwc1M24 ezPmAACPKzlutbucBB0IV9+FcGxn5HzNiIRSyPpbgdCFolfk26L4Yp+Gt/IB5GOIRJ3k nSQ9v9ZzjqotzTCE+4voY+xQLIk0TVTOdVoSjpdmCHVovYyEOn+38RDj3R1vckCBf/Dp pqQv554SVKs9n4+IOIkyNxgAd8p47paTOS7aV4TOw1ykuYQHJo1UQ8CitcevDuB5nWjR NqBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770720936; x=1771325736; h=content-transfer-encoding:in-reply-to:autocrypt:content-language :references:cc:to:from:subject:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=GNpIj6jaNl2LxIucX2SnvqUjVuHy9Wt9ulv9NB3hNFo=; b=S3kSUNiY8ineFOUW7YtkbT9hxh23msphA+pwjqWlEMS01HAT/nW6LQeM0zou4HJy50 bjc8stf0fljR/fCZiAZ48+xQJNyIgBVUQ0ggWaX4QR274iA/C8AQmUciYtQ3m7xxgjmE 4w9H2WfQy/NePqYTQqQsVugyp0BasmycRomFtFkloKDUiXOPw/CS8NVUyCwJUrOTKpwS CKQ+SNgjyIVwj402/kpdLC7ZoxPTRqZwOin2sZtRTG7pKOOMW4J4BDK/59FFDiKcfJsd fF/cozb7t9ksAcy4XRqbIC6GGIU4jYrvKlNDmNsQGimr68yXEdPrvukoidD9uAK6DpNV boEg== X-Gm-Message-State: AOJu0YzyfpX6LvVRqnb80A0ezYXJio3QvtwRSow+P4ta8K4c6pGs1zPG 8ok+FbWU25eqQFZoNkE3/YPfgRBUKoFLYiQAy5s4EYp2pGHOBwVrRnzvpTxcYjC5dqnYGIW4VNE lIE0= X-Gm-Gg: AZuq6aJWytdBwhLLTassQVLu3RnQ/6NRf1eGeTlal4UXH1MiDEoOs8Mt7jvpm6zs2fX YqOP3Hg+rXN8gCj+66kA+VP+a3qpdWmVlpXVrdEt/nWc10tKZyOMgoxUT1djWbvZSyULDFkcH3G x2sXSbVekV0Xx9GqbKbEl8TEApy34wGMPMqlaIp2eaK05SOpEyP5/ul852JqDc+sszBotz6e5TH y3E3BM8XA9eEzd+GWC525ldobF9bmhuRvKSHZ++Udbx+XMacXliOLzN9f6I3bfazeQnGe18ZNgi 2QpmETpWRnxISe+y7SlUdflZNK7Ih/6cjVwzTblso6o6ZpH4615H0z7u2X5wc3+vmF6QGe7BWUq /yfxykZ+2qN5ozUJA/cvBMmME2i1WyZWjAuEsGr3ZdLThMKmIb+Kt2XhcHrcnWPUbLUaDtioZVI uuZQju8aQ2F+nRRkHEvomIu7kLv84W3Oa8wRwC8SI15el8M2Z4k2Hgp0+eEf2wFL5NOcawx3pOD FV04xsP4MHAJvE= X-Received: by 2002:a05:6000:4012:b0:435:7154:2a7 with SMTP id ffacd0b85a97d-43629244890mr19756974f8f.6.1770720935719; Tue, 10 Feb 2026 02:55:35 -0800 (PST) Message-ID: <67b1f190-a7a8-4cf2-89ca-7186204f0b56@suse.com> Date: Tue, 10 Feb 2026 11:55:34 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v4 5/5] vPCI: re-init extended-capabilities when MMCFG availability changed From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand References: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Language: en-US Autocrypt: addr=jbeulich@suse.com; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL In-Reply-To: <25c65557-c97c-499c-a698-571e40cde563@suse.com> Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1770720955171154100 Content-Type: text/plain; charset="utf-8" When Dom0 informs us about MMCFG usability, this may change whether extended capabilities are available (accessible) for devices. Zap what might be on record, and re-initialize things. No synchronization is added for the case where devices may already be in use. That'll need sorting when (a) DomU support was added and (b) DomU-s may run already while Dom0 / hwdom still boots (dom0less, Hyperlaunch). Signed-off-by: Jan Beulich --- vpci_reinit_ext_capabilities()'es return value isn't checked, as it doesn't feel quite right to fail the hypercall because of this. At the same time it also doesn't feel quite right to have the function return "void". Thoughts? --- v4: Make sure ->cleanup() and ->init() are invoked. v3: New. --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -8,6 +8,8 @@ #include #include #include +#include + #include #include #include @@ -169,7 +171,10 @@ int cf_check physdev_check_pci_extcfg(st =20 ASSERT(pdev->seg =3D=3D info->segment); if ( pdev->bus >=3D info->start_bus && pdev->bus <=3D info->end_bus ) + { pci_check_extcfg(pdev); + vpci_reinit_ext_capabilities(pdev); + } =20 return 0; } --- a/xen/drivers/vpci/cap.c +++ b/xen/drivers/vpci/cap.c @@ -285,13 +285,16 @@ static int vpci_init_ext_capability_list return 0; } =20 -int vpci_init_capabilities(struct pci_dev *pdev) +int vpci_init_capabilities(struct pci_dev *pdev, bool ext_only) { int rc; =20 - rc =3D vpci_init_capability_list(pdev); - if ( rc ) - return rc; + if ( !ext_only ) + { + rc =3D vpci_init_capability_list(pdev); + if ( rc ) + return rc; + } =20 rc =3D vpci_init_ext_capability_list(pdev); if ( rc ) @@ -305,7 +308,7 @@ int vpci_init_capabilities(struct pci_de unsigned int pos =3D 0; =20 if ( !is_ext ) - pos =3D pci_find_cap_offset(pdev->sbdf, cap); + pos =3D !ext_only ? pci_find_cap_offset(pdev->sbdf, cap) : 0; else if ( is_hardware_domain(pdev->domain) ) pos =3D pci_find_ext_capability(pdev, cap); =20 @@ -349,7 +352,7 @@ int vpci_init_capabilities(struct pci_de return 0; } =20 -void vpci_cleanup_capabilities(struct pci_dev *pdev) +void vpci_cleanup_capabilities(struct pci_dev *pdev, bool ext_only) { for ( unsigned int i =3D 0; i < NUM_VPCI_INIT; i++ ) { @@ -361,7 +364,7 @@ void vpci_cleanup_capabilities(struct pc continue; =20 if ( !capability->is_ext ) - pos =3D pci_find_cap_offset(pdev->sbdf, cap); + pos =3D !ext_only ? pci_find_cap_offset(pdev->sbdf, cap) : 0; else if ( is_hardware_domain(pdev->domain) ) pos =3D pci_find_ext_capability(pdev, cap); if ( pos ) @@ -376,6 +379,20 @@ void vpci_cleanup_capabilities(struct pc } } =20 +int vpci_reinit_ext_capabilities(struct pci_dev *pdev) +{ + if ( !pdev->vpci ) + return 0; + + vpci_cleanup_capabilities(pdev, true); + + if ( vpci_remove_registers(pdev->vpci, PCI_CFG_SPACE_SIZE, + PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE= ) ) + ASSERT_UNREACHABLE(); + + return vpci_init_capabilities(pdev, true); +} + /* * Local variables: * mode: C --- a/xen/drivers/vpci/private.h +++ b/xen/drivers/vpci/private.h @@ -44,8 +44,8 @@ typedef struct { #define REGISTER_VPCI_EXTCAP(name, finit, fclean) \ REGISTER_VPCI_CAPABILITY(PCI_EXT_CAP_ID_##name, name, finit, fclean, t= rue) =20 -int vpci_init_capabilities(struct pci_dev *pdev); -void vpci_cleanup_capabilities(struct pci_dev *pdev); +int vpci_init_capabilities(struct pci_dev *pdev, bool ext_only); +void vpci_cleanup_capabilities(struct pci_dev *pdev, bool ext_only); =20 /* Add/remove a register handler. */ int __must_check vpci_add_register_mask(struct vpci *vpci, --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -102,7 +102,7 @@ void vpci_deassign_device(struct pci_dev &pdev->domain->vpci_dev_assigned_map); #endif =20 - vpci_cleanup_capabilities(pdev); + vpci_cleanup_capabilities(pdev, false); =20 spin_lock(&pdev->vpci->lock); while ( !list_empty(&pdev->vpci->handlers) ) @@ -159,7 +159,7 @@ int vpci_assign_device(struct pci_dev *p if ( rc ) goto out; =20 - rc =3D vpci_init_capabilities(pdev); + rc =3D vpci_init_capabilities(pdev, false); =20 out: if ( rc ) --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -20,6 +20,7 @@ #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1) =20 int __must_check vpci_init_header(struct pci_dev *pdev); +int vpci_reinit_ext_capabilities(struct pci_dev *pdev); =20 /* Assign vPCI to device by adding handlers. */ int __must_check vpci_assign_device(struct pci_dev *pdev); @@ -197,6 +198,11 @@ bool vpci_ecam_read(pci_sbdf_t sbdf, uns #else /* !CONFIG_HAS_VPCI */ struct vpci_vcpu {}; =20 +static inline int vpci_reinit_ext_capabilities(struct pci_dev *pdev) +{ + return 0; +} + static inline int vpci_assign_device(struct pci_dev *pdev) { return 0;