[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.2-testing] svm: Better handling of NMI injection -- avoid nested NMIs.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1211537345 -3600 # Node ID 98e7af9f5a4219d05ba26d2327bcd0db487c7de5 # Parent e03ac7ab7521543019a72aa47514e018d55232ae svm: Better handling of NMI injection -- avoid nested NMIs. We do this by emulating the NMI mask which blocks NMI delivery until next IRET on native hardware. Signed-off-by: Gianluca Guida <gianluca.guida@xxxxxxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> xen-unstable changeset: 17655:2ada81810ddb73f29dfd1eb00de466eec2881ce6 xen-unstable date: Mon May 19 10:03:26 2008 +0100 --- xen/arch/x86/hvm/svm/intr.c | 6 ++++++ xen/arch/x86/hvm/svm/svm.c | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff -r e03ac7ab7521 -r 98e7af9f5a42 xen/arch/x86/hvm/svm/intr.c --- a/xen/arch/x86/hvm/svm/intr.c Fri May 23 11:05:12 2008 +0100 +++ b/xen/arch/x86/hvm/svm/intr.c Fri May 23 11:09:05 2008 +0100 @@ -51,6 +51,12 @@ static void svm_inject_nmi(struct vcpu * ASSERT(vmcb->eventinj.fields.v == 0); vmcb->eventinj = event; + + /* + * SVM does not virtualise the NMI mask, so we emulate it by intercepting + * the next IRET and blocking NMI injection until the intercept triggers. + */ + vmcb->general1_intercepts |= GENERAL1_INTERCEPT_IRET; } static void svm_inject_extint(struct vcpu *v, int vector) diff -r e03ac7ab7521 -r 98e7af9f5a42 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Fri May 23 11:05:12 2008 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Fri May 23 11:09:05 2008 +0100 @@ -438,7 +438,8 @@ static enum hvm_intblk svm_interrupt_blo return hvm_intblk_shadow; if ( intack.source == hvm_intsrc_nmi ) - return hvm_intblk_none; + return ((vmcb->general1_intercepts & GENERAL1_INTERCEPT_IRET) ? + hvm_intblk_nmi_iret : hvm_intblk_none); ASSERT((intack.source == hvm_intsrc_pic) || (intack.source == hvm_intsrc_lapic)); @@ -2112,6 +2113,15 @@ asmlinkage void svm_vmexit_handler(struc reason = TSW_call_or_int; if ( (vmcb->exitinfo2 >> 44) & 1 ) errcode = (uint32_t)vmcb->exitinfo2; + + /* + * Some processors set the EXITINTINFO field when the task switch + * is caused by a task gate in the IDT. In this case we will be + * emulating the event injection, so we do not want the processor + * to re-inject the original event! + */ + vmcb->eventinj.bytes = 0; + hvm_task_switch((uint16_t)vmcb->exitinfo1, reason, errcode); break; } @@ -2191,6 +2201,19 @@ asmlinkage void svm_vmexit_handler(struc svm_do_nested_pgfault(vmcb->exitinfo2, regs); break; + case VMEXIT_IRET: + /* + * IRET clears the NMI mask. However because we clear the mask + * /before/ executing IRET, we set the interrupt shadow to prevent + * a pending NMI from being injected immediately. This will work + * perfectly unless the IRET instruction faults: in that case we + * may inject an NMI before the NMI handler's IRET instruction is + * retired. + */ + vmcb->general1_intercepts &= ~GENERAL1_INTERCEPT_IRET; + vmcb->interrupt_shadow = 1; + break; + default: exit_and_crash: gdprintk(XENLOG_ERR, "unexpected VMEXIT: exit reason = 0x%x, " _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |