I don't think this patch is complete to add NMIP support to KVM, and can
you pls exclude it from current APIC patchsets? We can revisit it later
with more thoughts.

-Xin 

>-----Original Message-----
>From: [EMAIL PROTECTED] 
>[mailto:[EMAIL PROTECTED] On Behalf Of 
>Gregory Haskins
>Sent: Friday, June 01, 2007 2:09 AM
>To: kvm-devel@lists.sourceforge.net
>Subject: [kvm-devel] [PATCH 6/9] KVM: Adds support for real 
>NMI injection onVMX processors
>
>Signed-off-by: Gregory Haskins <[EMAIL PROTECTED]>
>---
>
> drivers/kvm/vmx.c |   56 
>+++++++++++++++++++++++++++++++++++++++++++++++++----
> drivers/kvm/vmx.h |    3 +++
> 2 files changed, 55 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
>index 82e40c9..7923a42 100644
>--- a/drivers/kvm/vmx.c
>+++ b/drivers/kvm/vmx.c
>@@ -1301,7 +1301,14 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
>                              PIN_BASED_VM_EXEC_CONTROL,
>                              PIN_BASED_EXT_INTR_MASK   /* 20.6.1 */
>                              | PIN_BASED_NMI_EXITING   /* 20.6.1 */
>+                             | PIN_BASED_VIRTUAL_NMI   /* 20.6.1 */
>                       );
>+
>+      if (!(vmcs_read32(PIN_BASED_VM_EXEC_CONTROL) & 
>PIN_BASED_VIRTUAL_NMI))
>+              printk(KERN_DEBUG "KVM: Warning - Host 
>processor does " \
>+                     "not support virtual-NMI injection.  
>Using IRQ " \
>+                     "method\n");
>+ 
>       vmcs_write32_fixedbits(MSR_IA32_VMX_PROCBASED_CTLS,
>                              CPU_BASED_VM_EXEC_CONTROL,
>                              CPU_BASED_HLT_EXITING         /* 
>20.6.2 */
>@@ -1450,6 +1457,37 @@ static void inject_rmode_irq(struct 
>kvm_vcpu *vcpu, int irq)
>       vmcs_writel(GUEST_RSP, (vmcs_readl(GUEST_RSP) & 
>~0xffff) | (sp - 6));
> }
> 
>+static void do_nmi_requests(struct kvm_vcpu *vcpu)
>+{
>+      int nmi_window = 0;
>+
>+      BUG_ON(!(test_bit(kvm_irqpin_nmi, &vcpu->irq.pending)));
>+
>+      nmi_window =
>+              (((vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 0xb) == 0)
>+               && (vmcs_read32(VM_ENTRY_INTR_INFO_FIELD)
>+                   & INTR_INFO_VALID_MASK));
>+
>+      if (nmi_window) {
>+              if (vcpu->rmode.active)
>+                      inject_rmode_irq(vcpu, 2);
>+              else
>+                      vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
>+                                   2 |
>+                                   INTR_TYPE_NMI |
>+                                   INTR_INFO_VALID_MASK);
>+
>+              __clear_bit(kvm_irqpin_nmi, &vcpu->irq.pending);
>+      } else {
>+              /*
>+               * NMIs blocked.  Wait for unblock.
>+               */
>+              u32 cbvec = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
>+              cbvec |= CPU_BASED_NMI_EXITING;
>+              vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cbvec); 
>+      }
>+}
>+
> static void do_intr_requests(struct kvm_vcpu *vcpu,
>                           struct kvm_run *kvm_run,
>                           kvm_irqpin_t pin)
>@@ -1482,9 +1520,11 @@ static void do_intr_requests(struct 
>kvm_vcpu *vcpu,
>                       break;
>               case kvm_irqpin_nmi:
>                       /*
>-                       * FIXME: Someday we will handle this using the
>-                       * specific VMX NMI features.  For now, 
>just inject
>-                       * the NMI as a standard interrupt on vector 2
>+                       * We should only get here if the processor does
>+                       * not support virtual NMIs.  Inject 
>the NMI as a
>+                       * standard interrupt on vector 2.  The 
>implication is
>+                       * that NMIs are going to be subject to 
>RFLAGS.IF
>+                       * masking, unfortunately.
>                        */
>                       ack.flags |= KVM_IRQACKDATA_VECTOR_VALID;
>                       ack.vector = 2;
>@@ -1534,6 +1574,8 @@ static void 
>clear_pending_controls(struct kvm_vcpu *vcpu,
>       else
>               cbvec &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
> 
>+      cbvec &= ~CPU_BASED_NMI_EXITING;
>+
>       vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cbvec);
> }
> 
>@@ -1550,7 +1592,6 @@ static void do_interrupt_requests(struct 
>kvm_vcpu *vcpu,
>               switch (pin) {
>               case kvm_irqpin_localint:
>               case kvm_irqpin_extint:
>-              case kvm_irqpin_nmi:
>                       do_intr_requests(vcpu, kvm_run, pin);
>                       break;
>               case kvm_irqpin_smi:
>@@ -1558,6 +1599,13 @@ static void 
>do_interrupt_requests(struct kvm_vcpu *vcpu,
>                       printk(KERN_WARNING "KVM: dropping 
>unhandled SMI\n");
>                       __clear_bit(pin, &vcpu->irq.pending);
>                       break;
>+              case kvm_irqpin_nmi:
>+                      if (vmcs_read32(PIN_BASED_VM_EXEC_CONTROL)
>+                          & PIN_BASED_VIRTUAL_NMI)
>+                              do_nmi_requests(vcpu);
>+                      else
>+                              do_intr_requests(vcpu, kvm_run, pin);   
>+                      break;
>               case kvm_irqpin_invalid:
>                       /* drop */
>                       break;
>diff --git a/drivers/kvm/vmx.h b/drivers/kvm/vmx.h
>index d0dc93d..d3fe017 100644
>--- a/drivers/kvm/vmx.h
>+++ b/drivers/kvm/vmx.h
>@@ -35,6 +35,7 @@
> #define CPU_BASED_CR8_LOAD_EXITING      0x00080000
> #define CPU_BASED_CR8_STORE_EXITING     0x00100000
> #define CPU_BASED_TPR_SHADOW            0x00200000
>+#define CPU_BASED_NMI_EXITING           0x00400000
> #define CPU_BASED_MOV_DR_EXITING        0x00800000
> #define CPU_BASED_UNCOND_IO_EXITING     0x01000000
> #define CPU_BASED_ACTIVATE_IO_BITMAP    0x02000000
>@@ -44,6 +45,7 @@
> 
> #define PIN_BASED_EXT_INTR_MASK 0x1
> #define PIN_BASED_NMI_EXITING   0x8
>+#define PIN_BASED_VIRTUAL_NMI   0x20
> 
> #define VM_EXIT_ACK_INTR_ON_EXIT        0x00008000
> #define VM_EXIT_HOST_ADD_SPACE_SIZE     0x00000200
>@@ -221,6 +223,7 @@ enum vmcs_field {
> #define VECTORING_INFO_VALID_MASK             INTR_INFO_VALID_MASK
> 
> #define INTR_TYPE_EXT_INTR              (0 << 8) /* external 
>interrupt */
>+#define INTR_TYPE_NMI                   (2 << 8) /* 
>non-maskable interrupt */
> #define INTR_TYPE_EXCEPTION             (3 << 8) /* processor 
>exception */
> 
> /*
>
>
>---------------------------------------------------------------
>----------
>This SF.net email is sponsored by DB2 Express
>Download DB2 Express C - the FREE version of DB2 express and take
>control of your XML. No limits. Just data. Click to get it now.
>http://sourceforge.net/powerbar/db2/
>_______________________________________________
>kvm-devel mailing list
>kvm-devel@lists.sourceforge.net
>https://lists.sourceforge.net/lists/listinfo/kvm-devel
>

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to