# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1199965759 0
# Node ID 48c800d5a3718a4a8115c02fc0b76d16f85d35f8
# Parent 337dc1a3f7ca3663d7c057576acb293b08e7a70f
hvm: Fix evtchn-to-fake-pci interrupt propagation.
Previously the evtchn_upcall_pending flag would only ever be sampled
on VCPU0, possibly leading to long delays in deasserting the
fake-pci-device INTx line if the interrupt is actually delivered to
other than VCPU0.
Diagnosed by Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset: 16692:9865d5e82802fda2ac842c0c28a0833f2126551f
xen-unstable date: Tue Jan 08 15:55:29 2008 +0000
---
xen/arch/x86/hvm/irq.c | 35 +++++++++++++++++++++--------------
xen/arch/x86/hvm/svm/intr.c | 2 +-
xen/arch/x86/hvm/vmx/intr.c | 2 +-
xen/include/asm-x86/event.h | 7 ++++++-
xen/include/asm-x86/hvm/irq.h | 3 ++-
5 files changed, 31 insertions(+), 18 deletions(-)
diff -r 337dc1a3f7ca -r 48c800d5a371 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c Thu Jan 10 11:43:21 2008 +0000
+++ b/xen/arch/x86/hvm/irq.c Thu Jan 10 11:49:19 2008 +0000
@@ -125,17 +125,13 @@ void hvm_isa_irq_deassert(
spin_unlock(&d->arch.hvm_domain.irq_lock);
}
-void hvm_set_callback_irq_level(void)
-{
- struct vcpu *v = current;
+static void hvm_set_callback_irq_level(struct vcpu *v)
+{
struct domain *d = v->domain;
struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
unsigned int gsi, pdev, pintx, asserted;
- /* Fast lock-free tests. */
- if ( (v->vcpu_id != 0) ||
- (hvm_irq->callback_via_type == HVMIRQ_callback_none) )
- return;
+ ASSERT(v->vcpu_id == 0);
spin_lock(&d->arch.hvm_domain.irq_lock);
@@ -175,6 +171,22 @@ void hvm_set_callback_irq_level(void)
out:
spin_unlock(&d->arch.hvm_domain.irq_lock);
+}
+
+void hvm_maybe_deassert_evtchn_irq(void)
+{
+ struct domain *d = current->domain;
+ struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+
+ if ( hvm_irq->callback_via_asserted &&
+ !vcpu_info(d->vcpu[0], evtchn_upcall_pending) )
+ hvm_set_callback_irq_level(d->vcpu[0]);
+}
+
+void hvm_assert_evtchn_irq(struct vcpu *v)
+{
+ if ( v->vcpu_id == 0 )
+ hvm_set_callback_irq_level(v);
}
void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
@@ -314,15 +326,10 @@ int cpu_get_interrupt(struct vcpu *v, in
return -1;
}
-/*
- * TODO: 1. Should not need special treatment of event-channel events.
- * 2. Should take notice of interrupt shadows (or clear them).
- */
int hvm_local_events_need_delivery(struct vcpu *v)
{
- int pending;
-
- pending = (vcpu_info(v, evtchn_upcall_pending) || cpu_has_pending_irq(v));
+ int pending = cpu_has_pending_irq(v);
+
if ( unlikely(pending) )
pending = hvm_interrupts_enabled(v);
diff -r 337dc1a3f7ca -r 48c800d5a371 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Thu Jan 10 11:43:21 2008 +0000
+++ b/xen/arch/x86/hvm/svm/intr.c Thu Jan 10 11:49:19 2008 +0000
@@ -125,7 +125,7 @@ asmlinkage void svm_intr_assist(void)
/* Crank the handle on interrupt state and check for new interrrupts. */
pt_update_irq(v);
- hvm_set_callback_irq_level();
+ hvm_maybe_deassert_evtchn_irq();
if ( !cpu_has_pending_irq(v) )
goto out;
diff -r 337dc1a3f7ca -r 48c800d5a371 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c Thu Jan 10 11:43:21 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/intr.c Thu Jan 10 11:49:19 2008 +0000
@@ -110,7 +110,7 @@ asmlinkage void vmx_intr_assist(void)
pt_update_irq(v);
- hvm_set_callback_irq_level();
+ hvm_maybe_deassert_evtchn_irq();
update_tpr_threshold(vcpu_vlapic(v));
diff -r 337dc1a3f7ca -r 48c800d5a371 xen/include/asm-x86/event.h
--- a/xen/include/asm-x86/event.h Thu Jan 10 11:43:21 2008 +0000
+++ b/xen/include/asm-x86/event.h Thu Jan 10 11:49:19 2008 +0000
@@ -31,7 +31,12 @@ static inline void vcpu_kick(struct vcpu
static inline void vcpu_mark_events_pending(struct vcpu *v)
{
- if ( !test_and_set_bit(0, &vcpu_info(v, evtchn_upcall_pending)) )
+ if ( test_and_set_bit(0, &vcpu_info(v, evtchn_upcall_pending)) )
+ return;
+
+ if ( is_hvm_vcpu(v) )
+ hvm_assert_evtchn_irq(v);
+ else
vcpu_kick(v);
}
diff -r 337dc1a3f7ca -r 48c800d5a371 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h Thu Jan 10 11:43:21 2008 +0000
+++ b/xen/include/asm-x86/hvm/irq.h Thu Jan 10 11:49:19 2008 +0000
@@ -112,7 +112,8 @@ void hvm_isa_irq_deassert(
void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq);
-void hvm_set_callback_irq_level(void);
+void hvm_maybe_deassert_evtchn_irq(void);
+void hvm_assert_evtchn_irq(struct vcpu *v);
void hvm_set_callback_via(struct domain *d, uint64_t via);
int cpu_get_interrupt(struct vcpu *v, int *type);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|