| 
									
										
										
										
											2008-10-22 22:26:29 -07:00
										 |  |  | #ifndef _ASM_X86_DEBUGREG_H
 | 
					
						
							|  |  |  | #define _ASM_X86_DEBUGREG_H
 | 
					
						
							| 
									
										
										
										
											2007-10-17 20:35:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 16:24:09 -05:00
										 |  |  | #include <linux/bug.h>
 | 
					
						
							| 
									
										
										
										
											2012-12-14 22:37:13 +00:00
										 |  |  | #include <uapi/asm/debugreg.h>
 | 
					
						
							| 
									
										
										
										
											2012-01-20 16:24:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-25 22:24:44 +09:00
										 |  |  | DECLARE_PER_CPU(unsigned long, cpu_dr7); | 
					
						
							| 
									
										
										
										
											2009-06-01 23:43:10 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-20 16:24:09 -05:00
										 |  |  | #ifndef CONFIG_PARAVIRT
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * These special macros can be used to get or set a debugging register | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define get_debugreg(var, register)				\
 | 
					
						
							|  |  |  | 	(var) = native_get_debugreg(register) | 
					
						
							|  |  |  | #define set_debugreg(value, register)				\
 | 
					
						
							|  |  |  | 	native_set_debugreg(register, value) | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline unsigned long native_get_debugreg(int regno) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long val = 0;	/* Damn you, gcc! */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (regno) { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							|  |  |  | 		asm("mov %%db0, %0" :"=r" (val)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: | 
					
						
							|  |  |  | 		asm("mov %%db1, %0" :"=r" (val)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 2: | 
					
						
							|  |  |  | 		asm("mov %%db2, %0" :"=r" (val)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 3: | 
					
						
							|  |  |  | 		asm("mov %%db3, %0" :"=r" (val)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 6: | 
					
						
							|  |  |  | 		asm("mov %%db6, %0" :"=r" (val)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 7: | 
					
						
							|  |  |  | 		asm("mov %%db7, %0" :"=r" (val)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return val; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void native_set_debugreg(int regno, unsigned long value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (regno) { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							|  |  |  | 		asm("mov %0, %%db0"	::"r" (value)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: | 
					
						
							|  |  |  | 		asm("mov %0, %%db1"	::"r" (value)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 2: | 
					
						
							|  |  |  | 		asm("mov %0, %%db2"	::"r" (value)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 3: | 
					
						
							|  |  |  | 		asm("mov %0, %%db3"	::"r" (value)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 6: | 
					
						
							|  |  |  | 		asm("mov %0, %%db6"	::"r" (value)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 7: | 
					
						
							|  |  |  | 		asm("mov %0, %%db7"	::"r" (value)); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		BUG(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 23:43:10 +05:30
										 |  |  | static inline void hw_breakpoint_disable(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Zero the control register for HW Breakpoint */ | 
					
						
							|  |  |  | 	set_debugreg(0UL, 7); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Zero-out the individual HW breakpoint address registers */ | 
					
						
							|  |  |  | 	set_debugreg(0UL, 0); | 
					
						
							|  |  |  | 	set_debugreg(0UL, 1); | 
					
						
							|  |  |  | 	set_debugreg(0UL, 2); | 
					
						
							|  |  |  | 	set_debugreg(0UL, 3); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 11:03:12 +01:00
										 |  |  | static inline int hw_breakpoint_active(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-18 16:28:55 +01:00
										 |  |  | 	return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK; | 
					
						
							| 
									
										
										
										
											2009-11-10 11:03:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-09 21:03:43 +01:00
										 |  |  | extern void aout_dump_debugregs(struct user *dump); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-09 19:22:48 +02:00
										 |  |  | extern void hw_breakpoint_restore(void); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-16 11:43:02 -05:00
										 |  |  | #ifdef CONFIG_X86_64
 | 
					
						
							|  |  |  | DECLARE_PER_CPU(int, debug_stack_usage); | 
					
						
							|  |  |  | static inline void debug_stack_usage_inc(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	__get_cpu_var(debug_stack_usage)++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | static inline void debug_stack_usage_dec(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	__get_cpu_var(debug_stack_usage)--; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | int is_debug_stack(unsigned long addr); | 
					
						
							|  |  |  | void debug_stack_set_zero(void); | 
					
						
							|  |  |  | void debug_stack_reset(void); | 
					
						
							|  |  |  | #else /* !X86_64 */
 | 
					
						
							|  |  |  | static inline int is_debug_stack(unsigned long addr) { return 0; } | 
					
						
							|  |  |  | static inline void debug_stack_set_zero(void) { } | 
					
						
							|  |  |  | static inline void debug_stack_reset(void) { } | 
					
						
							|  |  |  | static inline void debug_stack_usage_inc(void) { } | 
					
						
							|  |  |  | static inline void debug_stack_usage_dec(void) { } | 
					
						
							|  |  |  | #endif /* X86_64 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-22 22:26:29 -07:00
										 |  |  | #endif /* _ASM_X86_DEBUGREG_H */
 |