vt-d: Do dpci eoi outside of irq_lock.

Deadlock may occur if do hvm_dpci_eoi() inside of irq_lock on MP
platform. For example, there are two physical cpus. If interrupt is
injected on cpu0, but vcpu is migrated to cpu1 and it does eoi inside
of irq_lock, then IPI will be issued to cpu0. At the same time, cpu0
may have disabled irq and is acquiring the same irq_lock. In addition,
current code cannot guarantee do hvm_dpci_eoi() inside of irq_lock
when timeout. This patch does hvm_dpci_eoi() outside of irq_lock, and
solves above problems.

Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
Signed-off-by: Weidong Han <weidong.han@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
Keir Fraser committed 2007-10-30 10:39:52 +00:00
1 parent dbda63b318
commit 06e3f8f276
5 files changed
+14 -16

No files matched your search

+2 -2
View File
@@ -26,7 +26,7 @@
#include <asm/hvm/domain.h>
#include <asm/hvm/support.h>
void __hvm_pci_intx_assert(
static void __hvm_pci_intx_assert(
struct domain *d, unsigned int device, unsigned int intx)
{
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
@@ -59,7 +59,7 @@ void hvm_pci_intx_assert(
spin_unlock(&d->arch.hvm_domain.irq_lock);
}
void __hvm_pci_intx_deassert(
static void __hvm_pci_intx_deassert(
struct domain *d, unsigned int device, unsigned int intx)
{
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+4
View File
@@ -459,7 +459,11 @@ void vioapic_update_EOI(struct domain *d, int vector)
ent->fields.remote_irr = 0;
if ( vtd_enabled )
{
spin_unlock(&d->arch.hvm_domain.irq_lock);
hvm_dpci_eoi(current->domain, gsi, ent);
spin_lock(&d->arch.hvm_domain.irq_lock);
}
if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
!ent->fields.mask &&
+1 -3
View File
@@ -145,8 +145,6 @@ void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
uint32_t device, intx, machine_gsi;
ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
if ( !vtd_enabled || (hvm_irq_dpci == NULL) ||
!hvm_irq_dpci->girq[guest_gsi].valid )
return;
@@ -157,7 +155,7 @@ void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
intx = hvm_irq_dpci->girq[guest_gsi].intx;
gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: device %x intx %x\n",
device, intx);
__hvm_pci_intx_deassert(d, device, intx);
hvm_pci_intx_deassert(d, device, intx);
if ( (ent == NULL) || !ent->fields.mask )
pirq_guest_eoi(d, machine_gsi);
}
+7 -7
View File
@@ -249,13 +249,13 @@ static void vpic_ioport_write(
vpic->isr &= ~(1 << irq);
if ( cmd == 7 )
vpic->priority_add = (irq + 1) & 7;
if ( vtd_enabled )
{
irq |= ((addr & 0xa0) == 0xa0) ? 8 : 0;
hvm_dpci_eoi(current->domain,
hvm_isa_irq_to_gsi(irq), NULL);
}
break;
/* Release lock and EOI the physical interrupt (if any). */
vpic_update_int_output(vpic);
vpic_unlock(vpic);
hvm_dpci_eoi(current->domain,
hvm_isa_irq_to_gsi((addr >> 7) ? (irq|8) : irq),
NULL);
return; /* bail immediately */
case 6: /* Set Priority */
vpic->priority_add = (val + 1) & 7;
break;
-4
View File
@@ -121,12 +121,8 @@ struct hvm_irq {
#define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
/* Modify state of a PCI INTx wire. */
void __hvm_pci_intx_assert(
struct domain *d, unsigned int device, unsigned int intx);
void hvm_pci_intx_assert(
struct domain *d, unsigned int device, unsigned int intx);
void __hvm_pci_intx_deassert(
struct domain *d, unsigned int device, unsigned int intx);
void hvm_pci_intx_deassert(
struct domain *d, unsigned int device, unsigned int intx);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.