Skip to contentSkip to conversation

KVM: VMX: Enable NMI with in-kernel irqchip

RFC PATCH In review Yang, Sheng 2 participants 6 messages May 8, 2008 – May 13, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 3/4 KVM: VMX: Enable NMI with in-kernel irqchip

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

---
 arch/x86/kvm/vmx.c         |  133 
+++++++++++++++++++++++++++++++++++++-------
 arch/x86/kvm/vmx.h         |   12 ++++-
 arch/x86/kvm/x86.c         |    1 +
 include/asm-x86/kvm_host.h |    1 +
 4 files changed, 125 insertions(+), 22 deletions(-)
arch/x86/kvm/vmx.c +6 -0
index 26c4f02..55fe525 100644
@@ -260,6 +260,12 @@ static inline int cpu_has_vmx_vpid(void)
 		SECONDARY_EXEC_ENABLE_VPID);
 }
 
+static inline int cpu_has_virtual_nmis(void)
+{
+	return (vmcs_config.pin_based_exec_ctrl &
+		PIN_BASED_VIRTUAL_NMIS);
+}
+
 static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr)
 {
 	int i;
@@ -1068,7 +1074,7 @@ static __init int setup_vmcs_config(struct vmcs_config 

*vmcs_conf)
u32 _vmentry_control = 0;

min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
- opt = 0;
+ opt = PIN_BASED_VIRTUAL_NMIS;
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS,
&_pin_based_exec_control) < 0)
return -EIO;
@@ -2110,6 +2116,13 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq)
irq | INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
}

+static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
+{
+ vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
+ INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
+ vcpu->arch.nmi_pending = 0;
+}
+
static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
{
int word_index = __ffs(vcpu->arch.irq_summary);
@@ -2146,9 +2159,11 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
/*
* Interrupts blocked. Wait for unblock.
*/
- cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
+ cpu_based_vm_exec_control |=
+ CPU_BASED_VIRTUAL_INTR_PENDING;
else
- cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+ cpu_based_vm_exec_control &=
+ ~CPU_BASED_VIRTUAL_INTR_PENDING;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
}

@@ -2633,6 +2648,19 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}

+static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{
+ u32 cpu_based_vm_exec_control;
+
+ /* clear pending NMI */
+ cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
+ cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
+ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ ++vcpu->stat.nmi_window_exits;
+
+ return 1;
+}
+
/*
* The exit handlers return 1 if the exit was handled fully and guest
execution
* may resume. Otherwise they set the kvm_run parameter to indicate what
needs
@@ -2643,6 +2671,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,

 	[EXIT_REASON_EXCEPTION_NMI]           = handle_exception,
 	[EXIT_REASON_EXTERNAL_INTERRUPT]      = handle_external_interrupt,
 	[EXIT_REASON_TRIPLE_FAULT]            = handle_triple_fault,
+	[EXIT_REASON_NMI_WINDOW]	      = handle_nmi_window,
 	[EXIT_REASON_IO_INSTRUCTION]          = handle_io,
 	[EXIT_REASON_CR_ACCESS]               = handle_cr,
 	[EXIT_REASON_DR_ACCESS]               = handle_dr,

@@ -2730,17 +2759,52 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
}

+static void enable_nmi_window(struct kvm_vcpu *vcpu) +{
+ u32 cpu_based_vm_exec_control;
+
+ if (!cpu_has_virtual_nmis())
+ return;
+
+ cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
+ cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING;
+ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+}
+
+static int vmx_nmi_enabled(struct kvm_vcpu *vcpu) +{
+ u32 guest_intr = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
+ return !(guest_intr & (GUEST_INTR_STATE_NMI |
+ GUEST_INTR_STATE_MOV_SS |
+ GUEST_INTR_STATE_STI));
+}
+
+static int vmx_irq_enabled(struct kvm_vcpu *vcpu) +{
+ u32 guest_intr = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
+ return (!(guest_intr & (GUEST_INTR_STATE_MOV_SS |
+ GUEST_INTR_STATE_STI)) &&
+ (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF));
+}
+
+static void enable_intr_window(struct kvm_vcpu *vcpu) +{
+ if (vcpu->arch.nmi_pending)
+ enable_nmi_window(vcpu);
+ else if (kvm_cpu_has_interrupt(vcpu))
+ enable_irq_window(vcpu);
+}
+
static void vmx_intr_assist(struct kvm_vcpu *vcpu) {
struct vcpu_vmx *vmx = to_vmx(vcpu);
- u32 idtv_info_field, intr_info_field;
- int has_ext_irq, interrupt_window_open;
+ u32 idtv_info_field, intr_info_field, exit_intr_info_field;
int vector;

update_tpr_threshold(vcpu);

- has_ext_irq = kvm_cpu_has_interrupt(vcpu);
intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
+ exit_intr_info_field = vmcs_read32(VM_EXIT_INTR_INFO);
idtv_info_field = vmx->idt_vectoring_info;
if (intr_info_field & INTR_INFO_VALID_MASK) {
if (idtv_info_field & INTR_INFO_VALID_MASK) {
@@ -2748,8 +2812,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
if (printk_ratelimit())
printk(KERN_ERR "Fault when IDT_Vectoring\n");
}
- if (has_ext_irq)
- enable_irq_window(vcpu);
+ enable_intr_window(vcpu);
return;
}
if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
@@ -2759,30 +2822,56 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
u8 vect = idtv_info_field & VECTORING_INFO_VECTOR_MASK;

vmx_inject_irq(vcpu, vect);
- if (unlikely(has_ext_irq))
- enable_irq_window(vcpu);
+ enable_intr_window(vcpu);
return;
}

KVMTRACE_1D(REDELIVER_EVT, vcpu, idtv_info_field, handler);

- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
+ /*
+ * SDM 3: 25.7.1.2
+ * Clear bit "block by NMI" before VM entry if a NMI delivery
+ * faulted.
+ */
+ if ((idtv_info_field & VECTORING_INFO_TYPE_MASK)
+ == INTR_TYPE_NMI_INTR && cpu_has_virtual_nmis())
+ vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
+ vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+ ~GUEST_INTR_STATE_NMI);
+
+ vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field
+ & ~INTR_INFO_RESVD_BITS_MASK);
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
vmcs_read32(VM_EXIT_INSTRUCTION_LEN));

if (unlikely(idtv_info_field & INTR_INFO_DELIVER_CODE_MASK))
vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE,
vmcs_read32(IDT_VECTORING_ERROR_CODE));
- if (unlikely(has_ext_irq))
- enable_irq_window(vcpu);
+ enable_intr_window(vcpu);
return;
}
- if (!has_ext_irq)
+ if (cpu_has_virtual_nmis()) {
+ /*
+ * SDM 3: 25.7.1.2
+ * Re-set bit "block by NMI" before VM entry if vmexit caused by
+ * a guest IRET fault.
+ */
+ if ((exit_intr_info_field & INTR_INFO_UNBLOCK_NMI) &&
+ (exit_intr_info_field & INTR_INFO_VECTOR_MASK) != 8)
+ vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
+ vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) |
+ GUEST_INTR_STATE_NMI);
+ else if (vcpu->arch.nmi_pending) {
+ if (vmx_nmi_enabled(vcpu))
+ vmx_inject_nmi(vcpu);
+ enable_intr_window(vcpu);
+ return;
+ }
+
+ }
+ if (!kvm_cpu_has_interrupt(vcpu))
return;
- interrupt_window_open =
- ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) &&
- (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
- if (interrupt_window_open) {
+ if (vmx_irq_enabled(vcpu)) {
vector = kvm_cpu_get_interrupt(vcpu); vmx_inject_irq(vcpu, vector); kvm_timer_intr_post(vcpu, vector);
@@ -2943,7 +3032,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
fixup_rmode_irq(vmx);

vcpu->arch.interrupt_window_open =
- (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
+ (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+ (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;

asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); vmx->launched = 1;
@@ -2951,9 +3041,10 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
intr_info = vmcs_read32(VM_EXIT_INTR_INFO);

/* We need to handle NMIs before interrupts are enabled */
- if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
+ if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {
KVMTRACE_0D(NMI, vcpu, handler);
- asm("int $2");
+ if (!cpu_has_virtual_nmis())
+ asm("int $2");
}
}

arch/x86/kvm/vmx.h +11 -1
index 79d94c6..425a134 100644
@@ -40,6 +40,7 @@
 #define CPU_BASED_CR8_LOAD_EXITING              0x00080000
 #define CPU_BASED_CR8_STORE_EXITING             0x00100000
 #define CPU_BASED_TPR_SHADOW                    0x00200000
+#define CPU_BASED_VIRTUAL_NMI_PENDING		0x00400000
 #define CPU_BASED_MOV_DR_EXITING                0x00800000
 #define CPU_BASED_UNCOND_IO_EXITING             0x01000000
 #define CPU_BASED_USE_IO_BITMAPS                0x02000000
@@ -216,7 +217,7 @@ enum vmcs_field {
 #define EXIT_REASON_TRIPLE_FAULT        2
 
 #define EXIT_REASON_PENDING_INTERRUPT   7
-
+#define EXIT_REASON_NMI_WINDOW		8
 #define EXIT_REASON_TASK_SWITCH         9
 #define EXIT_REASON_CPUID               10
 #define EXIT_REASON_HLT                 12
@@ -251,7 +252,9 @@ enum vmcs_field {
 #define INTR_INFO_VECTOR_MASK           0xff            /* 7:0 */
 #define INTR_INFO_INTR_TYPE_MASK        0x700           /* 10:8 */
 #define INTR_INFO_DELIVER_CODE_MASK     0x800           /* 11 */
+#define INTR_INFO_UNBLOCK_NMI		0x1000		/* 12 */
 #define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
+#define INTR_INFO_RESVD_BITS_MASK       0x7ffff000
 
 #define VECTORING_INFO_VECTOR_MASK           	INTR_INFO_VECTOR_MASK
 #define VECTORING_INFO_TYPE_MASK        	INTR_INFO_INTR_TYPE_MASK
@@ -259,9 +262,16 @@ 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_INTR		(2 << 8) /* NMI */
 #define INTR_TYPE_EXCEPTION             (3 << 8) /* processor exception */
 #define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */
 
+/* GUEST_INTERRUPTIBILITY_INFO flags. */
+#define GUEST_INTR_STATE_STI		0x00000001
+#define GUEST_INTR_STATE_MOV_SS		0x00000002
+#define GUEST_INTR_STATE_SMI		0x00000004
+#define GUEST_INTR_STATE_NMI		0x00000008
+
 /*
  * Exit Qualifications for MOV for Control Register Access
  */
arch/x86/kvm/x86.c +1 -0
index f95ebdb..16e9cd2 100644
@@ -72,6 +72,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "mmio_exits", VCPU_STAT(mmio_exits) },
 	{ "signal_exits", VCPU_STAT(signal_exits) },
 	{ "irq_window", VCPU_STAT(irq_window_exits) },
+	{ "nmi_window", VCPU_STAT(nmi_window_exits) },
 	{ "halt_exits", VCPU_STAT(halt_exits) },
 	{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
 	{ "hypercalls", VCPU_STAT(hypercalls) },
include/asm-x86/kvm_host.h +1 -0
index 2df8416..277216c 100644
@@ -344,6 +344,7 @@ struct kvm_vcpu_stat {
 	u32 mmio_exits;
 	u32 signal_exits;
 	u32 irq_window_exits;
+	u32 nmi_window_exits;
 	u32 halt_exits;
 	u32 halt_wakeup;
 	u32 request_irq_exits;

--
1.5.5

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

---
 arch/x86/kvm/vmx.c         |  133 +++++++++++++++++++++++++++++++++++++-------
 arch/x86/kvm/vmx.h         |   12 ++++-
 arch/x86/kvm/x86.c         |    1 +
 include/asm-x86/kvm_host.h |    1 +
 4 files changed, 125 insertions(+), 22 deletions(-)
arch/x86/kvm/vmx.c +112 -21

223 lines not on this page · raw message

arch/x86/kvm/vmx.h +11 -1
index 79d94c6..425a134 100644
@@ -40,6 +40,7 @@
 #define CPU_BASED_CR8_LOAD_EXITING              0x00080000
 #define CPU_BASED_CR8_STORE_EXITING             0x00100000
 #define CPU_BASED_TPR_SHADOW                    0x00200000
+#define CPU_BASED_VIRTUAL_NMI_PENDING		0x00400000
 #define CPU_BASED_MOV_DR_EXITING                0x00800000
 #define CPU_BASED_UNCOND_IO_EXITING             0x01000000
 #define CPU_BASED_USE_IO_BITMAPS                0x02000000
@@ -216,7 +217,7 @@ enum vmcs_field {
 #define EXIT_REASON_TRIPLE_FAULT        2
 
 #define EXIT_REASON_PENDING_INTERRUPT   7
-
+#define EXIT_REASON_NMI_WINDOW		8
 #define EXIT_REASON_TASK_SWITCH         9
 #define EXIT_REASON_CPUID               10
 #define EXIT_REASON_HLT                 12
@@ -251,7 +252,9 @@ enum vmcs_field {
 #define INTR_INFO_VECTOR_MASK           0xff            /* 7:0 */
 #define INTR_INFO_INTR_TYPE_MASK        0x700           /* 10:8 */
 #define INTR_INFO_DELIVER_CODE_MASK     0x800           /* 11 */
+#define INTR_INFO_UNBLOCK_NMI		0x1000		/* 12 */
 #define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
+#define INTR_INFO_RESVD_BITS_MASK       0x7ffff000
 
 #define VECTORING_INFO_VECTOR_MASK           	INTR_INFO_VECTOR_MASK
 #define VECTORING_INFO_TYPE_MASK        	INTR_INFO_INTR_TYPE_MASK
@@ -259,9 +262,16 @@ 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_INTR		(2 << 8) /* NMI */
 #define INTR_TYPE_EXCEPTION             (3 << 8) /* processor exception */
 #define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */
 
+/* GUEST_INTERRUPTIBILITY_INFO flags. */
+#define GUEST_INTR_STATE_STI		0x00000001
+#define GUEST_INTR_STATE_MOV_SS		0x00000002
+#define GUEST_INTR_STATE_SMI		0x00000004
+#define GUEST_INTR_STATE_NMI		0x00000008
+
 /*
  * Exit Qualifications for MOV for Control Register Access
  */
arch/x86/kvm/x86.c +1 -0
index f95ebdb..16e9cd2 100644
@@ -72,6 +72,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "mmio_exits", VCPU_STAT(mmio_exits) },
 	{ "signal_exits", VCPU_STAT(signal_exits) },
 	{ "irq_window", VCPU_STAT(irq_window_exits) },
+	{ "nmi_window", VCPU_STAT(nmi_window_exits) },
 	{ "halt_exits", VCPU_STAT(halt_exits) },
 	{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
 	{ "hypercalls", VCPU_STAT(hypercalls) },
include/asm-x86/kvm_host.h +1 -0
index 2df8416..277216c 100644
@@ -344,6 +344,7 @@ struct kvm_vcpu_stat {
 	u32 mmio_exits;
 	u32 signal_exits;
 	u32 irq_window_exits;
+	u32 nmi_window_exits;
 	u32 halt_exits;
 	u32 halt_wakeup;
 	u32 request_irq_exits;
Signature · 1 line
1.5.5

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#1 lore raw
Quoted 12 lines · Sheng

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) {

arch/x86/kvm/vmx.c +0 -0
 	int word_index = __ffs(vcpu->arch.irq_summary);
@@ -2146,9 +2159,11 @@ static void do_interrupt_requests(struct kvm_vcpu 
 *vcpu,
 		/*

arch/x86/kvm/vmx.c static void do_interrupt_requests(struct kvm_vcpu · line 2168

Quoted 10 lines
arch/x86/kvm/vmx.c +4 -2
 		 * Interrupts blocked.  Wait for unblock.
 		 */
-		cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
+		cpu_based_vm_exec_control |=
+			CPU_BASED_VIRTUAL_INTR_PENDING;
 	else
-		cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+		cpu_based_vm_exec_control &=
+			~CPU_BASED_VIRTUAL_INTR_PENDING;
 

This seems spurious.

arch/x86/kvm/vmx.c static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · line 3049

Quoted 10 lines
arch/x86/kvm/vmx.c +3 -2
 	/* We need to handle NMIs before interrupts are enabled */
-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {
 		KVMTRACE_0D(NMI, vcpu, handler);
-		asm("int $2");
+		if (!cpu_has_virtual_nmis())
+			asm("int $2");
 	}
 }

That's a host nmi. So does the PIN_BASED_VIRTUAL_NMI mean NMIs are handled like unacked host interrupts?

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
#2 lore raw
Quoted 16 lines · On Friday 09 May 2008 23:49:13 Avi Kivity wrote:
Quoted 15 lines · Sheng

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) {

arch/x86/kvm/vmx.c +0 -1
 	int word_index = __ffs(vcpu->arch.irq_summary);
@@ -2146,9 +2159,11 @@ static void do_interrupt_requests(struct kvm_vcpu
 *vcpu,
 		/*
 		 * Interrupts blocked.  Wait for unblock.
 		 */
-		cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
Quoted 8 lines

arch/x86/kvm/vmx.c static void do_interrupt_requests(struct kvm_vcpu *vcpu, · line 2166

Quoted 6 lines
arch/x86/kvm/vmx.c +4 -1
+		cpu_based_vm_exec_control |=
+			CPU_BASED_VIRTUAL_INTR_PENDING;
 	else
-		cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+		cpu_based_vm_exec_control &=
+			~CPU_BASED_VIRTUAL_INTR_PENDING;

This seems spurious.

Sorry, seems I am too anxious to keep it in hand... I would like to check it much careful in the future.

Quoted 13 lines

arch/x86/kvm/vmx.c static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · line 3049

Quoted 10 lines
arch/x86/kvm/vmx.c +1 -1
 	/* We need to handle NMIs before interrupts are enabled */
-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {
arch/x86/kvm/vmx.c +2 -1
 		KVMTRACE_0D(NMI, vcpu, handler);
-		asm("int $2");
+		if (!cpu_has_virtual_nmis())
+			asm("int $2");
 	}
 }

That's a host nmi. So does the PIN_BASED_VIRTUAL_NMI mean NMIs are handled like unacked host interrupts?

Not exactly. No host NMI here if Virtual_NMI is set. Copy from SDM 3B table 20-5:

"If this control(Virtual NMIs) is 1, NMIs are never blocked and the “blocking by NMI” bit (bit 3) in the interruptibility-state field
indicates “virtual-NMI blocking” (see Table 20-3). This control also interacts with the “NMI-window exiting” VM-execution control (see Section 20.6.2)."

--
Thanks
Yang, Sheng

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#3 lore raw
Quoted 47 lines · Sheng
Quoted 17 lines · On Friday 09 May 2008 23:49:13 Avi Kivity wrote:
Quoted 15 lines · Sheng

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) {

arch/x86/kvm/vmx.c +0 -1
 	int word_index = __ffs(vcpu->arch.irq_summary);
@@ -2146,9 +2159,11 @@ static void do_interrupt_requests(struct kvm_vcpu
 *vcpu,
 		/*
 		 * Interrupts blocked.  Wait for unblock.
 		 */
-		cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
Quoted 9 lines

arch/x86/kvm/vmx.c static void do_interrupt_requests(struct kvm_vcpu *vcpu, · line 2169

Quoted 7 lines
arch/x86/kvm/vmx.c +4 -1
+		cpu_based_vm_exec_control |=
+			CPU_BASED_VIRTUAL_INTR_PENDING;
 	else
-		cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+		cpu_based_vm_exec_control &=
+			~CPU_BASED_VIRTUAL_INTR_PENDING;
 

This seems spurious.

Sorry, seems I am too anxious to keep it in hand... I would like to check it much careful in the future.

Quoted 4 lines
Quoted 4 lines
arch/x86/kvm/vmx.c +1 -1
 	/* We need to handle NMIs before interrupts are enabled */
-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {
 		KVMTRACE_0D(NMI, vcpu, handler);
Quoted 9 lines

arch/x86/kvm/vmx.c static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · line 3049

Quoted 6 lines
arch/x86/kvm/vmx.c +2 -1
-		asm("int $2");
+		if (!cpu_has_virtual_nmis())
+			asm("int $2");
 	}
 }

That's a host nmi. So does the PIN_BASED_VIRTUAL_NMI mean NMIs are handled like unacked host interrupts?

Quoted 9 lines

Not exactly. No host NMI here if Virtual_NMI is set. Copy from SDM 3B table 20-5:

"If this control(Virtual NMIs) is 1, NMIs are never blocked and the “blocking by NMI” bit (bit 3) in the interruptibility-state field
indicates “virtual-NMI blocking” (see Table 20-3). This control also interacts with the “NMI-window exiting” VM-execution control (see Section 20.6.2)."

I still don't understand. What does "NMIs are never blocked" mean? what happens if an NMI occurs while in guest mode? Obviously we don't want it to be delivered to the guest.

Signature · 12 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
#4 lore raw
Quoted 52 lines · On Monday 12 May 2008 15:54:00 Avi Kivity wrote:
Quoted 42 lines · Sheng
Quoted 16 lines · On Friday 09 May 2008 23:49:13 Avi Kivity wrote:
Quoted 15 lines · Sheng

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) {

arch/x86/kvm/vmx.c +0 -1
 	int word_index = __ffs(vcpu->arch.irq_summary);
@@ -2146,9 +2159,11 @@ static void do_interrupt_requests(struct
 kvm_vcpu *vcpu,
 		/*
 		 * Interrupts blocked.  Wait for unblock.
 		 */
-		cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
Quoted 8 lines

arch/x86/kvm/vmx.c static void do_interrupt_requests(struct kvm_vcpu *vcpu, · line 2166

Quoted 6 lines
arch/x86/kvm/vmx.c +4 -1
+		cpu_based_vm_exec_control |=
+			CPU_BASED_VIRTUAL_INTR_PENDING;
 	else
-		cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+		cpu_based_vm_exec_control &=
+			~CPU_BASED_VIRTUAL_INTR_PENDING;

This seems spurious.

Sorry, seems I am too anxious to keep it in hand... I would like to check it much careful in the future.

Quoted 4 lines
Quoted 4 lines
arch/x86/kvm/vmx.c +1 -1
 	/* We need to handle NMIs before interrupts are enabled */
-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {

KVMTRACE_0D(NMI, vcpu, handler);

Quoted 8 lines

arch/x86/kvm/vmx.c static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · line 3049

Quoted 5 lines
arch/x86/kvm/vmx.c +2 -1
-		asm("int $2");
+		if (!cpu_has_virtual_nmis())
+			asm("int $2");
 	}
 }

That's a host nmi. So does the PIN_BASED_VIRTUAL_NMI mean NMIs are handled like unacked host interrupts?

Quoted 8 lines

Not exactly. No host NMI here if Virtual_NMI is set. Copy from SDM 3B table 20-5:

"If this control(Virtual NMIs) is 1, NMIs are never blocked and the “blocking by NMI” bit (bit 3) in the interruptibility-state field indicates “virtual-NMI blocking” (see Table 20-3). This control also interacts with the “NMI-window exiting” VM-execution control (see Section 20.6.2)."

Quoted 3 lines

I still don't understand. What does "NMIs are never blocked" mean? what happens if an NMI occurs while in guest mode? Obviously we don't want it to be delivered to the guest.

Oops, I neglected it... When virtual_nmi is set, the host NMI would routed to handle_exception. And we would handle it there, by judged the vector number.

I will posted the updated patchset soon.

Signature · 11 lines
Thanks
Yang, Sheng

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
#5 lore raw
Quoted 57 lines · Sheng
Quoted 52 lines · On Monday 12 May 2008 15:54:00 Avi Kivity wrote:
Quoted 42 lines · Sheng
Quoted 16 lines · On Friday 09 May 2008 23:49:13 Avi Kivity wrote:
Quoted 15 lines · Sheng

From 4942a5c35c97e5edb6fe1303e04fb86f25cac345 Mon Sep 17 00:00:00 2001 From: Sheng Yang <[email protected]>
Date: Thu, 8 May 2008 16:00:57 +0800
Subject: [PATCH 3/4] KVM: VMX: Enable NMI with in-kernel irqchip

static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) {

arch/x86/kvm/vmx.c +0 -1
 	int word_index = __ffs(vcpu->arch.irq_summary);
@@ -2146,9 +2159,11 @@ static void do_interrupt_requests(struct
 kvm_vcpu *vcpu,
 		/*
 		 * Interrupts blocked.  Wait for unblock.
 		 */
-		cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
Quoted 8 lines

arch/x86/kvm/vmx.c static void do_interrupt_requests(struct kvm_vcpu *vcpu, · line 2166

Quoted 6 lines
arch/x86/kvm/vmx.c +4 -1
+		cpu_based_vm_exec_control |=
+			CPU_BASED_VIRTUAL_INTR_PENDING;
 	else
-		cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+		cpu_based_vm_exec_control &=
+			~CPU_BASED_VIRTUAL_INTR_PENDING;

This seems spurious.

Sorry, seems I am too anxious to keep it in hand... I would like to check it much careful in the future.

Quoted 4 lines
Quoted 4 lines
arch/x86/kvm/vmx.c +1 -1
 	/* We need to handle NMIs before interrupts are enabled */
-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {

KVMTRACE_0D(NMI, vcpu, handler);

Quoted 8 lines

arch/x86/kvm/vmx.c static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) · line 3049

Quoted 5 lines
arch/x86/kvm/vmx.c +2 -1
-		asm("int $2");
+		if (!cpu_has_virtual_nmis())
+			asm("int $2");
 	}
 }

That's a host nmi. So does the PIN_BASED_VIRTUAL_NMI mean NMIs are handled like unacked host interrupts?

Quoted 8 lines

Not exactly. No host NMI here if Virtual_NMI is set. Copy from SDM 3B table 20-5:

"If this control(Virtual NMIs) is 1, NMIs are never blocked and the “blocking by NMI” bit (bit 3) in the interruptibility-state field indicates “virtual-NMI blocking” (see Table 20-3). This control also interacts with the “NMI-window exiting” VM-execution control (see Section 20.6.2)."

Quoted 3 lines

I still don't understand. What does "NMIs are never blocked" mean? what happens if an NMI occurs while in guest mode? Obviously we don't want it to be delivered to the guest.

Quoted 5 lines

Oops, I neglected it... When virtual_nmi is set, the host NMI would routed to handle_exception. And we would handle it there, by judged the vector number.

I will posted the updated patchset soon.

Faint, misunderstood again... Seems the cold affact my thinking...

Anyway, I will updated my patchset. Thanks!

Signature · 11 lines
Thanks
Yang, Sheng

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel