[PATCH kvm-unit-tests 4/4] x86: Test BSP change

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Testing whether changing the BSP, followed by INIT works correctly. The APIC ID
is saved after resume and compared. For this test to pass, a fix of QEMU is
needed in addition to a KVM fix.

Signed-off-by: Nadav Amit <namit@xxxxxxxxxxxxxxxxx>
---
 x86/init.c        | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 x86/unittests.cfg |  1 +
 2 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/x86/init.c b/x86/init.c
index 3694d67..2d7ea99 100644
--- a/x86/init.c
+++ b/x86/init.c
@@ -3,6 +3,7 @@
 #include "io.h"
 #include "processor.h"
 #include "msr.h"
+#include "smp.h"
 
 #define CHECK_HARD_RESET	0
 
@@ -36,18 +37,30 @@ static inline void rtc_out(u8 reg, u8 val)
     outb(val, 0x71);
 }
 
+static inline void send_init(void)
+{
+	char *reset_vec = (void*)0xfffffff0;
+
+	reset_vec[0] = 0xeb;
+	reset_vec[1] = 0xfe;
+	apic_icr_write(APIC_DEST_ALLINC | APIC_DEST_PHYSICAL
+		      | APIC_DM_INIT, 0);
+}
+
 extern char resume_start, resume_end;
 
 struct expected_state {
 	bool init;
+	unsigned int bsp;
 };
 
 static struct expected_state expected[] = {
-	{.init = false},
-	{.init = false},
-	{.init = false},
-	{.init = false},
-	{.init = true},
+	{.init = false, .bsp = 0},
+	{.init = false, .bsp = 0},
+	{.init = false, .bsp = 0},
+	{.init = false, .bsp = 0},
+	{.init = true, .bsp = 0},
+	{.init = true, .bsp = 1},
 };
 
 #define state (*(volatile int *)0x2000)
@@ -56,6 +69,7 @@ static struct expected_state expected[] = {
 #define dr0 (*(volatile int*)0x200c)
 #define cr2 (*(volatile int*)0x2010)
 #define sysenter_eip (*(volatile int*)0x2014)
+#define boot_apic_id (*(volatile int *)0x2018)
 
 static void set_test_regs(void)
 {
@@ -84,6 +98,39 @@ static bool check_test_regs(bool init)
 	return error;
 }
 
+static void change_bsp(bool bsp)
+{
+	unsigned long apicbase = rdmsr(MSR_IA32_APICBASE);
+
+	if (bsp)
+		apicbase |= MSR_IA32_APICBASE_BSP;
+	else
+		apicbase &= ~MSR_IA32_APICBASE_BSP;
+        wrmsr(MSR_IA32_APICBASE, apicbase);
+}
+
+static void set_bsp(void *data)
+{
+	set_test_regs();
+	change_bsp(true);
+}
+
+static bool change_bsp_test(void)
+{
+	int ncpus;
+
+	smp_init();
+	ncpus = cpu_count();
+	if (ncpus != 2) {
+		printf("Skipping BSP test\n");
+		return false;
+	}
+	on_cpu(1, set_bsp, NULL);
+	change_bsp(false);
+	return true;
+}
+
+
 int main(int argc, char **argv)
 {
 	volatile u16 *resume_vector_ptr = (u16 *)0x467L;
@@ -110,6 +157,12 @@ int main(int argc, char **argv)
 		if (check_test_regs(expected[state-1].init))
 			bad |= 4;
 
+		if (expected[state-1].bsp != boot_apic_id) {
+			printf("error: wrong BSP: %x expected: %x\n",
+				boot_apic_id, expected[state-1].bsp);
+			bad |= 8;
+		}
+
 #if CHECK_HARD_RESET
 		/*
 		 * Port 92 bit 0 is cleared on system reset.  On a soft reset it
@@ -151,11 +204,17 @@ int main(int argc, char **argv)
 
 	case 4:
 		printf("testing init to BSP... ");
-		apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL
-			      | APIC_DM_INIT, 0);
+		send_init();
 		break;
 
 	case 5:
+		printf("testing init to BSP (2nd core)... ");
+		if (change_bsp_test()) {
+			send_init();
+			break;
+		}
+		state++;	/* fall through */
+	case 6:
 		exit(bad);
 	}
 
@@ -177,6 +236,10 @@ asm (
 	"mov $0x176, %ecx\n"
 	"rdmsr\n"
 	"mov %eax, %cs:0x2014\n"	// sysenter_eip
+	"mov $1, %eax\n"
+	"cpuid\n"
+	"shrl $24, %ebx\n"
+	"mov %ebx, %cs:0x2018\n"	// apic_id
 	"mov $0x0f, %al\n"		// rtc_out(0x0f, 0x00);
 	"out %al, $0x70\n"
 	"mov $0x00, %al\n"
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index d7ddd9d..2d25801 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -85,6 +85,7 @@ arch = x86_64
 
 [init]
 file = init.flat
+smp = 2
 
 [msr]
 file = msr.flat
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux