|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2.1 2/2] vpci/msix: fix PBA accesses
On 26.02.2022 11:05, Roger Pau Monne wrote:
> --- a/xen/drivers/vpci/msix.c
> +++ b/xen/drivers/vpci/msix.c
> @@ -198,8 +198,13 @@ static int cf_check msix_read(
> if ( !access_allowed(msix->pdev, addr, len) )
> return X86EMUL_OKAY;
>
> + spin_lock(&msix->pdev->vpci->lock);
> if ( VMSIX_ADDR_IN_RANGE(addr, msix->pdev->vpci, VPCI_MSIX_PBA) )
> {
> + struct vpci *vpci = msix->pdev->vpci;
> + paddr_t base = vmsix_table_addr(vpci, VPCI_MSIX_PBA);
> + unsigned int idx = addr - base;
> +
> /*
> * Access to PBA.
> *
> @@ -207,25 +212,43 @@ static int cf_check msix_read(
> * guest address space. If this changes the address will need to be
> * translated.
> */
> +
> + if ( !msix->pba )
> + {
> + msix->pba = ioremap(base, vmsix_table_size(vpci, VPCI_MSIX_PBA));
> + if ( !msix->pba )
> + {
> + /*
> + * If unable to map the PBA return all 1s (all pending): it's
> + * likely better to trigger spurious events than drop them.
> + */
> + spin_unlock(&vpci->lock);
> + gprintk(XENLOG_WARNING,
> + "%pp: unable to map MSI-X PBA, report all pending\n",
> + msix->pdev);
> + return X86EMUL_OKAY;
Hmm, this may report more set bits than there are vectors. Which is
probably fine, but the comment may want adjusting a little to make
clear this is understood and meant to be that way.
> + }
> + }
Imo it would make sense to limit the locked region to around just this
check-and-map logic. There's no need for ...
> switch ( len )
> {
> case 4:
> - *data = readl(addr);
> + *data = readl(msix->pba + idx);
> break;
>
> case 8:
> - *data = readq(addr);
> + *data = readq(msix->pba + idx);
> break;
>
> default:
> ASSERT_UNREACHABLE();
> break;
> }
> + spin_unlock(&vpci->lock);
... the actual access to happen under lock, as you remove the mapping
only when the device is being removed. I'm inclined to suggest making
a helper function, which does an unlocked check, then the ioremap(),
then takes the lock and re-checks whether the field's still NULL, and
either installs the mapping or (after unlocking) iounmap()s it.
> --- a/xen/include/xen/vpci.h
> +++ b/xen/include/xen/vpci.h
> @@ -127,6 +127,8 @@ struct vpci {
> bool enabled : 1;
> /* Masked? */
> bool masked : 1;
> + /* PBA map */
> + void *pba;
Here (and elsewhere as/if applicable) you want to add __iomem, even
if this is merely for documentation purposes right now.
I think you did mention this elsewhere: Don't we also need to deal
with accesses to MMIO covered by the same BAR / page, but falling
outside of the MSI-X table and PBA?
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |