[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] vpci/header: Emulate legacy capability list for dom0
commit 4df04b27d372e0c9496de914ac5ec25cd861e18f Author: Jiqian Chen <Jiqian.Chen@xxxxxxx> AuthorDate: Wed Jun 11 11:05:03 2025 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Jun 11 11:05:03 2025 +0200 vpci/header: Emulate legacy capability list for dom0 Current logic of emulating legacy capability list is only for domU. So, expand it to emulate for dom0 too. Then it will be easy to hide a capability whose initialization fails in a function. And restrict adding PCI_STATUS register only for domU since dom0 has no limitation to access that register. Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/drivers/vpci/header.c | 39 ++++++++++++++++++++++++++------------- xen/drivers/vpci/vpci.c | 6 ++++++ xen/include/xen/vpci.h | 2 ++ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 0fb3cfa6a3..d26cbba08e 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -758,9 +758,9 @@ static int vpci_init_capability_list(struct pci_dev *pdev) { int rc; bool mask_cap_list = false; + bool is_hwdom = is_hardware_domain(pdev->domain); - if ( !is_hardware_domain(pdev->domain) && - pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST ) + 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 = 48; @@ -768,12 +768,18 @@ static int vpci_init_capability_list(struct pci_dev *pdev) 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 = is_hwdom ? 0 : ARRAY_SIZE(supported_caps); next = pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST, - supported_caps, - ARRAY_SIZE(supported_caps), &ttl); + supported_caps, n, &ttl); - rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, + rc = vpci_add_register(pdev->vpci, vpci_read_val, + is_hwdom ? vpci_hw_write8 : NULL, PCI_CAPABILITY_LIST, 1, (void *)(uintptr_t)next); if ( rc ) @@ -781,7 +787,7 @@ static int vpci_init_capability_list(struct pci_dev *pdev) next &= ~3; - if ( !next ) + 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 @@ -795,15 +801,18 @@ static int vpci_init_capability_list(struct pci_dev *pdev) next = pci_find_next_cap_ttl(pdev->sbdf, pos + PCI_CAP_LIST_NEXT, - supported_caps, - ARRAY_SIZE(supported_caps), &ttl); + supported_caps, n, &ttl); - rc = vpci_add_register(pdev->vpci, vpci_hw_read8, NULL, - pos + PCI_CAP_LIST_ID, 1, NULL); - if ( rc ) - return rc; + if ( !is_hwdom ) + { + rc = vpci_add_register(pdev->vpci, vpci_hw_read8, NULL, + pos + PCI_CAP_LIST_ID, 1, NULL); + if ( rc ) + return rc; + } - rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL, + rc = 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 ) @@ -813,6 +822,10 @@ static int vpci_init_capability_list(struct pci_dev *pdev) } } + /* 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_write16, PCI_STATUS, 2, NULL, diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c index d2f0f97e0a..09988f04c2 100644 --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -255,6 +255,12 @@ uint32_t cf_check vpci_hw_read32( return pci_conf_read32(pdev->sbdf, reg); } +void cf_check vpci_hw_write8( + const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data) +{ + pci_conf_write8(pdev->sbdf, reg, val); +} + void cf_check vpci_hw_write16( const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data) { diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index 475981cb81..fc8d5b470b 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -76,6 +76,8 @@ 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); -- generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |