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