diff mbox

[06/13] x2apic: Test for invalid state transitions

Message ID 54ef8db7c3d723cbbf3d486bdbd69c124178557b.1388858359.git.jan.kiszka@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka Jan. 4, 2014, 5:59 p.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

This checks if KVM properly acknowledges invalid state transitions on
MSR_APIC_BASE writes with a #GP.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 lib/x86/apic-defs.h |  3 +++
 x86/apic.c          | 41 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/lib/x86/apic-defs.h b/lib/x86/apic-defs.h
index c061e3d..94112b4 100644
--- a/lib/x86/apic-defs.h
+++ b/lib/x86/apic-defs.h
@@ -9,6 +9,9 @@ 
  */
 
 #define	APIC_DEFAULT_PHYS_BASE	0xfee00000
+#define APIC_BSP		(1UL << 8)
+#define APIC_EXTD		(1UL << 10)
+#define APIC_EN			(1UL << 11)
 
 #define	APIC_ID		0x20
 
diff --git a/x86/apic.c b/x86/apic.c
index d06153f..4ebcd4f 100644
--- a/x86/apic.c
+++ b/x86/apic.c
@@ -4,6 +4,7 @@ 
 #include "smp.h"
 #include "desc.h"
 #include "isr.h"
+#include "msr.h"
 
 static int g_fail;
 static int g_tests;
@@ -70,14 +71,52 @@  static void test_tsc_deadline_timer(void)
     }
 }
 
-#define MSR_APIC_BASE 0x0000001b
+static void do_write_apicbase(void *data)
+{
+    set_exception_return(&&resume);
+    wrmsr(MSR_IA32_APICBASE, *(u64 *)data);
+resume:
+    barrier();
+}
 
 void test_enable_x2apic(void)
 {
+    u64 invalid_state = APIC_DEFAULT_PHYS_BASE | APIC_BSP | APIC_EXTD;
+    u64 apic_enabled = APIC_DEFAULT_PHYS_BASE | APIC_BSP | APIC_EN;
+    u64 x2apic_enabled =
+        APIC_DEFAULT_PHYS_BASE | APIC_BSP | APIC_EN | APIC_EXTD;
+
     if (enable_x2apic()) {
         printf("x2apic enabled\n");
+
+        report("x2apic enabled to invalid state",
+               test_for_exception(GP_VECTOR, do_write_apicbase,
+                                  &invalid_state));
+        report("x2apic enabled to apic enabled",
+               test_for_exception(GP_VECTOR, do_write_apicbase,
+                                  &apic_enabled));
+
+        wrmsr(MSR_IA32_APICBASE, APIC_DEFAULT_PHYS_BASE | APIC_BSP);
+        report("disabled to invalid state",
+               test_for_exception(GP_VECTOR, do_write_apicbase,
+                                  &invalid_state));
+        report("disabled to x2apic enabled",
+               test_for_exception(GP_VECTOR, do_write_apicbase,
+                                  &x2apic_enabled));
+
+        wrmsr(MSR_IA32_APICBASE, apic_enabled);
+        report("apic enabled to invalid state",
+               test_for_exception(GP_VECTOR, do_write_apicbase,
+                                  &invalid_state));
+
+        wrmsr(MSR_IA32_APICBASE, x2apic_enabled);
+        apic_write(APIC_SPIV, 0x1ff);
     } else {
         printf("x2apic not detected\n");
+
+        report("enable unsupported x2apic",
+               test_for_exception(GP_VECTOR, do_write_apicbase,
+                                  &x2apic_enabled));
     }
 }