aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vpic.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-10-30 10:39:52 +0000
committerKeir Fraser <keir@xensource.com>2007-10-30 10:39:52 +0000
commit06e3f8f27662a8c1af0a4a43558a1dac65c2a97b (patch)
tree7730be68beaeba6b22e131fc5e3361692542b08a /xen/arch/x86/hvm/vpic.c
parentdbda63b318ad6a16e20ba8d934645799d3984593 (diff)
downloadxen-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.c14
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;