diff options
author | Keir Fraser <keir@xensource.com> | 2007-10-30 10:39:52 +0000 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-10-30 10:39:52 +0000 |
commit | 06e3f8f27662a8c1af0a4a43558a1dac65c2a97b (patch) | |
tree | 7730be68beaeba6b22e131fc5e3361692542b08a /xen/arch/x86/hvm/vpic.c | |
parent | dbda63b318ad6a16e20ba8d934645799d3984593 (diff) | |
download | xen-06e3f8f27662a8c1af0a4a43558a1dac65c2a97b.tar.gz xen-06e3f8f27662a8c1af0a4a43558a1dac65c2a97b.tar.bz2 xen-06e3f8f27662a8c1af0a4a43558a1dac65c2a97b.zip |
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>
Diffstat (limited to 'xen/arch/x86/hvm/vpic.c')
-rw-r--r-- | xen/arch/x86/hvm/vpic.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/xen/arch/x86/hvm/vpic.c b/xen/arch/x86/hvm/vpic.c index 161129a97f..4a3fc5ae5a 100644 --- a/xen/arch/x86/hvm/vpic.c +++ b/xen/arch/x86/hvm/vpic.c @@ -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; |