[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 1/3] xen/pt: fix some pass-thru devices don't work across reboot
>>> On 21.12.18 at 16:21, <chao.gao@xxxxxxxxx> wrote: > On Fri, Dec 21, 2018 at 03:13:50AM -0700, Jan Beulich wrote: >>>>> On 20.12.18 at 16:29, <chao.gao@xxxxxxxxx> wrote: >>> --- a/xen/drivers/passthrough/pci.c >>> +++ b/xen/drivers/passthrough/pci.c >>> @@ -1514,6 +1514,55 @@ static int assign_device(struct domain *d, u16 seg, >>> u8 > bus, u8 devfn, u32 flag) >>> return rc; >>> } >>> >>> +/* >>> + * Unmap established mappings between domain's pirq and device's MSI. >>> + * These mappings were set up by qemu/guest and are expected to be >>> + * destroyed when changing the device's ownership. >>> + */ >>> +static void pci_unmap_msi(struct pci_dev *pdev) >>> +{ >>> + struct msi_desc *entry; >>> + struct domain *d = pdev->domain; >>> + >>> + ASSERT(pcidevs_locked()); >>> + >>> + if ( !d ) >>> + return; >> >>Why? deassign_device() (the only caller) ought to guarantee this, >>due to its use of pci_get_pdev_by_domain(). I think this simply >>wants to be another ASSERT(), if anything at all. >> >>> + spin_lock(&d->event_lock); >>> + while ( (entry = list_first_entry_or_null(&pdev->msi_list, >>> + struct msi_desc, list)) != > NULL ) >>> + { >>> + struct pirq *info; >>> + int pirq = 0; >>> + unsigned int nr = entry->msi_attrib.type != PCI_CAP_ID_MSIX >>> + ? entry->msi.nvec : 1; >>> + >>> + while ( nr -- ) >> >>Stray blank. >> >>> + { >>> + struct hvm_pirq_dpci *pirq_dpci; >>> + >>> + pirq = domain_irq_to_pirq(d, entry[nr].irq); >>> + WARN_ON(pirq < 0); >>> + if ( pirq <= 0 ) >>> + continue; >>> + >>> + info = pirq_info(d, pirq); >>> + if ( !info ) >>> + continue; >>> + >>> + pirq_dpci = pirq_dpci(info); >>> + if ( pirq_dpci && >>> + (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) && >>> + (pirq_dpci->flags & HVM_IRQ_DPCI_GUEST_MSI) ) >>> + pt_irq_destroy_bind_msi(d, info); >>> + } >>> + if ( pirq > 0 ) >>> + unmap_domain_pirq(d, pirq); >> >>Can you guarantee that this function won't fail? Because if it >>does, I think you might end up in an infinite loop, because the > > Considering current code doesn't deal with remaining pirq, if we > failed to unmap some pirq here (remove all entries from the msi_list > here), it wouldn't be a big issue. Hence the real issue here is a > potential infinite loop. Then we can just use > list_for_each_entry_safe(...) to traverse msi_list to avoid infinite > loop. > >>entry doesn't always get removed from the list in error cases. >>Maybe unmap_domain_pirq() needs a "force" mode added, >>perhaps indirectly by way of passing "entry" into it (all other >>callers would pass NULL). > > Yes, it is viable. However, for this call site, unmap_domain_pirq() > would fail to remove an entry only if xsm_unmap_domain_irq() in > unmap_domain_pirq() failed. Can we expect that xsm_unmap_domain_irq() > would always succeed there? It would probably be a buggy policy, but we shouldn't crash/hang the hypervisor in such a case. > If the answer is yes, what needed is > another assertion rather than the "force" mode. Maybe we can > forcibly remove all entries still on the list after the loop. That's indeed a possible option. 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 |