[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v9 08/16] vpci/header: handle p2m range sets per BAR
On 8/29/23 19:19, Volodymyr Babchuk wrote: > diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c > index e96d7b2b37..3cc6a96849 100644 > --- a/xen/drivers/vpci/header.c > +++ b/xen/drivers/vpci/header.c > @@ -161,63 +161,101 @@ static void modify_decoding(const struct pci_dev > *pdev, uint16_t cmd, > > bool vpci_process_pending(struct vcpu *v) > { > - if ( v->vpci.mem ) > + struct pci_dev *pdev = v->vpci.pdev; > + struct map_data data = { > + .d = v->domain, > + .map = v->vpci.cmd & PCI_COMMAND_MEMORY, > + }; > + struct vpci_header *header = NULL; > + unsigned int i; > + > + if ( !pdev ) > + return false; > + > + read_lock(&v->domain->pci_lock); > + header = &pdev->vpci->header; > + for ( i = 0; i < ARRAY_SIZE(header->bars); i++ ) > { > - struct map_data data = { > - .d = v->domain, > - .map = v->vpci.cmd & PCI_COMMAND_MEMORY, > - }; > - int rc = rangeset_consume_ranges(v->vpci.mem, map_range, &data); > + struct vpci_bar *bar = &header->bars[i]; > + int rc; > + > + if ( rangeset_is_empty(bar->mem) ) > + continue; > + > + rc = rangeset_consume_ranges(bar->mem, map_range, &data); > > if ( rc == -ERESTART ) > + { > + read_unlock(&v->domain->pci_lock); > return true; > + } > > - write_lock(&v->domain->pci_lock); > - spin_lock(&v->vpci.pdev->vpci->lock); > - /* Disable memory decoding unconditionally on failure. */ > - modify_decoding(v->vpci.pdev, > - rc ? v->vpci.cmd & ~PCI_COMMAND_MEMORY : v->vpci.cmd, > - !rc && v->vpci.rom_only); > - spin_unlock(&v->vpci.pdev->vpci->lock); > - > - rangeset_destroy(v->vpci.mem); > - v->vpci.mem = NULL; > if ( rc ) > - /* > - * FIXME: in case of failure remove the device from the domain. > - * Note that there might still be leftover mappings. While this > is > - * safe for Dom0, for DomUs the domain will likely need to be > - * killed in order to avoid leaking stale p2m mappings on > - * failure. > - */ > - vpci_deassign_device(v->vpci.pdev); > - write_unlock(&v->domain->pci_lock); > + { > + spin_lock(&pdev->vpci->lock); > + /* Disable memory decoding unconditionally on failure. */ > + modify_decoding(pdev, v->vpci.cmd & ~PCI_COMMAND_MEMORY, > + false); > + spin_unlock(&pdev->vpci->lock); > + > + v->vpci.pdev = NULL; > + > + read_unlock(&v->domain->pci_lock); > + > + if ( is_hardware_domain(v->domain) ) > + { > + write_lock(&v->domain->pci_lock); > + vpci_deassign_device(v->vpci.pdev); s/v->vpci.pdev/pdev/ since v->vpci.pdev was assigned NULL a few lines earlier.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |