1#ifndef _ASM_X86_DEBUGREG_H 2#define _ASM_X86_DEBUGREG_H 3 4 5#include <linux/bug.h> 6#include <uapi/asm/debugreg.h> 7 8DECLARE_PER_CPU(unsigned long, cpu_dr7); 9 10#ifndef CONFIG_PARAVIRT 11/* 12 * These special macros can be used to get or set a debugging register 13 */ 14#define get_debugreg(var, register) \ 15 (var) = native_get_debugreg(register) 16#define set_debugreg(value, register) \ 17 native_set_debugreg(register, value) 18#endif 19 20static inline unsigned long native_get_debugreg(int regno) 21{ 22 unsigned long val = 0; /* Damn you, gcc! */ 23 24 switch (regno) { 25 case 0: 26 asm("mov %%db0, %0" :"=r" (val)); 27 break; 28 case 1: 29 asm("mov %%db1, %0" :"=r" (val)); 30 break; 31 case 2: 32 asm("mov %%db2, %0" :"=r" (val)); 33 break; 34 case 3: 35 asm("mov %%db3, %0" :"=r" (val)); 36 break; 37 case 6: 38 asm("mov %%db6, %0" :"=r" (val)); 39 break; 40 case 7: 41 asm("mov %%db7, %0" :"=r" (val)); 42 break; 43 default: 44 BUG(); 45 } 46 return val; 47} 48 49static inline void native_set_debugreg(int regno, unsigned long value) 50{ 51 switch (regno) { 52 case 0: 53 asm("mov %0, %%db0" ::"r" (value)); 54 break; 55 case 1: 56 asm("mov %0, %%db1" ::"r" (value)); 57 break; 58 case 2: 59 asm("mov %0, %%db2" ::"r" (value)); 60 break; 61 case 3: 62 asm("mov %0, %%db3" ::"r" (value)); 63 break; 64 case 6: 65 asm("mov %0, %%db6" ::"r" (value)); 66 break; 67 case 7: 68 asm("mov %0, %%db7" ::"r" (value)); 69 break; 70 default: 71 BUG(); 72 } 73} 74 75static inline void hw_breakpoint_disable(void) 76{ 77 /* Zero the control register for HW Breakpoint */ 78 set_debugreg(0UL, 7); 79 80 /* Zero-out the individual HW breakpoint address registers */ 81 set_debugreg(0UL, 0); 82 set_debugreg(0UL, 1); 83 set_debugreg(0UL, 2); 84 set_debugreg(0UL, 3); 85} 86 87static inline int hw_breakpoint_active(void) 88{ 89 return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK; 90} 91 92extern void aout_dump_debugregs(struct user *dump); 93 94extern void hw_breakpoint_restore(void); 95 96#ifdef CONFIG_X86_64 97DECLARE_PER_CPU(int, debug_stack_usage); 98static inline void debug_stack_usage_inc(void) 99{ 100 __this_cpu_inc(debug_stack_usage); 101} 102static inline void debug_stack_usage_dec(void) 103{ 104 __this_cpu_dec(debug_stack_usage); 105} 106int is_debug_stack(unsigned long addr); 107void debug_stack_set_zero(void); 108void debug_stack_reset(void); 109#else /* !X86_64 */ 110static inline int is_debug_stack(unsigned long addr) { return 0; } 111static inline void debug_stack_set_zero(void) { } 112static inline void debug_stack_reset(void) { } 113static inline void debug_stack_usage_inc(void) { } 114static inline void debug_stack_usage_dec(void) { } 115#endif /* X86_64 */ 116 117#ifdef CONFIG_CPU_SUP_AMD 118extern void set_dr_addr_mask(unsigned long mask, int dr); 119#else 120static inline void set_dr_addr_mask(unsigned long mask, int dr) { } 121#endif 122 123#endif /* _ASM_X86_DEBUGREG_H */ 124