[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 11/11] vpci/sriov: add support for SR-IOV capability
>>> On 17.07.18 at 11:48, <roger.pau@xxxxxxxxxx> wrote: > The current code detects enabling of the virtual functions feature and > automatically adds the VFs to the domain. It also detects enabling of > memory space and maps the VFs BARs into the domain p2m. Disabling of > the VF enable bit removes the devices and the BAR memory map from the > domain p2m. "The domain" is ambiguous here: DYM the domain owning the PF, or the (perhaps various) one(s) owning the VFs? From the code I guess the latter, but that doesn't really look correct. > @@ -500,6 +506,16 @@ static int init_bars(struct pci_dev *pdev) > }; > int rc; > > + if ( pdev->info.is_virtfn ) > + /* > + * No need to set traps for the command register or the BAR registers > + * because those are not used by VFs. Memory decoding and position of > + * the VF BARs is controlled from the PF. But iirc the BARs can be read and written (for sizing purposes at least), so I think you still need to handle accesses. > + * TODO: add DomU support for VFs. It's not clear to me whether this TODO is meant to cover the above. > +static void modify_memory_mapping(const struct pci_dev *pdev, unsigned int > pos, > + bool enable) > +{ > + const struct vpci_sriov *sriov = pdev->vpci->sriov; > + unsigned int i; > + int rc; > + > + if ( enable ) > + { > + struct pci_dev *pf_dev; > + > + pcidevs_lock(); > + /* > + * NB: a non-const pci_dev of the PF is needed in order to update > + * vf_rlen. > + */ > + pf_dev = pci_get_pdev(pdev->seg, pdev->bus, pdev->devfn); > + pcidevs_unlock(); > + ASSERT(pf_dev); ASSERT(pf_dev == pdev); ? > +static void control_write(const struct pci_dev *pdev, unsigned int reg, > + uint32_t val, void *data) > +{ > + struct vpci_sriov *sriov = data; > + unsigned int pos = reg - PCI_SRIOV_CTRL; > + uint16_t control = pci_conf_read16(pdev->seg, pdev->bus, > + PCI_SLOT(pdev->devfn), > + PCI_FUNC(pdev->devfn), > + pos + PCI_SRIOV_CTRL); > + bool enabled = control & PCI_SRIOV_CTRL_VFE; > + bool mem_enabled = control & PCI_SRIOV_CTRL_MSE; > + bool new_enabled = val & PCI_SRIOV_CTRL_VFE; > + bool new_mem_enabled = val & PCI_SRIOV_CTRL_MSE; > + > + if ( new_enabled != enabled ) > + { > + if ( new_enabled ) > + { > + struct callback_data *cb = xmalloc(struct callback_data); > + struct vcpu *curr = current; > + > + if ( !cb ) > + { > + gprintk(XENLOG_WARNING, "%04x:%02x:%02x.%u: " > + "unable to allocate memory for SR-IOV enable\n", > + pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), > + PCI_FUNC(pdev->devfn)); > + return; > + } > + > + /* > + * Only update the number of active VFs when enabling, when > + * disabling use the cached value in order to always remove the > + * same number of VFs that were active. > + */ > + sriov->num_vfs = pci_conf_read16(pdev->seg, pdev->bus, > + PCI_SLOT(pdev->devfn), > + PCI_FUNC(pdev->devfn), > + pos + PCI_SRIOV_NUM_VF); > + > + /* > + * NB: VFE needs to be enabled before calling pci_add_device so > Xen > + * can access the config space of VFs. > + */ > + pci_conf_write16(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), > + PCI_FUNC(pdev->devfn), reg, > + control | PCI_SRIOV_CTRL_VFE); > + > + /* > + * The spec states that the software must wait at least 100ms > + * before attempting to access VF registers when enabling virtual > + * functions on the PF. > + */ > + cb->pdev = pdev; > + cb->sriov = sriov; > + cb->pos = pos; > + cb->value = val; > + cb->new_enabled = new_enabled; > + cb->new_mem_enabled = new_mem_enabled; > + curr->vpci.task = WAIT; > + curr->vpci.wait.callback = enable_callback; > + curr->vpci.wait.data = cb; > + curr->vpci.wait.end = get_cycles() + 100 * cpu_khz; > + return; Not sure whether to better ask the question here or for the previous patch: Isn't this WAIT mechanism leading to the guest actually spinning? We certainly don't want this for a 100ms period. > +static void teardown_sriov(struct pci_dev *pdev) > +{ > + if ( pdev->vpci->sriov ) > + { > + /* TODO: removing PFs is not currently supported. */ > + ASSERT_UNREACHABLE(); Irrespective of the TODO I think it would be nice if this didn't lead to a host crash. > --- a/xen/drivers/vpci/vpci.c > +++ b/xen/drivers/vpci/vpci.c > @@ -459,10 +459,14 @@ void vpci_write(pci_sbdf_t sbdf, unsigned int reg, > unsigned int size, > return; > } > > - spin_lock(&pdev->vpci_lock); > + /* > + * NB: use the recursive variant here so that mapping an unmapping of the > + * VF vars works correctly and can recursively take the PF lock. > + */ > + spin_lock_recursive(&pdev->vpci_lock); > if ( !pdev->vpci ) > { > - spin_unlock(&pdev->vpci_lock); > + spin_unlock_recursive(&pdev->vpci_lock); Wouldn't it make sense to split out the locking changes, or do the conversion right in patch 1 (with a suitable explanation)? > @@ -144,6 +143,11 @@ struct vpci { > struct vpci_arch_msix_entry arch; > } entries[]; > } *msix; > + > + struct vpci_sriov { > + uint16_t num_vfs; Any particular reason for this to be uint16_t? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |