Skip to contentSkip to conversation

Nested Virtualization: interrupts (svm specific)

PATCH In review Christoph Egger 1 participant 1 message Aug 5, 2010

lore
Share & tools
lore
#0 lore raw

PATCH 11/14 Nested Virtualization: interrupts (svm specific)

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

# HG changeset patch
# User cegger
# Date 1281004719 -7200
Implement SVM specific interrupt handling

xen/arch/x86/hvm/svm/entry.S +5 -0
diff -r c6a5143c1c33 -r 092d43f1ba2a xen/arch/x86/hvm/svm/entry.S
@@ -56,6 +56,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
diff -r c6a5143c1c33 -r 092d43f1ba2a xen/arch/x86/hvm/svm/intr.c
@@ -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 vcp
     ASSERT(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:
+                /* Guest already enabled an interrupt window. */
+                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