All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes
@ 2014-06-03 20:27 Bandan Das
  2014-06-03 20:27 ` [PATCH kvm-unit-tests 1/2] VMX: check for supported contexts before calling invept Bandan Das
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Bandan Das @ 2014-06-03 20:27 UTC (permalink / raw)
  To: kvm; +Cc: Paolo Bonzini, Jan Kiszka

Adds a simple test for interrupt acknowledgement and change 
invept behavior to check for supported invalidation contexts

Bandan Das (2):
  VMX: check for supported contexts before calling invept
  VMX: Add test for interrupt acknowledgement

 lib/x86/isr.c   | 32 ++++++++++++++++++++++++++++++++
 lib/x86/isr.h   |  2 +-
 x86/vmx.c       | 20 ++++++++++++++++++++
 x86/vmx.h       |  1 +
 x86/vmx_tests.c | 40 ++++++++++++++++++++++++++++++----------
 5 files changed, 84 insertions(+), 11 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH kvm-unit-tests 1/2] VMX: check for supported contexts before calling invept
  2014-06-03 20:27 [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Bandan Das
@ 2014-06-03 20:27 ` Bandan Das
  2014-06-03 20:27 ` [PATCH kvm-unit-tests 2/2] VMX: Add test for interrupt acknowledgement Bandan Das
  2014-06-04  9:50 ` [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Bandan Das @ 2014-06-03 20:27 UTC (permalink / raw)
  To: kvm; +Cc: Paolo Bonzini, Jan Kiszka

It's incorrect to assume the context in which invept
is called. Check what is supported and fallback if
single context invalidation isn't supported

Signed-off-by: Bandan Das <bsd@redhat.com>
---
 x86/vmx.c       | 20 ++++++++++++++++++++
 x86/vmx.h       |  1 +
 x86/vmx_tests.c | 14 +++++++-------
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/x86/vmx.c b/x86/vmx.c
index 1d28c6f..1182eef 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -288,6 +288,26 @@ unsigned long get_ept_pte(unsigned long *pml4,
 	return pte;
 }
 
+void ept_sync(int type, u64 eptp)
+{
+	switch (type) {
+	case INVEPT_SINGLE:
+		if (ept_vpid.val & EPT_CAP_INVEPT_SINGLE) {
+			invept(INVEPT_SINGLE, eptp);
+			break;
+		}
+		/* else fall through */
+	case INVEPT_GLOBAL:
+		if (ept_vpid.val & EPT_CAP_INVEPT_ALL) {
+			invept(INVEPT_GLOBAL, eptp);
+			break;
+		}
+		/* else fall through */
+	default:
+		printf("WARNING: invept is not supported!\n");
+	}
+}
+
 int set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
 		int level, u64 pte_val)
 {
diff --git a/x86/vmx.h b/x86/vmx.h
index 351c3d9..26dd161 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -551,6 +551,7 @@ static inline void invept(unsigned long type, u64 eptp)
 }
 
 void print_vmexit_info();
+void ept_sync(int type, u64 eptp);
 void install_ept_entry(unsigned long *pml4, int pte_level,
 		unsigned long guest_addr, unsigned long pte,
 		unsigned long *pt_page);
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 2c2d6c4..324f074 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -1116,21 +1116,21 @@ static int ept_exit_handler()
 		case 1:
 			install_ept(pml4, (unsigned long)data_page1,
  				(unsigned long)data_page1, EPT_WA);
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		case 2:
 			install_ept(pml4, (unsigned long)data_page1,
  				(unsigned long)data_page1,
  				EPT_RA | EPT_WA | EPT_EA |
  				(2 << EPT_MEM_TYPE_SHIFT));
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		case 3:
 			data_page1_pte = get_ept_pte(pml4,
 				(unsigned long)data_page1, 1);
 			set_ept_pte(pml4, (unsigned long)data_page1, 
 				1, data_page1_pte & (~EPT_PRESENT));
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		case 4:
 			data_page1_pte = get_ept_pte(pml4,
@@ -1139,7 +1139,7 @@ static int ept_exit_handler()
 			data_page1_pte_pte = get_ept_pte(pml4, data_page1_pte, 2);
 			set_ept_pte(pml4, data_page1_pte, 2,
 				data_page1_pte_pte & (~EPT_PRESENT));
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		// Should not reach here
 		default:
@@ -1157,7 +1157,7 @@ static int ept_exit_handler()
 			install_ept(pml4, (unsigned long)data_page1,
  				(unsigned long)data_page1,
  				EPT_RA | EPT_WA | EPT_EA);
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		// Should not reach here
 		default:
@@ -1174,14 +1174,14 @@ static int ept_exit_handler()
 				set_stage(get_stage() + 1);
 			set_ept_pte(pml4, (unsigned long)data_page1, 
 				1, data_page1_pte | (EPT_PRESENT));
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		case 4:
 			if (exit_qual == (EPT_VLT_RD | EPT_VLT_LADDR_VLD))
 				set_stage(get_stage() + 1);
 			set_ept_pte(pml4, data_page1_pte, 2,
 				data_page1_pte_pte | (EPT_PRESENT));
-			invept(INVEPT_SINGLE, eptp);
+			ept_sync(INVEPT_SINGLE, eptp);
 			break;
 		default:
 			// Should not reach here
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH kvm-unit-tests 2/2] VMX: Add test for interrupt acknowledgement
  2014-06-03 20:27 [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Bandan Das
  2014-06-03 20:27 ` [PATCH kvm-unit-tests 1/2] VMX: check for supported contexts before calling invept Bandan Das
@ 2014-06-03 20:27 ` Bandan Das
  2014-06-04  9:50 ` [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Bandan Das @ 2014-06-03 20:27 UTC (permalink / raw)
  To: kvm; +Cc: Paolo Bonzini, Jan Kiszka

If the hypervisor has the interrupt acknowledgement bit set,
vector information is already present in intr_info during a vmexit.
The hypervisor then uses it to call the appropriate handler.

Signed-off-by: Bandan Das <bsd@redhat.com>
---
 lib/x86/isr.c   | 32 ++++++++++++++++++++++++++++++++
 lib/x86/isr.h   |  2 +-
 x86/vmx_tests.c | 26 +++++++++++++++++++++++---
 3 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/lib/x86/isr.c b/lib/x86/isr.c
index 7dcd38a..b0c6f53 100644
--- a/lib/x86/isr.c
+++ b/lib/x86/isr.c
@@ -90,3 +90,35 @@ void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs))
     *(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4);
 #endif
 }
+
+void handle_external_interrupt(int vector)
+{
+#ifdef __x86_64__
+	unsigned long tmp;
+#endif
+	idt_entry_t *idt = &boot_idt[vector];
+	unsigned long entry =
+	    idt->offset0 | ((unsigned long)idt->offset1 << 16) |
+	    ((unsigned long)idt->offset2 << 32);
+
+	asm volatile(
+#ifdef __x86_64__
+		     "mov %%rsp, %[sp]\n\t"
+		     "and $0xfffffffffffffff0, %%rsp\n\t"
+		     "push $%c[ss]\n\t"
+		     "push %[sp]\n\t"
+#endif
+		     "pushf\n\t"
+		     "orl $0x200, (%%rsp)\n\t"
+		     "push $%c[cs]\n\t"
+		     "call *%[entry]\n\t"
+		     :
+#ifdef __x86_64__
+		     [sp]"=&r"(tmp)
+#endif
+		     :
+		     [entry]"r"(entry),
+		     [ss]"i"(KERNEL_DS),
+		     [cs]"i"(KERNEL_CS)
+		     );
+}
diff --git a/lib/x86/isr.h b/lib/x86/isr.h
index b07a32a..a509291 100644
--- a/lib/x86/isr.h
+++ b/lib/x86/isr.h
@@ -10,5 +10,5 @@ typedef struct {
 } isr_regs_t;
 
 void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs));
-
+void handle_external_interrupt(int vector);
 #endif
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 324f074..a40cb18 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -1290,6 +1290,16 @@ static void interrupt_main(void)
 
 	report("intercepted interrupt + activity state hlt",
 	       rdtsc() - start > 10000 && timer_fired);
+
+	apic_write(APIC_TMICT, 0);
+	irq_disable();
+	set_stage(7);
+	vmcall();
+	timer_fired = false;
+	apic_write(APIC_TMICT, 1);
+	for (loops = 0; loops < 10000000 && !timer_fired; loops++)
+		asm volatile ("nop");
+	report("running a guest with interrupt acknowledgement set", timer_fired);
 }
 
 static int interrupt_exit_handler(void)
@@ -1307,6 +1317,11 @@ static int interrupt_exit_handler(void)
 			vmcs_write(PIN_CONTROLS,
 				   vmcs_read(PIN_CONTROLS) | PIN_EXTINT);
 			break;
+		case 7:
+			vmcs_write(EXI_CONTROLS, vmcs_read(EXI_CONTROLS) | EXI_INTA);
+			vmcs_write(PIN_CONTROLS,
+				   vmcs_read(PIN_CONTROLS) | PIN_EXTINT);
+			break;
 		case 1:
 		case 3:
 			vmcs_write(PIN_CONTROLS,
@@ -1321,9 +1336,14 @@ static int interrupt_exit_handler(void)
 		vmcs_write(GUEST_RIP, guest_rip + insn_len);
 		return VMX_TEST_RESUME;
 	case VMX_EXTINT:
-		irq_enable();
-		asm volatile ("nop");
-		irq_disable();
+		if (vmcs_read(EXI_CONTROLS) & EXI_INTA) {
+			int vector = vmcs_read(EXI_INTR_INFO) & 0xff;
+			handle_external_interrupt(vector);
+		} else {
+			irq_enable();
+			asm volatile ("nop");
+			irq_disable();
+		}
 		if (get_stage() >= 2) {
 			vmcs_write(GUEST_ACTV_STATE, ACTV_ACTIVE);
 			vmcs_write(GUEST_RIP, guest_rip + insn_len);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes
  2014-06-03 20:27 [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Bandan Das
  2014-06-03 20:27 ` [PATCH kvm-unit-tests 1/2] VMX: check for supported contexts before calling invept Bandan Das
  2014-06-03 20:27 ` [PATCH kvm-unit-tests 2/2] VMX: Add test for interrupt acknowledgement Bandan Das
@ 2014-06-04  9:50 ` Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2014-06-04  9:50 UTC (permalink / raw)
  To: Bandan Das, kvm; +Cc: Jan Kiszka

Il 03/06/2014 22:27, Bandan Das ha scritto:
> Adds a simple test for interrupt acknowledgement and change
> invept behavior to check for supported invalidation contexts
>
> Bandan Das (2):
>   VMX: check for supported contexts before calling invept
>   VMX: Add test for interrupt acknowledgement
>
>  lib/x86/isr.c   | 32 ++++++++++++++++++++++++++++++++
>  lib/x86/isr.h   |  2 +-
>  x86/vmx.c       | 20 ++++++++++++++++++++
>  x86/vmx.h       |  1 +
>  x86/vmx_tests.c | 40 ++++++++++++++++++++++++++++++----------
>  5 files changed, 84 insertions(+), 11 deletions(-)
>

Applied, thanks!

Paolo

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-06-04  9:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-03 20:27 [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Bandan Das
2014-06-03 20:27 ` [PATCH kvm-unit-tests 1/2] VMX: check for supported contexts before calling invept Bandan Das
2014-06-03 20:27 ` [PATCH kvm-unit-tests 2/2] VMX: Add test for interrupt acknowledgement Bandan Das
2014-06-04  9:50 ` [PATCH kvm-unit-tests 0/2] nvmx unit test cases changes Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.