[PATCH 1/3] Test: x86: Move setter/getter for Debug registers to common library

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

 



The setter/getter functions for the DR0..DR4 registers exist in debug.c
test and hence they can not be re-used by other tests. Therefore, move
them to the common library.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
---
 lib/x86/processor.h | 32 ++++++++++++++++++
 x86/debug.c         | 79 +++++++++++----------------------------------
 2 files changed, 51 insertions(+), 60 deletions(-)

diff --git a/lib/x86/processor.h b/lib/x86/processor.h
index 173520f..ec2e508 100644
--- a/lib/x86/processor.h
+++ b/lib/x86/processor.h
@@ -470,6 +470,38 @@ static inline u16 str(void)
     return val;
 }
 
+static inline void write_dr0(void *val)
+{
+    asm volatile ("mov %0, %%dr0" : : "r"(val) : "memory");
+}
+
+static inline void write_dr1(void *val)
+{
+    asm volatile ("mov %0, %%dr1" : : "r"(val) : "memory");
+}
+
+static inline void write_dr2(void *val)
+{
+    asm volatile ("mov %0, %%dr2" : : "r"(val) : "memory");
+}
+
+static inline void write_dr3(void *val)
+{
+    asm volatile ("mov %0, %%dr3" : : "r"(val) : "memory");
+}
+
+static inline void write_dr4(ulong val)
+{
+    asm volatile ("mov %0, %%dr4" : : "r"(val) : "memory");
+}
+
+static inline ulong read_dr4(void)
+{
+    ulong val;
+    asm volatile ("mov %%dr4, %0" : "=r"(val));
+    return val;
+}
+
 static inline void write_dr6(ulong val)
 {
     asm volatile ("mov %0, %%dr6" : : "r"(val) : "memory");
diff --git a/x86/debug.c b/x86/debug.c
index 382fdde..6b3ff4e 100644
--- a/x86/debug.c
+++ b/x86/debug.c
@@ -18,58 +18,17 @@ static volatile unsigned long db_addr[10], dr6[10];
 static volatile unsigned int n;
 static volatile unsigned long value;
 
-static unsigned long get_dr4(void)
-{
-	unsigned long value;
-
-	asm volatile("mov %%dr4, %0" : "=r" (value));
-	return value;
-}
-
-static unsigned long get_dr6(void)
-{
-	unsigned long value;
-
-	asm volatile("mov %%dr6,%0" : "=r" (value));
-	return value;
-}
-
-static void set_dr0(void *value)
-{
-	asm volatile("mov %0,%%dr0" : : "r" (value));
-}
-
-static void set_dr1(void *value)
-{
-	asm volatile("mov %0,%%dr1" : : "r" (value));
-}
-
-static void set_dr4(unsigned long value)
-{
-	asm volatile("mov %0,%%dr4" : : "r" (value));
-}
-
-static void set_dr6(unsigned long value)
-{
-	asm volatile("mov %0,%%dr6" : : "r" (value));
-}
-
-static void set_dr7(unsigned long value)
-{
-	asm volatile("mov %0,%%dr7" : : "r" (value));
-}
-
 static void handle_db(struct ex_regs *regs)
 {
 	db_addr[n] = regs->rip;
-	dr6[n] = get_dr6();
+	dr6[n] = read_dr6();
 
 	if (dr6[n] & 0x1)
 		regs->rflags |= (1 << 16);
 
 	if (++n >= 10) {
 		regs->rflags &= ~(1 << 8);
-		set_dr7(0x00000400);
+		write_dr7(0x00000400);
 	}
 }
 
@@ -105,15 +64,15 @@ int main(int ac, char **av)
 	got_ud = 0;
 	cr4 = read_cr4();
 	write_cr4(cr4 & ~X86_CR4_DE);
-	set_dr4(0);
-	set_dr6(0xffff4ff2);
-	report(get_dr4() == 0xffff4ff2 && !got_ud, "reading DR4 with CR4.DE == 0");
+	write_dr4(0);
+	write_dr6(0xffff4ff2);
+	report(read_dr4() == 0xffff4ff2 && !got_ud, "reading DR4 with CR4.DE == 0");
 
 	cr4 = read_cr4();
 	write_cr4(cr4 | X86_CR4_DE);
-	get_dr4();
+	read_dr4();
 	report(got_ud, "reading DR4 with CR4.DE == 1");
-	set_dr6(0);
+	write_dr6(0);
 
 	extern unsigned char sw_bp;
 	asm volatile("int3; sw_bp:");
@@ -121,8 +80,8 @@ int main(int ac, char **av)
 
 	n = 0;
 	extern unsigned char hw_bp1;
-	set_dr0(&hw_bp1);
-	set_dr7(0x00000402);
+	write_dr0(&hw_bp1);
+	write_dr7(0x00000402);
 	asm volatile("hw_bp1: nop");
 	report(n == 1 &&
 	       db_addr[0] == ((unsigned long)&hw_bp1) && dr6[0] == 0xffff0ff1,
@@ -130,15 +89,15 @@ int main(int ac, char **av)
 
 	n = 0;
 	extern unsigned char hw_bp2;
-	set_dr0(&hw_bp2);
-	set_dr6(0x00004002);
+	write_dr0(&hw_bp2);
+	write_dr6(0x00004002);
 	asm volatile("hw_bp2: nop");
 	report(n == 1 &&
 	       db_addr[0] == ((unsigned long)&hw_bp2) && dr6[0] == 0xffff4ff1,
 	       "hw breakpoint (test that dr6.BS is not cleared)");
 
 	n = 0;
-	set_dr6(0);
+	write_dr6(0);
 	asm volatile(
 		"pushf\n\t"
 		"pop %%rax\n\t"
@@ -161,7 +120,7 @@ int main(int ac, char **av)
 	 * emulated. Test that single stepping works on emulated instructions.
 	 */
 	n = 0;
-	set_dr6(0);
+	write_dr6(0);
 	asm volatile(
 		"pushf\n\t"
 		"pop %%rax\n\t"
@@ -188,8 +147,8 @@ int main(int ac, char **av)
 	       "single step emulated instructions");
 
 	n = 0;
-	set_dr1((void *)&value);
-	set_dr7(0x00d0040a); // 4-byte write
+	write_dr1((void *)&value);
+	write_dr7(0x00d0040a); // 4-byte write
 
 	extern unsigned char hw_wp1;
 	asm volatile(
@@ -201,7 +160,7 @@ int main(int ac, char **av)
 	       "hw watchpoint (test that dr6.BS is not cleared)");
 
 	n = 0;
-	set_dr6(0);
+	write_dr6(0);
 
 	extern unsigned char hw_wp2;
 	asm volatile(
@@ -213,16 +172,16 @@ int main(int ac, char **av)
 	       "hw watchpoint (test that dr6.BS is not set)");
 
 	n = 0;
-	set_dr6(0);
+	write_dr6(0);
 	extern unsigned char sw_icebp;
 	asm volatile(".byte 0xf1; sw_icebp:");
 	report(n == 1 &&
 	       db_addr[0] == (unsigned long)&sw_icebp && dr6[0] == 0xffff0ff0,
 	       "icebp");
 
-	set_dr7(0x400);
+	write_dr7(0x400);
 	value = KERNEL_DS;
-	set_dr7(0x00f0040a); // 4-byte read or write
+	write_dr7(0x00f0040a); // 4-byte read or write
 
 	/*
 	 * Each invocation of the handler should shift n by 1 and set bit 0 to 1.
-- 
2.27.0




[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