]>
Commit | Line | Data |
---|---|---|
1965aae3 PA |
1 | #ifndef _ASM_X86_DEBUGREG_H |
2 | #define _ASM_X86_DEBUGREG_H | |
21ebddd3 TG |
3 | |
4 | ||
f649e938 | 5 | #include <linux/bug.h> |
af170c50 | 6 | #include <uapi/asm/debugreg.h> |
f649e938 | 7 | |
28b4e0d8 | 8 | DECLARE_PER_CPU(unsigned long, cpu_dr7); |
b332828c | 9 | |
f649e938 PG |
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 | ||
20 | static 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 | ||
49 | static 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 | ||
b332828c P |
75 | static 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 | ||
59d8eb53 FW |
87 | static inline int hw_breakpoint_active(void) |
88 | { | |
0a3aee0d | 89 | return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK; |
59d8eb53 FW |
90 | } |
91 | ||
9f6b3c2c FW |
92 | extern void aout_dump_debugregs(struct user *dump); |
93 | ||
24f1e32c | 94 | extern void hw_breakpoint_restore(void); |
24f1e32c | 95 | |
42181186 SR |
96 | #ifdef CONFIG_X86_64 |
97 | DECLARE_PER_CPU(int, debug_stack_usage); | |
98 | static inline void debug_stack_usage_inc(void) | |
99 | { | |
89cbc767 | 100 | __this_cpu_inc(debug_stack_usage); |
42181186 SR |
101 | } |
102 | static inline void debug_stack_usage_dec(void) | |
103 | { | |
89cbc767 | 104 | __this_cpu_dec(debug_stack_usage); |
42181186 SR |
105 | } |
106 | int is_debug_stack(unsigned long addr); | |
107 | void debug_stack_set_zero(void); | |
108 | void debug_stack_reset(void); | |
109 | #else /* !X86_64 */ | |
110 | static inline int is_debug_stack(unsigned long addr) { return 0; } | |
111 | static inline void debug_stack_set_zero(void) { } | |
112 | static inline void debug_stack_reset(void) { } | |
113 | static inline void debug_stack_usage_inc(void) { } | |
114 | static inline void debug_stack_usage_dec(void) { } | |
115 | #endif /* X86_64 */ | |
116 | ||
d6d55f0b JS |
117 | #ifdef CONFIG_CPU_SUP_AMD |
118 | extern void set_dr_addr_mask(unsigned long mask, int dr); | |
119 | #else | |
120 | static inline void set_dr_addr_mask(unsigned long mask, int dr) { } | |
121 | #endif | |
42181186 | 122 | |
1965aae3 | 123 | #endif /* _ASM_X86_DEBUGREG_H */ |