[PATCH kvm-unit-tests 3/4] x86: check register values after reset

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

 



Checking the reset values of dr0, cr2 and sysenter_eip after reset.  Since INIT
does not initialize certain registers, we keep for each state whether it is
INIT or not. It is also required for the next patch.

Signed-off-by: Nadav Amit <namit@xxxxxxxxxxxxxxxxx>
---
 x86/init.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/x86/init.c b/x86/init.c
index 717bd12..3694d67 100644
--- a/x86/init.c
+++ b/x86/init.c
@@ -1,6 +1,8 @@
 #include "libcflat.h"
 #include "apic.h"
 #include "io.h"
+#include "processor.h"
+#include "msr.h"
 
 #define CHECK_HARD_RESET	0
 
@@ -36,9 +38,51 @@ static inline void rtc_out(u8 reg, u8 val)
 
 extern char resume_start, resume_end;
 
+struct expected_state {
+	bool init;
+};
+
+static struct expected_state expected[] = {
+	{.init = false},
+	{.init = false},
+	{.init = false},
+	{.init = false},
+	{.init = true},
+};
+
 #define state (*(volatile int *)0x2000)
 #define bad (*(volatile int *)0x2004)
 #define resumed (*(volatile int *)0x2008)
+#define dr0 (*(volatile int*)0x200c)
+#define cr2 (*(volatile int*)0x2010)
+#define sysenter_eip (*(volatile int*)0x2014)
+
+static void set_test_regs(void)
+{
+	write_dr0(1);
+	write_cr2(1);
+	wrmsr(MSR_IA32_SYSENTER_EIP, 1);
+}
+
+static bool check_test_regs(bool init)
+{
+	bool error = false;
+
+	if (dr0 != 0) {
+		printf("error: dr0 was not initialized: %x\n", dr0);
+		error = true;
+	}
+	if (cr2 != 0) {
+		printf("error: cr2 was not initialized\n", cr2);
+		error = true;
+	}
+	if (init && sysenter_eip != 1) {
+		printf("wrong sysenter_eip msr: %x\n", sysenter_eip);
+		error = true;
+	}
+
+	return error;
+}
 
 int main(int argc, char **argv)
 {
@@ -63,6 +107,9 @@ int main(int argc, char **argv)
 			bad |= 2;
 		}
 
+		if (check_test_regs(expected[state-1].init))
+			bad |= 4;
+
 #if CHECK_HARD_RESET
 		/*
 		 * Port 92 bit 0 is cleared on system reset.  On a soft reset it
@@ -76,6 +123,7 @@ int main(int argc, char **argv)
 #endif
 	}
 
+	set_test_regs();
 	resumed = 0;
 
 	switch (state++) {
@@ -122,6 +170,13 @@ asm (
 	".code16\n"
 	"resume_start:\n"
 	"incb %cs:0x2008\n"		// resumed++;
+	"mov %dr0, %ecx\n"
+	"mov %ecx, %cs:0x200c\n"	// dr0
+	"mov %cr2, %ecx\n"
+	"mov %ecx, %cs:0x2010\n"	// cr2
+	"mov $0x176, %ecx\n"
+	"rdmsr\n"
+	"mov %eax, %cs:0x2014\n"	// sysenter_eip
 	"mov $0x0f, %al\n"		// rtc_out(0x0f, 0x00);
 	"out %al, $0x70\n"
 	"mov $0x00, %al\n"
-- 
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