[kvm-unit-tests PATCH 4/7] x86/debug: Run single-step #DB tests in usermode (and kernel mode)

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

 



Run the single-step #DB tests in usermode in addition to running them in
kernel mode, i.e. run at CPL0 and CPL3.

Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
 x86/debug.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/x86/debug.c b/x86/debug.c
index 4b2fbe97..21f1da0b 100644
--- a/x86/debug.c
+++ b/x86/debug.c
@@ -12,6 +12,7 @@
 #include "libcflat.h"
 #include "processor.h"
 #include "desc.h"
+#include "usermode.h"
 
 static volatile unsigned long bp_addr;
 static volatile unsigned long db_addr[10], dr6[10];
@@ -75,28 +76,43 @@ static void handle_ud(struct ex_regs *regs)
 }
 
 typedef unsigned long (*db_test_fn)(void);
-typedef void (*db_report_fn)(unsigned long);
+typedef void (*db_report_fn)(unsigned long, const char *);
 
 static void __run_single_step_db_test(db_test_fn test, db_report_fn report_fn)
 {
 	unsigned long start;
+	bool ign;
 
 	n = 0;
 	write_dr6(0);
 
 	start = test();
-	report_fn(start);
+	report_fn(start, "");
+
+	n = 0;
+	write_dr6(0);
+	/*
+	 * Run the test in usermode.  Use the expected start RIP from the first
+	 * run, the usermode framework doesn't make it easy to get the expected
+	 * RIP out of the test, and it shouldn't change in any case.  Run the
+	 * test with IOPL=3 so that it can use OUT, CLI, STI, etc...
+	 */
+	set_iopl(3);
+	run_in_user((usermode_func)test, GP_VECTOR, 0, 0, 0, 0, &ign);
+	set_iopl(0);
+
+	report_fn(start, "Usermode ");
 }
 
 #define run_ss_db_test(name) __run_single_step_db_test(name, report_##name)
 
-static void report_singlestep_basic(unsigned long start)
+static void report_singlestep_basic(unsigned long start, const char *usermode)
 {
 	report(n == 3 &&
 	       is_single_step_db(dr6[0]) && db_addr[0] == start &&
 	       is_single_step_db(dr6[1]) && db_addr[1] == start + 1 &&
 	       is_single_step_db(dr6[2]) && db_addr[2] == start + 1 + 1,
-	       "Single-step #DB basic test");
+	       "%sSingle-step #DB basic test", usermode);
 }
 
 static unsigned long singlestep_basic(void)
@@ -122,7 +138,8 @@ static unsigned long singlestep_basic(void)
 	return start;
 }
 
-static void report_singlestep_emulated_instructions(unsigned long start)
+static void report_singlestep_emulated_instructions(unsigned long start,
+						    const char *usermode)
 {
 	report(n == 6 &&
 	       is_single_step_db(dr6[0]) && db_addr[0] == start &&
@@ -131,7 +148,7 @@ static void report_singlestep_emulated_instructions(unsigned long start)
 	       is_single_step_db(dr6[3]) && db_addr[3] == start + 1 + 3 + 2 &&
 	       is_single_step_db(dr6[4]) && db_addr[4] == start + 1 + 3 + 2 + 2 &&
 	       is_single_step_db(dr6[5]) && db_addr[5] == start + 1 + 3 + 2 + 2 + 1,
-	       "Single-step #DB on emulated instructions");
+	       "%sSingle-step #DB on emulated instructions", usermode);
 }
 
 static unsigned long singlestep_emulated_instructions(void)
-- 
2.34.1.703.g22d0c6ccf7-goog




[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