diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2012-07-09 16:42:32 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-07-10 11:31:09 +0300 |
commit | 5d62c43a17edaa7f6a88821c9086e6c8e0e5327d (patch) | |
tree | 3a87b9355b9fce43838e803a38591bb0e4bb908e /cpu-exec.c | |
parent | a94820ddc36f8c452b37f9dcb323f55ffdbc75f9 (diff) | |
download | qemu-5d62c43a17edaa7f6a88821c9086e6c8e0e5327d.tar.gz qemu-5d62c43a17edaa7f6a88821c9086e6c8e0e5327d.tar.bz2 qemu-5d62c43a17edaa7f6a88821c9086e6c8e0e5327d.zip |
apic: Defer interrupt updates to VCPU thread
KVM performs TPR raising asynchronously to QEMU, specifically outside
QEMU's global lock. When an interrupt is injected into the APIC and TPR
is checked to decide if this can be delivered, a stale TPR value may be
used, causing spurious interrupts in the end.
Fix this by deferring apic_update_irq to the context of the target VCPU.
We introduce a new interrupt flag for this, CPU_INTERRUPT_POLL. When it
is set, the VCPU calls apic_poll_irq before checking for further pending
interrupts. To avoid special-casing KVM, we also implement this logic
for TCG mode.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'cpu-exec.c')
-rw-r--r-- | cpu-exec.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 08c35f72d4..fc185a4f04 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -288,6 +288,12 @@ int cpu_exec(CPUArchState *env) } #endif #if defined(TARGET_I386) +#if !defined(CONFIG_USER_ONLY) + if (interrupt_request & CPU_INTERRUPT_POLL) { + env->interrupt_request &= ~CPU_INTERRUPT_POLL; + apic_poll_irq(env->apic_state); + } +#endif if (interrupt_request & CPU_INTERRUPT_INIT) { cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0); |