[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4.1 3/4] x86/pt: enable binding of GSIs to a PVH Dom0
>>> On 02.06.17 at 15:58, <roger.pau@xxxxxxxxxx> wrote: > --- a/xen/drivers/passthrough/io.c > +++ b/xen/drivers/passthrough/io.c > @@ -164,6 +164,25 @@ static void pt_irq_time_out(void *data) > > spin_lock(&irq_map->dom->event_lock); > > + if ( irq_map->flags & HVM_IRQ_DPCI_IDENTITY_GSI ) > + { > + struct pirq *pirq = dpci_pirq(irq_map); This could (and hence should) be const. However, ... > + ASSERT(is_hardware_domain(irq_map->dom)); > + /* > + * Identity mapped, no need to iterate over the guest GSI list to > find > + * other pirqs sharing the same guest GSI. > + * > + * In the identity mapped case the EOI can also be done now, this way > + * the iteration over the list of domain pirqs is avoided. > + */ > + hvm_gsi_deassert(irq_map->dom, pirq->pirq); ... this is its only use, so I'm not convinced a local variable is needed at all. > @@ -274,10 +293,16 @@ int pt_irq_create_bind( > spin_lock(&d->event_lock); > > hvm_irq_dpci = domain_get_irq_dpci(d); > - if ( hvm_irq_dpci == NULL ) > + if ( hvm_irq_dpci == NULL && !is_hardware_domain(d) ) Would you mind at once switching to the shorter !hvm_irq_dpci (also further down), the more that you're using the inverse without " != NULL" elsewhere? > { > unsigned int i; > > + /* > + * NB: the hardware domain doesn't use a hvm_irq_dpci struct because > + * it's only allowed to identity map GSIs, and so the data contained > in > + * that struct (used to map guest GSIs into machine GSIs and perform > + * interrupt routing) it's completely useless to it. "is completely ..." > @@ -422,35 +447,52 @@ int pt_irq_create_bind( > case PT_IRQ_TYPE_PCI: > case PT_IRQ_TYPE_MSI_TRANSLATE: > { > - unsigned int bus = pt_irq_bind->u.pci.bus; > - unsigned int device = pt_irq_bind->u.pci.device; > - unsigned int intx = pt_irq_bind->u.pci.intx; > - unsigned int guest_gsi = hvm_pci_intx_gsi(device, intx); > - unsigned int link = hvm_pci_intx_link(device, intx); > - struct dev_intx_gsi_link *digl = xmalloc(struct dev_intx_gsi_link); > - struct hvm_girq_dpci_mapping *girq = > - xmalloc(struct hvm_girq_dpci_mapping); > + struct dev_intx_gsi_link *digl = NULL; > + struct hvm_girq_dpci_mapping *girq = NULL; > + unsigned int guest_gsi; > > - if ( !digl || !girq ) > + /* > + * Mapping GSIs for the hardware domain is different than doing it > for > + * an unpriviledged guest, the hardware domain is only allowed to > + * identity map GSIs, and as such all the data in the u.pci union is > + * discarded. > + */ > + if ( !is_hardware_domain(d) ) I think I did indicate before that it would feel more safe if you checked hvm_irq_dpci here (which is NULL if and only if d is hwdom). At the very least I'd expect a respective ASSERT() below (but I think the alternative condition here and ASSERT(is_hardware_domain(d)) in the "else" block would be better). > { > - spin_unlock(&d->event_lock); > - xfree(girq); > - xfree(digl); > - return -ENOMEM; > - } > + unsigned int link; > + > + digl = xmalloc(struct dev_intx_gsi_link); > + girq = xmalloc(struct hvm_girq_dpci_mapping); > > - hvm_irq_dpci->link_cnt[link]++; > + if ( !digl || !girq ) > + { > + spin_unlock(&d->event_lock); > + xfree(girq); > + xfree(digl); > + return -ENOMEM; > + } > + > + girq->bus = digl->bus = pt_irq_bind->u.pci.bus; > + girq->device = digl->device = pt_irq_bind->u.pci.device; > + girq->intx = digl->intx = pt_irq_bind->u.pci.intx; > + list_add_tail(&digl->list, &pirq_dpci->digl_list); > > - digl->bus = bus; > - digl->device = device; > - digl->intx = intx; > - list_add_tail(&digl->list, &pirq_dpci->digl_list); > + guest_gsi = hvm_pci_intx_gsi(digl->device, digl->intx); > + link = hvm_pci_intx_link(digl->device, digl->intx); > > - girq->bus = bus; > - girq->device = device; > - girq->intx = intx; > - girq->machine_gsi = pirq; > - list_add_tail(&girq->list, &hvm_irq_dpci->girq[guest_gsi]); > + hvm_irq_dpci->link_cnt[link]++; > + > + girq->machine_gsi = pirq; > + list_add_tail(&girq->list, &hvm_irq_dpci->girq[guest_gsi]); > + } > + else > + { > + /* MSI_TRANSLATE is not supported by the hardware domain. */ s/by/for/ ? > @@ -472,7 +514,28 @@ int pt_irq_create_bind( > pirq_dpci->flags = HVM_IRQ_DPCI_MAPPED | > HVM_IRQ_DPCI_MACH_PCI | > HVM_IRQ_DPCI_GUEST_PCI; > - share = BIND_PIRQ__WILL_SHARE; > + if ( !is_hardware_domain(d) ) > + share = BIND_PIRQ__WILL_SHARE; > + else > + { > + unsigned int pin; > + struct hvm_vioapic *vioapic = gsi_vioapic(d, guest_gsi, > + &pin); const > @@ -489,9 +552,16 @@ int pt_irq_create_bind( > * IRQ_GUEST is not set. As such we can reset 'dom' > directly. > */ > pirq_dpci->dom = NULL; > - list_del(&girq->list); > - list_del(&digl->list); > - hvm_irq_dpci->link_cnt[link]--; > + if ( girq || digl ) > + { > + unsigned int link; > + > + ASSERT(girq && digl); Perhaps even "ASSERT(girq && digl && hvm_irq_dpci)" or follow the model outlined above for consistency? > @@ -504,10 +574,17 @@ int pt_irq_create_bind( > spin_unlock(&d->event_lock); > > if ( iommu_verbose ) > - printk(XENLOG_G_INFO > - "d%d: bind: m_gsi=%u g_gsi=%u dev=%02x.%02x.%u intx=%u\n", > - d->domain_id, pirq, guest_gsi, bus, > - PCI_SLOT(device), PCI_FUNC(device), intx); > + { > + char buf[24] = ""; > + > + if ( !is_hardware_domain(d) ) > + snprintf(buf, ARRAY_SIZE(buf), " dev=%02x.%02x.%u intx=%u", > + digl->bus, PCI_SLOT(digl->device), > + PCI_FUNC(digl->device), digl->intx); Perhaps again better "if ( digl )". > @@ -696,7 +777,8 @@ int hvm_do_IRQ_dpci(struct domain *d, struct pirq *pirq) > struct hvm_irq_dpci *dpci = domain_get_irq_dpci(d); > struct hvm_pirq_dpci *pirq_dpci = pirq_dpci(pirq); > > - if ( !iommu_enabled || !dpci || !pirq_dpci || > + if ( !is_hvm_domain(d) || !iommu_enabled || > + (!is_hardware_domain(d) && !dpci) || !pirq_dpci || > !(pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) ) > return 0; So why again do we suddenly need !is_hvm_domain() here? With the name of the function there shouldn't be any caller invoking it for a PV guest. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |