From nobody Tue Mar 3 03:05:53 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=1772019812; cv=none; d=zohomail.com; s=zohoarc; b=i2vJFNLIWSpIp5kd1BN0BApU99DRvMwvkfo7HQpM8VqNL5zfzzHrvGfYh+rG1IPyHnM/blzhqrmcM6BkD5Djtm1paxPzgOXI7Xs6sG1AmOPJqMldJrtuF8d9NthvcAj2Uq5tGOXOn0Ff7W9NbQfIvn4e8lc1GpmNr/G62WPHQN4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772019812; 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=d/bYJNCMrXcDk4+lvsUiKd0KIHHaZPQTZxJdb8c+n/Q=; b=nAOfeE8L+p4y9HpJgr3AvqaND9jrv36+PcPh5TSbXNQRpt7GBgh6MlU4EDBEoj2Mq9qD+TTBzlqJ2LHikz2iASJc6oYJwFavnGfd6iOHQvMr/y4yaAsPACXGdpkzn7phJOmCkz3eShI7QhO6QnGMbWSQhHP7FPMng18uRFuHKo0= 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 1772019812389772.3128176975795; Wed, 25 Feb 2026 03:43:32 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1240607.1541923 (Exim 4.92) (envelope-from ) id 1vvDIQ-00026u-Rh; Wed, 25 Feb 2026 11:43:14 +0000 Received: by outflank-mailman (output) from mailman id 1240607.1541923; Wed, 25 Feb 2026 11:43:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vvDIQ-00026n-P8; Wed, 25 Feb 2026 11:43:14 +0000 Received: by outflank-mailman (input) for mailman id 1240607; Wed, 25 Feb 2026 11:43:12 +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 1vvDIO-00026d-JT for xen-devel@lists.xenproject.org; Wed, 25 Feb 2026 11:43:12 +0000 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [2a00:1450:4864:20::331]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 25231154-123f-11f1-b164-2bf370ae4941; Wed, 25 Feb 2026 12:43:04 +0100 (CET) Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-4838c15e3cbso57168005e9.3 for ; Wed, 25 Feb 2026 03:43:04 -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-483bfbb465bsm24281275e9.3.2026.02.25.03.43.02 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 25 Feb 2026 03:43:03 -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: 25231154-123f-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1772019783; x=1772624583; 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=d/bYJNCMrXcDk4+lvsUiKd0KIHHaZPQTZxJdb8c+n/Q=; b=NSbhNsX3J5ohKHVscD9xBCQ81R++IoQGCW4xoZxRKolGXuJcL9eJBTexw0urhlUYk3 k3nO5OZtQcyKksLN86YfMiLcVchxgdRMW1WsBckg11qmqfki4Mt1u3sEZfDPcrz4cX/w 5TFMhjGUlvO3DWLtvihnxyayeCNOCBhT82r8fQbUXT0kVTYvGTVC2/JMUB8+48tyvjXw 3+YTykAF414oDgTRmdsOc2zGovI5R38GvzBAwpbuyCTyeyArN5TgAhepCJGl8ds54Ueg zPk1mnuY4XZGV/0CgW2X/n4MqdoKVh3Xt2OultZvf+CAQaRV4hTHRmGPVHFgF9bDsahw YpTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772019783; x=1772624583; 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=d/bYJNCMrXcDk4+lvsUiKd0KIHHaZPQTZxJdb8c+n/Q=; b=SV6ary24wX3Qzb3VnX70RGhZjVW5qaJ6B7/yB1CxSzOxC+jADLakL3zBE5kG0ugmOZ hXoClCOAbYXYRvoJlTzdMNdeg/q62MhGckMMNhMXP4Z9X/uvuWO3V/30gSv9SVcgNhLD tS6HueWcWYsynEFj9/BLPg0vVgrxeD+EZ5hT5vo10q8jVhepdfS2R2RLTKVVlhgpgqU3 8VnlTJTbUsTvKPoikvksOAz5NfZgDeg+s6n8y6HlGqXaqr8xjVP3ind14PQlXIVl0Sz2 DvEusG6LZ8UbxqFzyEliIU5NaWkDQijBHAn8vk9rkEExOU6s6kmdKVmUPOgoLAbmki1y g2BA== X-Gm-Message-State: AOJu0YxB5ZSOF1wqBo8ZKwm9FBmVRb3c8mSBKSX+4ljya2CLZYZnkGDw yKlXbtkCuueT8fLnfACsgvu7qWI5x7y5QmUyRnWWZaC4jwdaCfPJNWtFPChnSEzFOzFHqui0sTu iV+M= X-Gm-Gg: ATEYQzwpp/y0dMBYHzo0ZyKz/yML7h/Vm9OHwa++sQ9vM65v4xvi4F2SZj9cy4XP8SM 8xJEpRtXkihdsj+EjKSAhHRxp0A944yFf5fZ6tgyn5C/wSLdGuPzbNdIvdFeTD4hCRL5ueR81v9 mQzXIDh7pSR3yRsVPoFkMgYM6CZm2Mi8iZigay+0j8OgTESBmoGR4RW7UGt7VB7+IA57gQpcpnd Hu7A/pkgwPSA7Kc5GbuOPG5Cc8dyshKrRMnAfoOCCvLJRp6Ifu26wzjWLfxL56LYiPRWJMW0Zgl Y0akFVNcyKVGN+cDo3nEBuJ0yrWndB3Ou81bXg0gD6zt+kusrYD8vOWHgs91DsektQ6JzqbzMhG iL42PIN12k7klKOmDd9fW18nO55FQ57mQxWbs9bbdsQXLan2UseWY7ysxiux1EzF9OS4eb0+0lV WSuwPg3dfVlNw+NIo4w1+UrkbhziEQ4YnQ1TlDe1QdWHI3DbKE7U7tiUSUJAJLITALR+MzhbYya qucGxCFfedvEg0= X-Received: by 2002:a05:600c:4751:b0:475:de12:d3b5 with SMTP id 5b1f17b1804b1-483a963df99mr242185875e9.34.1772019783358; Wed, 25 Feb 2026 03:43:03 -0800 (PST) Message-ID: Date: Wed, 25 Feb 2026 12:43:01 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v5 1/5] vPCI: introduce private header From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand , Andrew Cooper , Julien Grall , Stefano Stabellini , Volodymyr Babchuk , Bertrand Marquis , Michal Orzel , Anthony PERARD References: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@suse.com> Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772019814615158500 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 Reviewed-by: Stewart Hildebrand --- Subsequently, at least on x86 more stuff may want moving into asm/vpci.h. --- v5: Add new generated header to test harness clean rule and to .gitignore. Also move vpci_init_header(). v4: New. --- a/.gitignore +++ b/.gitignore @@ -154,6 +154,7 @@ tools/tests/x86_emulator/test_x86_emulat tools/tests/x86_emulator/x86_emulate tools/tests/x86_emulator/xop*.[ch] tools/tests/vpci/list.h +tools/tests/vpci/private.h tools/tests/vpci/vpci.[hc] tools/tests/vpci/test_vpci tools/xcutils/lsevtchn --- a/tools/tests/vpci/Makefile +++ b/tools/tests/vpci/Makefile @@ -14,12 +14,12 @@ 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: - rm -rf $(TARGET) *.o *~ vpci.h vpci.c list.h + rm -rf $(TARGET) *.o *~ vpci.h vpci.c list.h private.h =20 .PHONY: distclean distclean: 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,126 @@ +#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) + +int __must_check vpci_init_header(struct pci_dev *pdev); + +/* 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,66 +19,17 @@ 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); - /* Assign vPCI to device by adding handlers. */ int __must_check vpci_assign_device(struct pci_dev *pdev); =20 /* 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 +153,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 +175,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 Tue Mar 3 03:05:53 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=1772019828; cv=none; d=zohomail.com; s=zohoarc; b=a0b3wtjfgLDd+zUbgCT0dMXN2Jn/lMON5d+Hivk68dKPNLHq2FaVbPyr4W2wqhADw9ClFbxwMEIhyj8Z7ljjYf5K+/0z9R3dVswwsIhhSbRHBUwDo7JU8OVlGmx3f0BUiiFf1fnl2DanknbhYWt8J8apnzdq20T3DjKReHbMrgs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772019828; 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=uAgcdDfpsSw1jsAfrY2aV1rXdVm2j1GaT1wB7ahB0HM=; b=jRGx3/st4Yl7IHA8ZDdF8tv+aYbjvEQa4Li44VOCd0vOD7yoBC96A7TatgHwYUStxaietYSCrfMrBfVKEwIKPL4VU5TxPvgXgeARPbgGK6eNUEfWJENRHg9Gc7mv3vGIQdyOM33uZaL40+D3P7J+RME0OZRNUhWc0CWGZdLhCnk= 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 1772019828414261.35837578286225; Wed, 25 Feb 2026 03:43:48 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1240610.1541934 (Exim 4.92) (envelope-from ) id 1vvDIm-0002Tr-3a; Wed, 25 Feb 2026 11:43:36 +0000 Received: by outflank-mailman (output) from mailman id 1240610.1541934; Wed, 25 Feb 2026 11:43:36 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vvDIm-0002Ti-0C; Wed, 25 Feb 2026 11:43:36 +0000 Received: by outflank-mailman (input) for mailman id 1240610; Wed, 25 Feb 2026 11:43:35 +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 1vvDIl-0002SC-BY for xen-devel@lists.xenproject.org; Wed, 25 Feb 2026 11:43:35 +0000 Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [2a00:1450:4864:20::335]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 36268e7e-123f-11f1-9ccf-f158ae23cfc8; Wed, 25 Feb 2026 12:43:32 +0100 (CET) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-48375f1defeso46010455e9.0 for ; Wed, 25 Feb 2026 03:43:32 -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-483bd6f19d6sm66613375e9.2.2026.02.25.03.43.31 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 25 Feb 2026 03:43:31 -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: 36268e7e-123f-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1772019812; x=1772624612; 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=uAgcdDfpsSw1jsAfrY2aV1rXdVm2j1GaT1wB7ahB0HM=; b=hCtIPvNF0GAePeUiht/dviW63m76RF4YyJF6dsyKcrLD6VNhnS2Op0t2SCsnT7qp4F AkXhg2ou0WCG9lpt+GRp8QhnlFex7V1OZGQfYuE8ORZyht+278l2Lnv4LlBG8lYEb0k6 EYlBoTn8W38xp5BGg9FdUylfT0qpuUZgquHBZA/zVbMDhoakiebSP6qo151jFY4IQWl9 WUzTTOXd/7umiVH6TZrr00v8TNLXXEJ2DdOkJXmIdvWI7aZyqOEpmqZXbW8QT7a+Z/Fm HYlfWPf/RzWM0awhoPIVgFwdrGiuIi7oj1PY+NZ+EqUbJyb0d2Q+vD5iNdQBfi1eHTPH uJzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772019812; x=1772624612; 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=uAgcdDfpsSw1jsAfrY2aV1rXdVm2j1GaT1wB7ahB0HM=; b=wFlwNvhpJMWhenu1uRkJtJnCu+qy6n/VLPsgNorbBXteTCOZZkMIOS70+Fux0xHO0w mLRlfz9J1cpr6X+48Y/o7Ni/ibP3W5lNeuXAQpHAKPpY3LMUPFqJU6iOPJ+zIesSbiw3 R+BC25j8Wa79wZqIlVohzlycISRiWGI3uJUVge5VG9ccSjeCOE+opLIp1c41h6+y+GaZ mmCMFdzlp0mhoUWImD1lO5Za9tOJVfUGSkYQgb3PLb1gsr2salCmJ6ASuY8fm6Q5blwi PulX4bBG+NoUYy6PXB4b5wqYZ+OcXFlMZRb+K622E7nhIdo791/OB5x19RA572U4V4gX X/Yg== X-Gm-Message-State: AOJu0YypdJl+x4GV/j0hh8MHLVzvTHANTqtsxV5fxdd8nE10pe97lvxD iYhWpPDpvsjD/cG8NPzoeQUuF3zJX8bceD5/AOmLxADF7cizt73Ir0Hq+aPSt9zSXrMyhiqkgTU V0/Q= X-Gm-Gg: ATEYQzww0k1DvocuMsfQhLUDMcVEhrCCveKJhJ1Fq0BySvX7YhxftIUUsxinJmn2ub/ NvmjItcDS9yLfxE0zCXA/4CTJJp/lByPAopseM+5pLFKkwZ05ZSBQdVcm1b0lFHz2ssM77h4zfc oZ2bOvnNAqy/KTWQEzBRt1vB6Bn+Jx0VPPUC1zwbfJpuhPuKXKXvtjS590NLjR+bQSDC/4KgawT xsgIXuZ1d4LbM1+YLkzNlZnG4Jsw14XaKGfLC4hMMALP7H6/I5V0A165lNfuLz1rg8dBmQdySjZ oEMRexBzRJ0/xTSanWS3al9ax9wuoGCN9Q3TA0unUsL8+/b8OWXbHIczOD6wnYBDCVHwYZlrD0Z 9FunbIhn9xFFU++hH8fraeoA+KrcZXHCtj5h3yfVdbLzfYIkDT05WIL8JD+vTEnNGcYMDY3tTA+ yIqhOqR2llbViUhNPEvfuHuGboOEhfoCmFeKIgJer07o+7zKYoLcZ3eZ4hQoKou5tQGmjBttdpu HCBRsl20ZZJiMw= X-Received: by 2002:a05:600c:a016:b0:477:fcb:2256 with SMTP id 5b1f17b1804b1-483a962e470mr270138675e9.17.1772019811947; Wed, 25 Feb 2026 03:43:31 -0800 (PST) Message-ID: Date: Wed, 25 Feb 2026 12:43:30 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v5 2/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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@suse.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772019830564158500 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 Reviewed-by: Stewart Hildebrand Acked-by: Roger Pau Monn=C3=A9 --- 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; @@ -32,6 +46,9 @@ typedef struct { =20 int __must_check vpci_init_header(struct pci_dev *pdev); =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, @@ -49,6 +66,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 Tue Mar 3 03:05:53 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=1772019862; cv=none; d=zohomail.com; s=zohoarc; b=QsP5JUda8Bpz0olzBxfzire51X+jydYO4yvm8gMDnLytxCA6gV6xVdstsB+VYfszCvzLXKvU0+TJGFiXfFyLPqtJA+bL5ddp/X+VWD475nKqDXzYIMKdQEyYwSifQIgE1dgGows6AkCuUip6ju9EBv1autsfcf8pD/uzECw5D20= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772019862; 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=qvqxSGqotIAOODsHnK2+oa0DmybL0jdHjJLUZwFNknw=; b=P8kRFnumCkeoDcG5VOrQ0dlZLP7UBI/27kmISuiqWhAIFOXJgKyX3rNCw/Ld16qQXrTb0Y15ccGke4fTDcmC/QV1bn7v7pJMT/8ZrV4ksIGryxm0bNuFGFPccLCq0WzuH5g4d5HFuPbZ6OPqGthtd7GYfaXG12RbEpO1vQfkCzI= 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 1772019862601274.0645625930399; Wed, 25 Feb 2026 03:44:22 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1240623.1541943 (Exim 4.92) (envelope-from ) id 1vvDJE-00032f-DC; Wed, 25 Feb 2026 11:44:04 +0000 Received: by outflank-mailman (output) from mailman id 1240623.1541943; Wed, 25 Feb 2026 11:44:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vvDJE-00032Y-AW; Wed, 25 Feb 2026 11:44:04 +0000 Received: by outflank-mailman (input) for mailman id 1240623; Wed, 25 Feb 2026 11:44:03 +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 1vvDJD-0002SC-1Q for xen-devel@lists.xenproject.org; Wed, 25 Feb 2026 11:44:03 +0000 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [2a00:1450:4864:20::333]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 470d1f37-123f-11f1-9ccf-f158ae23cfc8; Wed, 25 Feb 2026 12:44:01 +0100 (CET) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-483487335c2so58992385e9.2 for ; Wed, 25 Feb 2026 03:44:01 -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-483bffc17dasm17462215e9.2.2026.02.25.03.44.00 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 25 Feb 2026 03:44:00 -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: 470d1f37-123f-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1772019840; x=1772624640; 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=qvqxSGqotIAOODsHnK2+oa0DmybL0jdHjJLUZwFNknw=; b=cgYfSze+bxQCzruFc3EXdrJMlZmGFyQ62Y+tWUW5Q0Om5PRRpTDKshn/Z4pnXrgbMk jlc95OoWL+G9JvKcfobUZjMsASfHxWMc99eK4TB2MEcf42T5oB9VFWhKVUBm0IAok/zQ ZREXwbTB0NGQLWwo5PuFfTMg6OTWAnlEaCOZ2Efb9/3S4IWkYmVdNNmNgLx+ESe3981B PpqT0/eN+5P5J/r9thcFAOh4kmr6XAcKtJso5JMCpTibD6qDtwfuRUq3pJzX3KZuHyLx UVq7tkgKkdmhDX2+vyAWJH3av1x+VEXMTqRlEkoFjNZxoJECcMCqbVzi7CLl1KOR8ngq y9ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772019840; x=1772624640; 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=qvqxSGqotIAOODsHnK2+oa0DmybL0jdHjJLUZwFNknw=; b=Pv7N/xYE2nQWOO45xsMOXqUzYKr4iql0IfgqwzZsoGpzrwiQ/9LNliK+1DINHMKimW SyQT4vpk70UvNOZC+ih6coNJ0LnDkXgkgk5nvllBren7yr7sq8PVY1iAnenXIFHVAEdJ mLYughEY9XNcRzCRUKgiroC/aqGibE2PIx96AkRkIDWuauMrDTW/fAbWJ8mDP5PH9IYK LSXi9DFreW9FkGQwimDW3TZuJ1b0dSv2tTqJ+trGHmdcevHHiV++BFYSHhEY9OdBUX9V IyqHfpYBlyYwBerehZZIbsF02pAGG6aNSo9kEMeAt1Icz+H09Ra59dmRTibIyjEbMwFP yBxw== X-Gm-Message-State: AOJu0YxN97PEU9HCQAqd3NBfvCVUDUsPLxPIA6kC/8S5sia4gBi9iLUQ 8yvVQkVKzJ/f/Oh7zNiYxCQgWwkBSCFK3xfO1bsOiujI3+kKJc3JwN7juXq6Y9ceaX/ZRGMQk6L my9c= X-Gm-Gg: ATEYQzwXbUO5zVoiywV76lFA5YhFB5p+PZ0LK7XUOBPVC5oQ+JyFh10mPXqakqvbYd4 i6arE4wqG5chcnkzLXoBLytVQ/qNq7e/AAdBSfS9CbmUwrMGGuvu7q1f8J5wklVjNGKfLeJy9yT qhhO0XU7W4Wt3+TU6Wtef7ddH9CWmLBcgkp30TmDkibLgxvt2qHTPsEFZThKHBmhKI7oQtcznse iyKe8utJvMcShyZ5uJKyCqTr5Sv4ey/zJEFR3+IwrE6Dwpix4d2YNkVwupxS+QkEef42iKalQ4B xkLWG7A4Xv29OC1Srxt0/6nBK+c7L4d7IlO6ptp7icJcWv6sGgcGdNJp0qDvId4bA//mbATDVL3 ZvWYXPLU4M+2s9jc4bdVs9Bm4K7Hscv1OvEZ+aNFlffnt4vzZOJr1teSZxds8tuyb8bYHcQipI3 guK3LNZz0pZsxGsiaJv5ycyP84t09NKiit5ORM9L6+1noZE4xCdph3FMsOvWiaOxivz28eywfdk EgV48iirKrJbUA= X-Received: by 2002:a05:600c:4f93:b0:477:df7:b020 with SMTP id 5b1f17b1804b1-483aaa15e35mr278740115e9.18.1772019840449; Wed, 25 Feb 2026 03:44:00 -0800 (PST) Message-ID: Date: Wed, 25 Feb 2026 12:43:59 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v5 3/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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@suse.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772019864523158500 ... 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 Reviewed-by: Stewart Hildebrand Acked-by: Roger Pau Monn=C3=A9 --- 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 Tue Mar 3 03:05:54 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=1772019881; cv=none; d=zohomail.com; s=zohoarc; b=e3vBi0GBQSUaiOhiENBV1VpyJY07p3jVz2u51kGqdQLE4EG+VyC0S2i6xvxdIMHYnQ2nG2HBfSCWGSRiG+bkRiPLoCrbyVdKbmdeg7ZjikpIwwK9Suivs1dSWIW3bqSnJqfGVa+4NlzdO3X+FwXMIwhbcxy+sNVVo//JOf8OzQE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772019881; 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=F4vS9yj8ZbkDhyH0h+l80l5O91ePGrjIYaOjnrsaMT4=; b=X+hVdcFIsTBfnfo9+jBFRgmTOtGwV8vLoc2lcFHGchDe7CcIUTmxkz6WjIlzIGnNfT9hv6W9sIuQ0gWuTO26ID8eEdqiTtdSo47Y2kFiHIiyKxIC0YUaqJovYLkkGqnpAH2OXsVWlgqvpt+5Qb0eLo0iJJZ3qiqw+DHn1B8LwIk= 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 1772019881304893.4477697349606; Wed, 25 Feb 2026 03:44:41 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1240633.1541954 (Exim 4.92) (envelope-from ) id 1vvDJa-0003ZC-Lf; Wed, 25 Feb 2026 11:44:26 +0000 Received: by outflank-mailman (output) from mailman id 1240633.1541954; Wed, 25 Feb 2026 11:44:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vvDJa-0003Z5-HS; Wed, 25 Feb 2026 11:44:26 +0000 Received: by outflank-mailman (input) for mailman id 1240633; Wed, 25 Feb 2026 11:44:25 +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 1vvDJZ-0002tl-Qn for xen-devel@lists.xenproject.org; Wed, 25 Feb 2026 11:44:25 +0000 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [2a00:1450:4864:20::432]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 5537a146-123f-11f1-b164-2bf370ae4941; Wed, 25 Feb 2026 12:44:24 +0100 (CET) Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-439857ec679so1690940f8f.2 for ; Wed, 25 Feb 2026 03:44:24 -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-483bd6f19f5sm154793855e9.1.2026.02.25.03.44.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 25 Feb 2026 03:44:23 -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: 5537a146-123f-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1772019864; x=1772624664; 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=F4vS9yj8ZbkDhyH0h+l80l5O91ePGrjIYaOjnrsaMT4=; b=P1VdV8pG1MEgcpHbPnzYCAY+08dufnw9qQ2P4pwCW/faAYczJnBkO48gWvkThWPCig Z33s5TZEmHGcCKTfEuWTNS3V3FIEl4f4AswUV8iFMPXHwAYRmWN7r8R2/+8eP9r6qdFK c3IsZuQ3W6c0HV80gtVSwLZB6Ef+/h87P5W/Io/7NyqzLwGAZXse4RtvM4BShtgR+kpp jCbNBig2ARF+LrIb+mPgCoecUOlTlHpLDyZ4dxq5o7pKYAStWpApx+7aql5vXfqLUXZO LobCP7I9ywEWB0KLk8bdF4ZacLH8bgWCqlldSeSdpoQ4kID/GxOkWR9n87zYhD1zcG34 TGRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772019864; x=1772624664; 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=F4vS9yj8ZbkDhyH0h+l80l5O91ePGrjIYaOjnrsaMT4=; b=g7FvXB8G7aM+X/Wwe8xUOMDv1Kf3t9DUNJjJHklxfh/Uj6Vm82VDHFYwb6nEtffpf0 i9W8crBfQEGkuJsXDkjIsp2I/ZYHuBRdM8JEYoZYWK5ao/U/kfCAGtm4XscFMDnq7bNV MEoBEqSSRIv6S9YJWEYVFwUieG2qkoo9kPG+vlMySIAQj6bkeM8iF/Gb1OumtzEV98wF WT+73/QZfJ4vHocbmmV07ILc+y+fB8ZO8zConVqQwZWK7mOA8BnYL5cDF4xPwX7/2dfL gM269VCUXjdsmzFEpsC+1eByy4gTGzTAtZy3enQRwq+nM9YkiW9vBMaYxkDvnMe2h2Wh pJvA== X-Gm-Message-State: AOJu0YzgWKfMMJzGBhXkFIy3U8ajK1nHSYNYJLEpWeN1aUP4rCdOVkGa XboETysJspKLOCCJFuHrwGqmJ6uKGs5ZPN1B8Oz99ZQkVgHggOYIu7trNky6zS8aYxSQ798WETm G3e4= X-Gm-Gg: ATEYQzxIjblR7V2I5PgPkG8nwSyjzJnmauTto0aLcEbu+M4XliPHRsx2MM9//5Uo7gO RwevQS0rSa/p3rYASZUacKlwGVxgZnnNK1pYN+xAB5bAb+D5fs2/1jI5cJZHvVbrUWPo9cZ2aWG evN7YcSm+M0QsZ6/qJlsN+KyzaJ1xKyu84h93HFvbBPJFAELub0MUfejRUuhSLtD4BfWZvzgxY+ JCVnP+6vsaUI936qKoNP3JaKrtERBvztC6RBCrgCFTRwt6hBW1Iq4Oz9eTkWHo4owY+SUOKRiDH B0QJuca+Dt0kvNsYtTkpGWBhy6gA3V8cX5Z2jqChEQJYA20qjl9y/pIfZTJP5JXmtwY5VGFuruK FYetdxlfw7nQU1mk0lI/0brMyanL6K/Idb7kCCB8cGOG5t9YiPkNFQJ+SacpkeB5LhXQzImW+YB WggjxjWyzxWHV113MEr7bKNnbFILDluYK5MLwhjCDChq2INC691Q2jeKyaW7LFW3Sw05LVGLt0e sbl8YSrE9Q2pHc= X-Received: by 2002:a05:600c:5397:b0:483:56c4:73ac with SMTP id 5b1f17b1804b1-483c216bf67mr1163205e9.7.1772019864193; Wed, 25 Feb 2026 03:44:24 -0800 (PST) Message-ID: <252e527e-dcb2-4710-8a43-070c49512e00@suse.com> Date: Wed, 25 Feb 2026 12:44:22 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v5 4/5] vPCI/ReBAR: improve cleanup From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand References: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@suse.com> Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772019882544158500 Content-Type: text/plain; charset="utf-8" We cannot assume extended config space to (still) be accessible when cleaning up. Necessary value need caching instead. In fact, as the caller also cannot look up extended capabilities, the cleanup function needs to cope with being called when there's no ReBAR capability at all. As kind of a side effect nbars being 0 (which init_rebar() doesn't explicitly reject) no longer results in a bogus call to vpci_remove_registers(). Fixes: ee459aeac096 ("vpci/rebar: Implement cleanup function for Rebar") Signed-off-by: Jan Beulich --- v5: New. --- a/xen/drivers/vpci/rebar.c +++ b/xen/drivers/vpci/rebar.c @@ -53,17 +53,12 @@ static void cf_check rebar_ctrl_write(co static int cf_check cleanup_rebar(const struct pci_dev *pdev, bool hide) { int rc; - uint32_t ctrl; - unsigned int nbars; - unsigned int rebar_offset =3D pci_find_ext_capability(pdev, - PCI_EXT_CAP_ID_REB= AR); + unsigned int nbars =3D pdev->vpci->rebar.nbars; + unsigned int rebar_offset =3D pdev->vpci->rebar.offset; =20 - if ( !hide ) + if ( !rebar_offset || !nbars || !hide ) return 0; =20 - ctrl =3D pci_conf_read32(pdev->sbdf, rebar_offset + PCI_REBAR_CTRL(0)); - nbars =3D MASK_EXTR(ctrl, PCI_REBAR_CTRL_NBAR_MASK); - rc =3D vpci_remove_registers(pdev->vpci, rebar_offset + PCI_REBAR_CAP(= 0), PCI_REBAR_CTRL(nbars - 1)); if ( rc ) @@ -121,6 +116,10 @@ static int cf_check init_rebar(struct pc =20 ctrl =3D pci_conf_read32(pdev->sbdf, rebar_offset + PCI_REBAR_CTRL(0)); nbars =3D MASK_EXTR(ctrl, PCI_REBAR_CTRL_NBAR_MASK); + + pdev->vpci->rebar.offset =3D rebar_offset; + pdev->vpci->rebar.nbars =3D nbars; + for ( unsigned int i =3D 0; i < nbars; i++ ) { int rc; --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -135,6 +135,13 @@ struct vpci { struct vpci_arch_msix_entry arch; } entries[]; } *msix; + + /* Resizable BARs data */ + struct vpci_rebar { + unsigned int offset:12; + unsigned int nbars:3; + } rebar; + #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT /* Guest SBDF of the device. */ #define INVALID_GUEST_SBDF ((pci_sbdf_t){ .sbdf =3D ~0U }) From nobody Tue Mar 3 03:05:54 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=1772019906; cv=none; d=zohomail.com; s=zohoarc; b=Al26Sf70knYmnvaVYQrjBgdUvkVSumqyNwaEwFnfLYJPZkGl3V+8J31i5UQWb9OfKm6O44kIVUm7bNniG2VGgQRjqWBNJ7B/O5YB1jeYr/Y4bKNeSiX+ikO2MCjw3e0MlkCcveywqYxIEPOqHruNx2jZ+CaRt4myvNnOGzxPNFI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772019906; 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=5hnVqcplaxx7N9eKjGfFgGadhHdC3ywA3qjLGFALOaQ=; b=MmvpAdgvT3FV0DmSWdnWCMIKfpyFptOE72/gkH7+Np3MPsC99b3gKir/4LNvl0Iicoe9GcWk70nD+8BVNx4tPksLlc0VaArtQM9TrhyIOCawgiSBCmHhnX4WsnPYdw+GaVo7zAjUgnY6DQwssLne15+cpf28ueh/YAJ945QrWZo= 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 1772019906213868.6140869763835; Wed, 25 Feb 2026 03:45:06 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1240639.1541964 (Exim 4.92) (envelope-from ) id 1vvDJw-00042d-T0; Wed, 25 Feb 2026 11:44:48 +0000 Received: by outflank-mailman (output) from mailman id 1240639.1541964; Wed, 25 Feb 2026 11:44:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vvDJw-00042W-Oz; Wed, 25 Feb 2026 11:44:48 +0000 Received: by outflank-mailman (input) for mailman id 1240639; Wed, 25 Feb 2026 11:44:47 +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 1vvDJv-0002tl-PO for xen-devel@lists.xenproject.org; Wed, 25 Feb 2026 11:44:47 +0000 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [2a00:1450:4864:20::435]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 6260a9a1-123f-11f1-b164-2bf370ae4941; Wed, 25 Feb 2026 12:44:46 +0100 (CET) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-4398f8403edso485490f8f.1 for ; Wed, 25 Feb 2026 03:44:46 -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-43970d4c977sm35949921f8f.32.2026.02.25.03.44.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 25 Feb 2026 03:44:45 -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: 6260a9a1-123f-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1772019886; x=1772624686; 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=5hnVqcplaxx7N9eKjGfFgGadhHdC3ywA3qjLGFALOaQ=; b=FPv32s3VUBMK+sHKJzGJ0a9wSV7ydqv8ZmX1ejpzsUcnwK1b2fxWqgUSGzRJ2MRURj DWwPy49tz/wNJUPEoq3mRLlQvVVDHzRPfzBSvNHLp+2v5h2y7/7DfIluNyKG6xTecYlY foxqs+VJqssJMkvYriyBjMuRPykEqXpp1vEw6nPXPLJm/WJTzkVNLGNMeL01eWRRdbl+ VQlOzk2B1sl91JhLcMO5gLoOkeV70xFDFiLpPXPt3pxXcstoqNv7TN3oJEjgvAfDZDxy sPAc2+ILGPdweFLbtsmeiPtTFEFwMw1e/GwTVBOQDw2XNX1xx72cXFX5EADDbHdZRMP2 Ij7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772019886; x=1772624686; 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=5hnVqcplaxx7N9eKjGfFgGadhHdC3ywA3qjLGFALOaQ=; b=AQuseMMDSDN8n3CFQ7YTRwnk8XjaHJLE53vuP4joNwzA/ZL0nu0njj3OXJ/P6ZxN98 ynsiXTzZD33yMOHbiIRH6niNZjtInaczfAqcE9ceii/ifLnmdgalHIgU5HOwyBuSQmih e08ods55YHwHmGxIy3ORZlXuAO+QGpfTheXAU1ShcnUEJ3YEi1nksvuPtZCNvGq6PeeJ fYIbz2fQTj2fNLxVDu2izppY2bxYx3wSWQIUqKdAT2pvQll3RVNL1pxvoQEjtfCgjrW5 ahFFbrlaQ0LRyY900o6v1mrTHoxeuhkxsqMPLy5DIvjx4XUuMVeAB7W6vW6iG8+ePIdd LdJQ== X-Gm-Message-State: AOJu0YxHLApdx56Q+flogWBndwJzFvn5dF6MdOXIGHNozQjqIZl/LwrE v282nKaCFkymsyy9gMY9mi/xYuYfkm/sGl1mtqiZRXvsKcwAdOsnbUBnH9FeU6MEuDNQGPjFg9/ VEp4= X-Gm-Gg: ATEYQzwundrQBW+C7q2MUIJjmCb8Wsz1dEOYw97aQr4+8fhDHChyL4f7zBG2vNBDmjl gTAuhlSXXV5vKGI0oSMFTiY/MvKDYO5F8sP5zjveSQ8VhsCrgjXRJ5c7wYor8N5HUApj3CJ/Vti cXsy9dL8EIh27LEWliZlilzpxGSAQ6MhGen5uT6rXUuYrlezpNRepGOoPCY6CRWp9siDdj9Okz7 Sr/0j1+Cod1WaDuSHPxJnQYXhL2qe92mPBlECs03SKXB2SMvUcnPcY6hQIwO9wcnlAGiCG6Wqo4 pu8kSFHnbYq73fCm55X2mF2OlBm/mdoffuRMVsUWbGgDvahBp4m6BBNh5aPTN7Vr4Q1F0xDUkrA fFLa2/6yVVNq6g3f+3JH+oj/BLIXcra3jwdPa8WH5h21WDnDM1W19U/t8edb3tbzZJMRWSZW+s6 4GVYqcJWrhVHtqcuOhx0IffSyQCKaQalgDVX95UrDAUB4dUvYeFlFO3ZoSgQXX2tNMLaBtwaHmv +FvLub1tW0AUBE= X-Received: by 2002:a05:6000:1867:b0:439:9312:4b72 with SMTP id ffacd0b85a97d-439942ed0b3mr265421f8f.30.1772019886133; Wed, 25 Feb 2026 03:44:46 -0800 (PST) Message-ID: <9f1fcbfc-e7b6-4ef3-8f58-c88f9667d606@suse.com> Date: Wed, 25 Feb 2026 12:44:44 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v5 5/5] vPCI: re-init extended-capabilities when MMCFG availability changed From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: =?UTF-8?Q?Roger_Pau_Monn=C3=A9?= , Stewart Hildebrand References: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@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: <6202d2d4-ad80-4e37-b1f6-cd9d19add72f@suse.com> Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772019906837158500 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). vpci_cleanup_capabilities() also shouldn't have used pci_find_ext_capability(), as already when the function was introduced extended config space may not have been (properly) accessible anymore, no matter whether it was during init. Extended capability cleanup hooks need to cope with being called when the respective capability doesn't exist (and hence the corresponding ->init() hook was never called). Fixes: 70e6dace747e ("vpci: Use cleanup to free capability resource during = deassign") Signed-off-by: Jan Beulich --- vpci_reinit_ext_capabilities()'es return value is checked only to log an error; it doesn't feel quite right to fail the hypercall because of this. Roger brought up the idea of de-assigning the device in such a case, but if a driver doesn't use extended capabilities the device would likely continue to work fine, for Dom0 this probably wouldn't be quite right anyway, and it's also unclear whether calling deassign_device() could be done from this context. Something like what pci_check_disable_device() does may be an option, if we really think we need to "break" the device. The use of is_hardware_domain() in vpci_cleanup_capabilities() was uncommented and hence is left so. Shouldn't there be a DomU-related TODO or FIXME? --- v5: Don't use pci_find_ext_capability() in vpci_cleanup_capabilities(). Add assertion in vpci_reinit_ext_capabilities(). 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,8 +171,17 @@ 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 ) + { + int rc; + pci_check_extcfg(pdev); =20 + rc =3D vpci_reinit_ext_capabilities(pdev); + if ( rc ) + gprintk(XENLOG_ERR, "%pp(%pd): vPCI extcap reinit failed: %d\n= ", + &pdev->sbdf, pdev->domain, rc); + } + return 0; } #endif /* COMPAT */ --- 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,22 +352,23 @@ 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++ ) { const vpci_capability_t *capability =3D &__start_vpci_array[i]; const unsigned int cap =3D capability->id; - unsigned int pos =3D 0; =20 if ( !capability->cleanup ) continue; =20 - 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 ) + /* + * Cannot call pci_find_ext_capability() here, as extended config + * space may (no longer) be accessible. + */ + if ( capability->is_ext + ? is_hardware_domain(pdev->domain) + : !ext_only && pci_find_cap_offset(pdev->sbdf, cap) ) { int rc =3D capability->cleanup(pdev, false); =20 @@ -376,6 +380,28 @@ void vpci_cleanup_capabilities(struct pc } } =20 +int vpci_reinit_ext_capabilities(struct pci_dev *pdev) +{ + if ( !pdev->vpci ) + return 0; + + /* + * FIXME: DomU support is missing. For already running domains we may + * need to pause them around the entire re-evaluation of extended conf= ig + * space accessibility. + */ + if ( pdev->domain ) + ASSERT(pdev->domain =3D=3D hardware_domain || pdev->domain =3D=3D = dom_io); + + 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 @@ -46,8 +46,8 @@ typedef struct { =20 int __must_check vpci_init_header(struct pci_dev *pdev); =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 @@ -25,6 +25,8 @@ int __must_check vpci_assign_device(stru /* Remove all handlers and free vpci related structures. */ void vpci_deassign_device(struct pci_dev *pdev); =20 +int vpci_reinit_ext_capabilities(struct pci_dev *pdev); + /* 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, @@ -202,6 +204,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;