aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/x86_64/traps.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-01 14:02:00 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-01 14:02:00 +0000
commit95b697252f765f9433c45f7115ed9ce0abcbf170 (patch)
tree20d54c39a5b0fe47b65e9c5f94382faa3f7bfc37 /xen/arch/x86/x86_64/traps.c
parent22b984ae9a41041ecbab3eb487de75e3f1ffb592 (diff)
downloadxen-95b697252f765f9433c45f7115ed9ce0abcbf170.tar.gz
xen-95b697252f765f9433c45f7115ed9ce0abcbf170.tar.bz2
xen-95b697252f765f9433c45f7115ed9ce0abcbf170.zip
x86: fix MCE/NMI injection
This attempts to address all the concerns raised in http://lists.xensource.com/archives/html/xen-devel/2009-11/msg01195.html, but I'm nevertheless still not convinced that all aspects of the injection handling really work reliably. In particular, while the patch here on top of the fixes for the problems menioned in the referenced mail also adds code to keep send_guest_trap() from injecting multiple events at a time, I don't think the is the right mechanism - it should be possible to handle NMI/MCE nested within each other. Another fix on top of the ones for the earlier described problems is that the vCPU affinity restore logic didn't account for software injected NMIs - these never set cpu_affinity_tmp, but due to it most likely being different from cpu_affinity it would have got restored (to a potentially random value) nevertheless. Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/x86_64/traps.c')
-rw-r--r--xen/arch/x86/x86_64/traps.c56
1 files changed, 2 insertions, 54 deletions
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index e1c65ee53f..78a0452b49 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -270,9 +270,6 @@ unsigned long do_iret(void)
struct cpu_user_regs *regs = guest_cpu_user_regs();
struct iret_context iret_saved;
struct vcpu *v = current;
- struct domain *d = v->domain;
- struct bank_entry *entry;
- int cpu = smp_processor_id();
if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp,
sizeof(iret_saved))) )
@@ -308,60 +305,11 @@ unsigned long do_iret(void)
regs->rcx = iret_saved.rcx;
}
- /* Restore affinity. */
- if ((v->trap_priority >= VCPU_TRAP_NMI)
- && !cpus_equal(v->cpu_affinity_tmp, v->cpu_affinity))
- vcpu_set_affinity(v, &v->cpu_affinity_tmp);
-
- /* inject vMCE to PV_Guest including DOM0. */
- if (v->trap_priority >= VCPU_TRAP_NMI) {
- printk(KERN_DEBUG "MCE: Return from vMCE# trap!\n");
- if ( v->vcpu_id == 0 ) {
- if ( !d->arch.vmca_msrs.nr_injection ) {
- printk(KERN_WARNING "MCE: Ret from vMCE#, "
- "No injection Node\n");
- goto end;
- }
-
- d->arch.vmca_msrs.nr_injection--;
- if (!list_empty(&d->arch.vmca_msrs.impact_header)) {
- entry = list_entry(d->arch.vmca_msrs.impact_header.next,
- struct bank_entry, list);
- printk(KERN_DEBUG "MCE: Delete last injection Node\n");
- list_del(&entry->list);
- }
- else
- printk(KERN_DEBUG "MCE: Not found last injection "
- "Node, something Wrong!\n");
-
- /* futher injection*/
- if ( d->arch.vmca_msrs.nr_injection > 0) {
- if ( d->arch.vmca_msrs.nr_injection > 0 &&
- guest_has_trap_callback(d, v->vcpu_id,
- TRAP_machine_check) &&
- !test_and_set_bool(dom0->vcpu[0]->mce_pending)) {
- cpumask_t affinity;
-
- dom0->vcpu[0]->cpu_affinity_tmp =
- dom0->vcpu[0]->cpu_affinity;
- cpus_clear(affinity);
- cpu_set(cpu, affinity);
- printk(KERN_DEBUG "MCE: CPU%d set affinity, old %d\n", cpu,
- dom0->vcpu[0]->processor);
- vcpu_set_affinity(dom0->vcpu[0], &affinity);
- vcpu_kick(dom0->vcpu[0]);
- }
- }
- }
- } /* end of outer-if */
-
-end:
- /* Restore previous trap priority */
- v->trap_priority = v->old_trap_priority;
-
/* Restore upcall mask from supplied EFLAGS.IF. */
vcpu_info(v, evtchn_upcall_mask) = !(iret_saved.rflags & X86_EFLAGS_IF);
+ async_exception_cleanup(v);
+
/* Saved %rax gets written back to regs->rax in entry.S. */
return iret_saved.rax;