This test checks that single stepping through CPUID and RDMSR works. Both instructions trigger VM exits and are emulated by the hypervisor. Signed-off-by: Kyle Huey <khuey@xxxxxxxxxxxx> --- x86/debug.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/x86/debug.c b/x86/debug.c index d04de23..fb1fb0d 100644 --- a/x86/debug.c +++ b/x86/debug.c @@ -107,16 +107,47 @@ hw_bp2: "popf\n\t" : "=g" (start) : : "rax"); report("single step", n == 3 && bp_addr[0] == start+1+6 && dr6[0] == 0xffff4ff0 && bp_addr[1] == start+1+6+1 && dr6[1] == 0xffff4ff0 && bp_addr[2] == start+1+6+1+1 && dr6[2] == 0xffff4ff0); + /* + * cpuid and rdmsr (among others) trigger VM exits and are then + * emulated. Test that single stepping works on emulated instructions. + */ + n = 0; + set_dr6(0); + asm volatile( + "pushf\n\t" + "pop %%rax\n\t" + "or $(1<<8),%%rax\n\t" + "push %%rax\n\t" + "lea (%%rip),%0\n\t" + "popf\n\t" + "and $~(1<<8),%%rax\n\t" + "push %%rax\n\t" + "xor %%rax,%%rax\n\t" + "cpuid\n\t" + "movl $0x1a0,%%ecx\n\t" + "rdmsr\n\t" + "popf\n\t" + : "=g" (start) : : "rax", "ebx", "ecx", "edx"); + report("single step emulated instructions", + n == 7 && + bp_addr[0] == start+1+6 && dr6[0] == 0xffff4ff0 && + bp_addr[1] == start+1+6+1 && dr6[1] == 0xffff4ff0 && + bp_addr[2] == start+1+6+1+3 && dr6[2] == 0xffff4ff0 && + bp_addr[3] == start+1+6+1+3+2 && dr6[3] == 0xffff4ff0 && + bp_addr[4] == start+1+6+1+3+2+5 && dr6[4] == 0xffff4ff0 && + bp_addr[5] == start+1+6+1+3+2+5+2 && dr6[4] == 0xffff4ff0 && + bp_addr[6] == start+1+6+1+3+2+5+2+1 && dr6[4] == 0xffff4ff0); + n = 0; set_dr1((void *)&value); set_dr7(0x00d0040a); asm volatile( "mov $42,%%rax\n\t" "mov %%rax,%0\n\t" : "=m" (value) : : "rax"); -- 2.10.2 -- 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