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