Nested Virtualization: interrupts (svm specific)
PATCH 12/15 Nested Virtualization: interrupts (svm specific)
Signed-off-by Christoph Egger <[email protected]>
Signature · 6 lines
---to satisfy European Law for business letters: Advanced Micro Devices GmbH Einsteinring 24, 85609 Dornach b. Muenchen Geschaeftsfuehrer: Andrew Bowd, Thomas M. McCoy, Giuliano Meroni Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
# HG changeset patch
# User cegger
# Date 1275382037 -7200
Implement SVM specific interrupt handling
xen/arch/x86/hvm/svm/entry.S +5 -0
@@ -60,6 +60,11 @@ ENTRY(svm_asm_do_resume) call svm_intr_assist get_current(bx) + + movl NESTEDHVM_hostflags(r(bx)),%eax + and $NESTEDHVM_forcevmexit,%eax + jnz svm_stgi_label + CLGI mov VCPU_processor(r(bx)),%eax
xen/arch/x86/hvm/svm/intr.c +35 -4
@@ -33,6 +33,7 @@#include <asm/hvm/vlapic.h> #include <asm/hvm/svm/svm.h> #include <asm/hvm/svm/intr.h> +#include <asm/hvm/nestedhvm.h> /* for nestedhvm_vcpu_in_guestmode */ #include <xen/event.h> #include <xen/kernel.h> #include <public/hvm/ioreq.h>
@@ -58,7 +59,7 @@ static void svm_inject_nmi(struct vcpu **/ vmcb->general1_intercepts |=GENERAL1_INTERCEPT_IRET ; } - +static void svm_inject_extint (struct vcpu *v,int vector) {struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -72,7 +73,7 @@ static void svm_inject_extint(struct vcpASSERT (vmcb->eventinj.fields.v ==0 ); vmcb->eventinj = event; } - +static void enable_intr_window (struct vcpu *v,struct hvm_intack intack) {struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -117,15 +118,46 @@ asmlinkage void svm_intr_assist(void)struct vcpu *v = current;struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;struct hvm_intack intack; +enum hvm_intblk intblk;/* Crank the handle on interrupt state. */ pt_update_irq (v); do { + int rc; + intack = hvm_vcpu_has_pending_irq(v); if ( likely(intack.source == hvm_intsrc_none) ) return; + intblk = hvm_interrupt_blocked(v, intack); + if ( intblk == hvm_intblk_gif ) { + ASSERT(nestedhvm_enabled(v->domain)); + return; + } + + /* Interrupts for the nested guest are already + * in the vmcb. + */ + if ( nestedhvm_enabled(v->domain) && nestedhvm_vcpu_in_guestmode(v) ) + { + rc = nestedhvm_vcpu_interrupt(v, intack); + switch (rc) { + case NESTEDHVM_INTR_NOTINTERCEPTED: + /* Inject interrupt into 2nd level guest directly. */ + break; + case NESTEDHVM_INTR_NOTHANDLED: + case NESTEDHVM_INTR_FORCEVMEXIT: + return; + case NESTEDHVM_INTR_MASKED: + enable_intr_window(v, intack); + return; + default: + panic("%s: nestedhvm_vcpu_interrupt can't handle value 0x%x\n", + __func__, rc); + } + } + /* * Pending IRQs must be delayed if: * 1. An event is already pending. This is despite the fact that SVM
@@ -140,8 +172,7 @@ asmlinkage void svm_intr_assist(void)* have cleared the interrupt out of the IRR. * 2. The IRQ is masked. */ -if (unlikely (vmcb->eventinj.fields.v) || -hvm_interrupt_blocked (v, intack) ) +if (unlikely (vmcb->eventinj.fields.v) || intblk ) {enable_intr_window (v, intack);return ;
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel