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