From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Jiqian Chen <Jiqian.Chen@amd.com>
Cc: xen-devel@lists.xenproject.org, Huang Rui <ray.huang@amd.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Anthony PERARD <anthony.perard@vates.tech>,
Michal Orzel <michal.orzel@amd.com>,
Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
Stefano Stabellini <sstabellini@kernel.org>
Subject: Re: [PATCH v3 05/11] vpci: Refactor REGISTER_VPCI_INIT
Date: Tue, 6 May 2025 16:37:10 +0200 [thread overview]
Message-ID: <aBoelpSu4xmJH2Eo@macbook.lan> (raw)
In-Reply-To: <20250421061903.1542652-6-Jiqian.Chen@amd.com>
On Mon, Apr 21, 2025 at 02:18:57PM +0800, Jiqian Chen wrote:
> Refactor REGISTER_VPCI_INIT to contain more capability specific
> information, this is benifit for follow-on changes to hide capability
> which initialization fails.
>
> What's more, change the definition of init_header() since it is
> not a capability and it is needed for all devices' PCI config space.
>
> Note:
> Call vpci_make_msix_hole() in the end of init_msix() since the
> change of sequence of init_header() and init_msix().
> The fini hook will be implemented in follow-on changes.
I would maybe add that the cleanup hook is also added in this change,
even if it's still unused. Further changes will make use of it.
>
> Signed-off-by: Jiqian Chen <Jiqian.Chen@amd.com>
> ---
> cc: "Roger Pau Monné" <roger.pau@citrix.com>
> cc: Andrew Cooper <andrew.cooper3@citrix.com>
> cc: Anthony PERARD <anthony.perard@vates.tech>
> cc: Michal Orzel <michal.orzel@amd.com>
> cc: Jan Beulich <jbeulich@suse.com>
> cc: Julien Grall <julien@xen.org>
> cc: Stefano Stabellini <sstabellini@kernel.org>
> ---
> v2->v3 changes:
> * This is separated from patch "vpci: Hide capability when it fails to initialize" of v2.
> * Delete __maybe_unused attribute of "out" in function vpci_assign_devic().
> * Rename REGISTER_VPCI_EXTEND_CAP to REGISTER_VPCI_EXTENDED_CAP.
>
> v1->v2 changes:
> * Removed the "priorities" of initializing capabilities since it isn't used anymore.
> * Added new function vpci_capability_mask() and vpci_ext_capability_mask() to remove failed capability from list.
> * Called vpci_make_msix_hole() in the end of init_msix().
>
> Best regards,
> Jiqian Chen.
> ---
> xen/drivers/vpci/header.c | 3 +--
> xen/drivers/vpci/msi.c | 2 +-
> xen/drivers/vpci/msix.c | 8 +++++--
> xen/drivers/vpci/rebar.c | 2 +-
> xen/drivers/vpci/vpci.c | 48 +++++++++++++++++++++++++++++++--------
> xen/include/xen/vpci.h | 28 ++++++++++++++++-------
> xen/include/xen/xen.lds.h | 2 +-
> 7 files changed, 68 insertions(+), 25 deletions(-)
>
> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
> index ee94ad8e5037..afe4bcdfcb30 100644
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -842,7 +842,7 @@ static int vpci_init_ext_capability_list(struct pci_dev *pdev)
> return 0;
> }
>
> -static int cf_check init_header(struct pci_dev *pdev)
> +int vpci_init_header(struct pci_dev *pdev)
> {
> uint16_t cmd;
> uint64_t addr, size;
> @@ -1038,7 +1038,6 @@ static int cf_check init_header(struct pci_dev *pdev)
> pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd);
> return rc;
> }
> -REGISTER_VPCI_INIT(init_header, VPCI_PRIORITY_MIDDLE);
>
> /*
> * Local variables:
> diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
> index 66e5a8a116be..ea7dc0c060ea 100644
> --- a/xen/drivers/vpci/msi.c
> +++ b/xen/drivers/vpci/msi.c
> @@ -270,7 +270,7 @@ static int cf_check init_msi(struct pci_dev *pdev)
>
> return 0;
> }
> -REGISTER_VPCI_INIT(init_msi, VPCI_PRIORITY_LOW);
> +REGISTER_VPCI_LEGACY_CAP(PCI_CAP_ID_MSI, init_msi, NULL);
>
> void vpci_dump_msi(void)
> {
> diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c
> index 6bd8c55bb48e..0228ffd9fda9 100644
> --- a/xen/drivers/vpci/msix.c
> +++ b/xen/drivers/vpci/msix.c
> @@ -751,9 +751,13 @@ static int cf_check init_msix(struct pci_dev *pdev)
> pdev->vpci->msix = msix;
> list_add(&msix->next, &d->arch.hvm.msix_tables);
>
> - return 0;
> + spin_lock(&pdev->vpci->lock);
> + rc = vpci_make_msix_hole(pdev);
> + spin_unlock(&pdev->vpci->lock);
> +
> + return rc;
> }
> -REGISTER_VPCI_INIT(init_msix, VPCI_PRIORITY_HIGH);
> +REGISTER_VPCI_LEGACY_CAP(PCI_CAP_ID_MSIX, init_msix, NULL);
>
> /*
> * Local variables:
> diff --git a/xen/drivers/vpci/rebar.c b/xen/drivers/vpci/rebar.c
> index 793937449af7..026f8f7972d9 100644
> --- a/xen/drivers/vpci/rebar.c
> +++ b/xen/drivers/vpci/rebar.c
> @@ -118,7 +118,7 @@ static int cf_check init_rebar(struct pci_dev *pdev)
>
> return 0;
> }
> -REGISTER_VPCI_INIT(init_rebar, VPCI_PRIORITY_LOW);
> +REGISTER_VPCI_EXTENDED_CAP(PCI_EXT_CAP_ID_REBAR, init_rebar, NULL);
>
> /*
> * Local variables:
> diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
> index 3349b98389b8..5474b66668c1 100644
> --- a/xen/drivers/vpci/vpci.c
> +++ b/xen/drivers/vpci/vpci.c
> @@ -36,8 +36,8 @@ struct vpci_register {
> };
>
> #ifdef __XEN__
> -extern vpci_register_init_t *const __start_vpci_array[];
> -extern vpci_register_init_t *const __end_vpci_array[];
> +extern vpci_capability_t *const __start_vpci_array[];
> +extern vpci_capability_t *const __end_vpci_array[];
> #define NUM_VPCI_INIT (__end_vpci_array - __start_vpci_array)
>
> #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
> @@ -83,6 +83,36 @@ static int assign_virtual_sbdf(struct pci_dev *pdev)
>
> #endif /* CONFIG_HAS_VPCI_GUEST_SUPPORT */
>
> +static int vpci_init_capabilities(struct pci_dev *pdev)
> +{
> + for ( unsigned int i = 0; i < NUM_VPCI_INIT; i++ )
> + {
> + const vpci_capability_t *capability = __start_vpci_array[i];
> + const unsigned int cap = capability->id;
> + const bool is_ext = capability->is_ext;
> + unsigned int pos;
> + int rc;
> +
> + if ( !is_hardware_domain(pdev->domain) && is_ext )
> + continue;
> +
> + if ( !is_ext )
> + pos = pci_find_cap_offset(pdev->sbdf, cap);
> + else
> + pos = pci_find_ext_capability(pdev->sbdf, cap);
> +
> + if ( !pos || !capability->init )
Isn't it bogus to have a vpci_capability_t entry with a NULL init
function?
> + continue;
> +
> + rc = capability->init(pdev);
> +
I wouldn't add a newline between the function call and checking the
return value, but that's just my taste.
> + if ( rc )
> + return rc;
> + }
> +
> + return 0;
> +}
> +
> void vpci_deassign_device(struct pci_dev *pdev)
> {
> unsigned int i;
> @@ -128,7 +158,6 @@ void vpci_deassign_device(struct pci_dev *pdev)
>
> int vpci_assign_device(struct pci_dev *pdev)
> {
> - unsigned int i;
> const unsigned long *ro_map;
> int rc = 0;
>
> @@ -159,14 +188,13 @@ int vpci_assign_device(struct pci_dev *pdev)
> goto out;
> #endif
>
> - for ( i = 0; i < NUM_VPCI_INIT; i++ )
> - {
> - rc = __start_vpci_array[i](pdev);
> - if ( rc )
> - break;
> - }
> + rc = vpci_init_header(pdev);
> + if ( rc )
> + goto out;
> +
> + rc = vpci_init_capabilities(pdev);
>
> - out: __maybe_unused;
> + out:
> if ( rc )
> vpci_deassign_device(pdev);
>
> diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
> index 9d47b8c1a50e..8e815b418b7d 100644
> --- a/xen/include/xen/vpci.h
> +++ b/xen/include/xen/vpci.h
> @@ -13,11 +13,12 @@ typedef uint32_t vpci_read_t(const struct pci_dev *pdev, unsigned int reg,
> typedef void vpci_write_t(const struct pci_dev *pdev, unsigned int reg,
> uint32_t val, void *data);
>
> -typedef int vpci_register_init_t(struct pci_dev *dev);
> -
> -#define VPCI_PRIORITY_HIGH "1"
> -#define VPCI_PRIORITY_MIDDLE "5"
> -#define VPCI_PRIORITY_LOW "9"
> +typedef struct {
> + unsigned int id;
> + bool is_ext;
> + int (*init)(struct pci_dev *pdev);
> + void (*fini)(struct pci_dev *pdev);
> +} vpci_capability_t;
>
> #define VPCI_ECAM_BDF(addr) (((addr) & 0x0ffff000) >> 12)
>
> @@ -29,9 +30,20 @@ typedef int vpci_register_init_t(struct pci_dev *dev);
> */
> #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1)
>
> -#define REGISTER_VPCI_INIT(x, p) \
> - static vpci_register_init_t *const x##_entry \
> - __used_section(".data.vpci." p) = (x)
> +#define REGISTER_VPCI_CAP(cap, x, y, ext) \
x and y are not very helpful identifier names, better use some more
descriptive naming, init and fini? Same below.
> + static vpci_capability_t x##_t = { \
> + .id = (cap), \
> + .init = (x), \
> + .fini = (y), \
> + .is_ext = (ext), \
> + }; \
> + static vpci_capability_t *const x##_entry \
> + __used_section(".data.vpci.") = &(x##_t)
> +
> +#define REGISTER_VPCI_LEGACY_CAP(cap, x, y) REGISTER_VPCI_CAP(cap, x, y, false)
> +#define REGISTER_VPCI_EXTENDED_CAP(cap, x, y) REGISTER_VPCI_CAP(cap, x, y, true)
> +
> +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);
> diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h
> index 16a9b1ba03db..c73222112dd3 100644
> --- a/xen/include/xen/xen.lds.h
> +++ b/xen/include/xen/xen.lds.h
> @@ -187,7 +187,7 @@
> #define VPCI_ARRAY \
> . = ALIGN(POINTER_ALIGN); \
> __start_vpci_array = .; \
> - *(SORT(.data.vpci.*)) \
> + *(.data.vpci.*) \
Aside from Jan comment, please keep the '\' aligned with the others on
the block.
Thanks, Roger.
next prev parent reply other threads:[~2025-05-06 14:37 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-21 6:18 [PATCH v3 00/11] Support hiding capability when its initialization fails Jiqian Chen
2025-04-21 6:18 ` [PATCH v3 01/11] vpci/header: Move emulating cap list logic into new function Jiqian Chen
2025-04-29 7:10 ` Chen, Jiqian
2025-05-06 13:30 ` Roger Pau Monné
2025-04-21 6:18 ` [PATCH v3 02/11] driver/pci: Get next capability without passing caps Jiqian Chen
2025-04-22 15:59 ` Jan Beulich
2025-04-23 3:13 ` Chen, Jiqian
2025-04-21 6:18 ` [PATCH v3 03/11] vpci/header: Emulate legacy capability list for dom0 Jiqian Chen
2025-04-22 16:01 ` Jan Beulich
2025-04-23 3:31 ` Chen, Jiqian
2025-04-23 7:27 ` Jan Beulich
2025-05-06 13:47 ` Roger Pau Monné
2025-05-06 13:50 ` Roger Pau Monné
2025-05-07 2:46 ` Chen, Jiqian
2025-05-07 2:50 ` Chen, Jiqian
2025-05-07 7:49 ` Roger Pau Monné
2025-05-07 8:13 ` Chen, Jiqian
2025-04-21 6:18 ` [PATCH v3 04/11] vpci/header: Emulate extended " Jiqian Chen
2025-05-06 14:14 ` Roger Pau Monné
2025-05-07 3:32 ` Chen, Jiqian
2025-05-07 7:55 ` Roger Pau Monné
2025-04-21 6:18 ` [PATCH v3 05/11] vpci: Refactor REGISTER_VPCI_INIT Jiqian Chen
2025-04-22 16:03 ` Jan Beulich
2025-04-23 3:49 ` Chen, Jiqian
2025-04-23 7:36 ` Jan Beulich
2025-04-23 8:17 ` Chen, Jiqian
2025-05-06 14:37 ` Roger Pau Monné [this message]
2025-05-07 5:59 ` Chen, Jiqian
2025-05-07 8:04 ` Roger Pau Monné
2025-05-07 8:23 ` Chen, Jiqian
2025-04-21 6:18 ` [PATCH v3 06/11] vpci: Hide legacy capability when it fails to initialize Jiqian Chen
2025-05-06 16:00 ` Roger Pau Monné
2025-05-07 6:38 ` Chen, Jiqian
2025-05-07 8:07 ` Roger Pau Monné
2025-04-21 6:18 ` [PATCH v3 07/11] vpci: Hide extended " Jiqian Chen
2025-04-22 16:06 ` Jan Beulich
2025-05-08 9:16 ` Chen, Jiqian
2025-05-08 9:47 ` Roger Pau Monné
2025-05-06 16:21 ` Roger Pau Monné
2025-05-07 7:26 ` Chen, Jiqian
2025-05-07 8:09 ` Roger Pau Monné
2025-05-07 8:49 ` Chen, Jiqian
2025-05-07 9:05 ` Roger Pau Monné
2025-04-21 6:19 ` [PATCH v3 08/11] vpci: Refactor vpci_remove_register to remove matched registers Jiqian Chen
2025-05-06 16:29 ` Roger Pau Monné
2025-04-21 6:19 ` [PATCH v3 09/11] vpci/rebar: Remove registers when init_rebar() fails Jiqian Chen
2025-05-08 9:39 ` Roger Pau Monné
2025-05-09 5:27 ` Chen, Jiqian
2025-04-21 6:19 ` [PATCH v3 10/11] vpci/msi: Free MSI resources when init_msi() fails Jiqian Chen
2025-05-08 9:57 ` Roger Pau Monné
2025-04-21 6:19 ` [PATCH v3 11/11] vpci/msix: Add function to clean MSIX resources Jiqian Chen
2025-05-08 10:04 ` Roger Pau Monné
2025-05-09 5:45 ` Chen, Jiqian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aBoelpSu4xmJH2Eo@macbook.lan \
--to=roger.pau@citrix.com \
--cc=Jiqian.Chen@amd.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@vates.tech \
--cc=jbeulich@suse.com \
--cc=julien@xen.org \
--cc=michal.orzel@amd.com \
--cc=ray.huang@amd.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.