[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v5 11/11] vpci/msix: add MSI-X handlers



On Mon, Aug 14, 2017 at 03:28:50PM +0100, Roger Pau Monne wrote:
[...]
> +static void vpci_msix_control_write(struct pci_dev *pdev, unsigned int reg,
> +                                    uint32_t val, void *data)
> +{
> +    uint8_t seg = pdev->seg, bus = pdev->bus;
> +    uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
> +    struct vpci_msix *msix = data;
> +    bool new_masked, new_enabled;
> +
> +    new_masked = val & PCI_MSIX_FLAGS_MASKALL;
> +    new_enabled = val & PCI_MSIX_FLAGS_ENABLE;
> +
> +    /*
> +     * According to the PCI 3.0 specification, switching the enable bit
> +     * to 1 or the function mask bit to 0 should cause all the cached
> +     * addresses and data fields to be recalculated. Xen implements this
> +     * as disabling and enabling the entries.
> +     *
> +     * Note that the disable/enable sequence is only performed when the
> +     * guest has written to the entry (ie: updated field set).
> +     */
> +    if ( new_enabled && !new_masked && (!msix->enabled || msix->masked) )
> +    {
> +        paddr_t table_base = pdev->vpci->header.bars[msix->table.bir].addr;
> +        unsigned int i;
> +        int rc;
> +
> +        for ( i = 0; i < msix->max_entries; i++ )
> +        {
> +            if ( msix->entries[i].masked || !msix->entries[i].updated )
> +                continue;
> +
> +            rc = vpci_msix_arch_disable(&msix->entries[i].arch, pdev);
> +            if ( rc )
> +            {
> +                gdprintk(XENLOG_ERR,
> +                         "%04x:%02x:%02x.%u: unable to disable entry %u: 
> %d\n",
> +                         seg, bus, slot, func, msix->entries[i].nr, rc);
> +                return;
> +            }
> +
> +            rc = vpci_msix_arch_enable(&msix->entries[i].arch, pdev,
> +                                       msix->entries[i].addr,
> +                                       msix->entries[i].data,
> +                                       msix->entries[i].nr, table_base);
> +            if ( rc )
> +            {
> +                gdprintk(XENLOG_ERR,
> +                         "%04x:%02x:%02x.%u: unable to enable entry %u: 
> %d\n",
> +                         seg, bus, slot, func, msix->entries[i].nr, rc);
> +                /* Entry is likely not configured, skip it. */
> +                continue;
> +            }
> +
> +            /*
> +             * At this point the PIRQ is still masked. Unmask it, or else the
> +             * guest won't receive interrupts. This is due to the
> +             * disable/enable sequence performed above.
> +             */
> +            vpci_msix_arch_mask(&msix->entries[i].arch, pdev, false);
> +
> +            msix->entries[i].updated = false;
> +        }
> +    }

I've realized that this function is missing the unmapping/unbinding of
PIRQs when the guest disables MSIX. I've added this now and will be
part of the next iteration.

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.