From: "Jan Beulich" Subject: [PATCH] VT-d: check return value of pirq_guest_bind() Date: Tue, 09 Dec 2008 10:24:09 +0000 Message-ID: <493E5559.76E4.0078.0@novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Return-path: Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Weidong Han List-Id: xen-devel@lists.xenproject.org The eliminates a hypervisor crash when the respective domain dies or gets the device hot removed. Signed-off-by: Jan Beulich Reviewed-by: Weidong Han Index: 2008-11-20/xen/drivers/passthrough/io.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2008-11-20.orig/xen/drivers/passthrough/io.c 2008-12-04 = 12:23:07.000000000 +0100 +++ 2008-11-20/xen/drivers/passthrough/io.c 2008-12-04 12:35:10.0000000= 00 +0100 @@ -60,7 +60,7 @@ int pt_irq_create_bind_vtd( uint32_t machine_gsi, guest_gsi; uint32_t device, intx, link; struct dev_intx_gsi_link *digl; - int pirq =3D pt_irq_bind->machine_irq; + int rc, pirq =3D pt_irq_bind->machine_irq; =20 if ( pirq < 0 || pirq >=3D NR_IRQS ) return -EINVAL; @@ -98,7 +98,17 @@ int pt_irq_create_bind_vtd( hvm_irq_dpci->mirq[pirq].gmsi.gflags =3D pt_irq_bind->u.msi.gf= lags; hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] =3D = pirq; /* bind after hvm_irq_dpci is setup to avoid race with irq = handler*/ - pirq_guest_bind(d->vcpu[0], pirq, 0); + rc =3D pirq_guest_bind(d->vcpu[0], pirq, 0); + if ( unlikely(rc) ) + { + hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] =3D = 0; + hvm_irq_dpci->mirq[pirq].gmsi.gflags =3D 0; + hvm_irq_dpci->mirq[pirq].gmsi.gvec =3D 0; + clear_bit(_HVM_IRQ_DPCI_MSI, &hvm_irq_dpci->mirq[pirq].fla= gs); + clear_bit(pirq, hvm_irq_dpci->mapping); + spin_unlock(&d->event_lock); + return rc; + } } else if (hvm_irq_dpci->mirq[pirq].gmsi.gvec !=3D pt_irq_bind->u.ms= i.gvec ||hvm_irq_dpci->msi_gvec_pirq[pt_irq_bind->u.msi.gvec] = !=3D pirq) @@ -139,13 +149,30 @@ int pt_irq_create_bind_vtd( /* Bind the same mirq once in the same domain */ if ( !test_and_set_bit(machine_gsi, hvm_irq_dpci->mapping)) { + unsigned int vector =3D domain_irq_to_vector(d, machine_gsi); + hvm_irq_dpci->mirq[machine_gsi].dom =3D d; =20 /* Init timer before binding */ - init_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, = machine_gsi)], + init_timer(&hvm_irq_dpci->hvm_timer[vector], pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], = 0); /* Deal with gsi for legacy devices */ - pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE= ); + rc =3D pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WIL= L_SHARE); + if ( unlikely(rc) ) + { + kill_timer(&hvm_irq_dpci->hvm_timer[vector]); + hvm_irq_dpci->mirq[machine_gsi].dom =3D NULL; + clear_bit(machine_gsi, hvm_irq_dpci->mapping); + hvm_irq_dpci->girq[guest_gsi].machine_gsi =3D 0; + hvm_irq_dpci->girq[guest_gsi].intx =3D 0; + hvm_irq_dpci->girq[guest_gsi].device =3D 0; + hvm_irq_dpci->girq[guest_gsi].valid =3D 0; + list_del(&digl->list); + hvm_irq_dpci->link_cnt[link]--; + spin_unlock(&d->event_lock); + xfree(digl); + return rc; + } } =20 gdprintk(XENLOG_INFO VTDPREFIX,