aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-05-08 11:50:12 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-05-08 11:50:12 +0100
commita5db2986d47fafc5e62f992616f057bfa43015d9 (patch)
tree9c1ab5e139540d127637a6666ac8acf9b47dd568 /xen
parent727a00e80e581ee15ea2b7caea3fe27c415164f5 (diff)
downloadxen-a5db2986d47fafc5e62f992616f057bfa43015d9.tar.gz
xen-a5db2986d47fafc5e62f992616f057bfa43015d9.tar.bz2
xen-a5db2986d47fafc5e62f992616f057bfa43015d9.zip
x86 hvm: hvm_set_callback_irq_level() must not be called in IRQ
context or with IRQs disabled. Ensure this by deferring to tasklet (softirq) context if required. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/x86/hvm/hvm.c5
-rw-r--r--xen/arch/x86/hvm/irq.c12
-rw-r--r--xen/include/asm-x86/hvm/vcpu.h2
3 files changed, 17 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index a2c23e09f1..000a70d9ac 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -697,6 +697,10 @@ int hvm_vcpu_initialise(struct vcpu *v)
if ( rc != 0 )
goto fail3;
+ tasklet_init(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet,
+ (void(*)(unsigned long))hvm_assert_evtchn_irq,
+ (unsigned long)v);
+
v->arch.guest_context.user_regs.eflags = 2;
if ( v->vcpu_id == 0 )
@@ -726,6 +730,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
void hvm_vcpu_destroy(struct vcpu *v)
{
+ tasklet_kill(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet);
hvm_vcpu_cacheattr_destroy(v);
vlapic_destroy(v);
hvm_funcs.vcpu_destroy(v);
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index 97eb25f9cb..bd2f145921 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -185,8 +185,16 @@ void hvm_maybe_deassert_evtchn_irq(void)
void hvm_assert_evtchn_irq(struct vcpu *v)
{
- if ( v->vcpu_id == 0 )
- hvm_set_callback_irq_level(v);
+ if ( v->vcpu_id != 0 )
+ return;
+
+ if ( unlikely(in_irq() || !local_irq_is_enabled()) )
+ {
+ tasklet_schedule(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet);
+ return;
+ }
+
+ hvm_set_callback_irq_level(v);
}
void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
index faea392f92..cd24177232 100644
--- a/xen/include/asm-x86/hvm/vcpu.h
+++ b/xen/include/asm-x86/hvm/vcpu.h
@@ -66,6 +66,8 @@ struct hvm_vcpu {
struct arch_svm_struct svm;
} u;
+ struct tasklet assert_evtchn_irq_tasklet;
+
struct mtrr_state mtrr;
u64 pat_cr;