File 24888-pci-release-devices.patch of Package xen

References: bnc#744771

# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1330080392 -3600
# Node ID 71159fb049f253030c3820c260d092d4aec6b166
# Parent  35d855e520038bf5814f53d105dc4adf58a670f2
passthrough: release assigned PCI devices earlier during domain shutdown

At least with xend, where there's not even a tool stack side attempt to
de-assign devices during domain shutdown, this allows immediate re-
starts of a domain to work reliably. (There's no apparent reason why
c/s 18010:c1577f094ae4 chose to put this in the asynchronous part of
domain destruction).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>

# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# Date 1331114358 -3600
# Node ID f234e34ea28f753bba92980f367cf545666d69a1
# Parent  e0d944b501512fe3b9866f79e95ad0f29cd5caca
passthrough: fix domain ref leak after 24888:71159fb049f2

As pointed out by Keir.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>

--- a/xen/arch/ia64/xen/dom0_ops.c
+++ b/xen/arch/ia64/xen/dom0_ops.c
@@ -330,10 +330,13 @@ long arch_do_domctl(xen_domctl_t *op, XE
             break;
 
         ret = -EINVAL;
-        if ( unlikely((d = get_domain_by_id(op->domain)) == NULL) )
+        if ( unlikely((d = get_domain_by_id(op->domain)) == NULL) ||
+             unlikely(d->is_dying) )
         {
             gdprintk(XENLOG_ERR,
                 "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n");
+            if ( d )
+                put_domain(d);
             break;
         }
         bus = (op->u.assign_device.machine_bdf >> 16) & 0xff;
@@ -344,6 +347,7 @@ long arch_do_domctl(xen_domctl_t *op, XE
             gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
                      "%x:%x.%x already assigned, or non-existent\n",
                      bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+            put_domain(d);
             break;
         }
 
--- a/xen/arch/ia64/xen/domain.c
+++ b/xen/arch/ia64/xen/domain.c
@@ -671,10 +671,8 @@ void arch_domain_destroy(struct domain *
 		free_xenheap_pages(d->shared_info,
 				   get_order_from_shift(XSI_SHIFT));
 
-	if ( iommu_enabled && need_iommu(d) )	{
-		pci_release_devices(d);
+	if ( iommu_enabled && need_iommu(d) )
 		iommu_domain_destroy(d);
-	}
 
 	tlb_track_destroy(d);
 
@@ -1719,6 +1717,8 @@ int domain_relinquish_resources(struct d
 
 	switch (d->arch.relres) {
 	case RELRES_not_started:
+		pci_release_devices(d);
+
 		/* Relinquish guest resources for VT-i domain. */
 		if (is_hvm_domain(d))
 			vmx_relinquish_guest_resources(d);
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -607,7 +607,6 @@ void arch_domain_destroy(struct domain *
         hvm_domain_destroy(d);
 
     vmce_destroy_msr(d);
-    pci_release_devices(d);
     free_domain_pirqs(d);
     if ( !is_idle_domain(d) )
         iommu_domain_destroy(d);
@@ -1956,6 +1955,8 @@ int domain_relinquish_resources(struct d
     switch ( d->arch.relmem )
     {
     case RELMEM_not_started:
+        pci_release_devices(d);
+
         /* Tear down paging-assistance stuff. */
         paging_teardown(d);
 
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -828,10 +828,13 @@ long arch_do_domctl(
             break;
 
         ret = -EINVAL;
-        if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) )
+        if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ||
+             unlikely(d->is_dying) )
         {
             gdprintk(XENLOG_ERR,
                 "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n");
+            if ( d )
+                goto assign_device_out;
             break;
         }
 
openSUSE Build Service is sponsored by