x86: defer processing events on the NMI exit path

Otherwise, we may end up in the scheduler, keeping NMIs masked for a
possibly unbounded period of time (until whenever the next IRET gets
executed). Enforce timely event processing by sending a self IPI.

Of course it's open for discussion whether to always use the straight
exit path from handle_ist_exception.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
This commit is contained in:
Jan Beulich committed 2013-03-04 10:19:34 +01:00
1 parent e6a6fd6365
commit d463b005bb
2 files changed
+23 -6

No files matched your search

+1 -1
View File
@@ -171,7 +171,7 @@ compat_bad_hypercall:
jmp compat_test_all_events
/* %rbx: struct vcpu, interrupts disabled */
compat_restore_all_guest:
ENTRY(compat_restore_all_guest)
ASSERT_INTERRUPTS_DISABLED
RESTORE_ALL adj=8 compat=1
.Lft0: iretq
+22 -5
View File
@@ -11,6 +11,7 @@
#include <asm/apicdef.h>
#include <asm/page.h>
#include <public/xen.h>
#include <irq_vectors.h>
ALIGN
/* %rbx: struct vcpu */
@@ -615,6 +616,9 @@ ENTRY(early_page_fault)
jmp restore_all_xen
.popsection
ENTRY(nmi)
pushq $0
movl $TRAP_nmi,4(%rsp)
handle_ist_exception:
SAVE_ALL
testb $3,UREGS_cs(%rsp)
@@ -629,12 +633,25 @@ handle_ist_exception:
movzbl UREGS_entry_vector(%rsp),%eax
leaq exception_table(%rip),%rdx
callq *(%rdx,%rax,8)
jmp ret_from_intr
cmpb $TRAP_nmi,UREGS_entry_vector(%rsp)
jne ret_from_intr
ENTRY(nmi)
pushq $0
movl $TRAP_nmi,4(%rsp)
jmp handle_ist_exception
/* We want to get straight to the IRET on the NMI exit path. */
testb $3,UREGS_cs(%rsp)
jz restore_all_xen
GET_CURRENT(%rbx)
/* Send an IPI to ourselves to cover for the lack of event checking. */
movl VCPU_processor(%rbx),%eax
shll $IRQSTAT_shift,%eax
leaq irq_stat(%rip),%rcx
cmpl $0,(%rcx,%rax,1)
je 1f
movl $EVENT_CHECK_VECTOR,%edi
call send_IPI_self
1: movq VCPU_domain(%rbx),%rax
cmpb $0,DOMAIN_is_32bit_pv(%rax)
je restore_all_guest
jmp compat_restore_all_guest
ENTRY(nmi_crash)
pushq $0
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.