.. | .. |
---|
8 | 8 | |
---|
9 | 9 | DECLARE_PER_CPU(unsigned long, cpu_dr7); |
---|
10 | 10 | |
---|
11 | | -#ifndef CONFIG_PARAVIRT |
---|
| 11 | +#ifndef CONFIG_PARAVIRT_XXL |
---|
12 | 12 | /* |
---|
13 | 13 | * These special macros can be used to get or set a debugging register |
---|
14 | 14 | */ |
---|
.. | .. |
---|
18 | 18 | native_set_debugreg(register, value) |
---|
19 | 19 | #endif |
---|
20 | 20 | |
---|
21 | | -static inline unsigned long native_get_debugreg(int regno) |
---|
| 21 | +static __always_inline unsigned long native_get_debugreg(int regno) |
---|
22 | 22 | { |
---|
23 | 23 | unsigned long val = 0; /* Damn you, gcc! */ |
---|
24 | 24 | |
---|
.. | .. |
---|
47 | 47 | return val; |
---|
48 | 48 | } |
---|
49 | 49 | |
---|
50 | | -static inline void native_set_debugreg(int regno, unsigned long value) |
---|
| 50 | +static __always_inline void native_set_debugreg(int regno, unsigned long value) |
---|
51 | 51 | { |
---|
52 | 52 | switch (regno) { |
---|
53 | 53 | case 0: |
---|
.. | .. |
---|
85 | 85 | set_debugreg(0UL, 3); |
---|
86 | 86 | } |
---|
87 | 87 | |
---|
88 | | -static inline int hw_breakpoint_active(void) |
---|
| 88 | +static __always_inline bool hw_breakpoint_active(void) |
---|
89 | 89 | { |
---|
90 | 90 | return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK; |
---|
91 | 91 | } |
---|
92 | 92 | |
---|
93 | | -extern void aout_dump_debugregs(struct user *dump); |
---|
94 | | - |
---|
95 | 93 | extern void hw_breakpoint_restore(void); |
---|
96 | 94 | |
---|
97 | | -#ifdef CONFIG_X86_64 |
---|
98 | | -DECLARE_PER_CPU(int, debug_stack_usage); |
---|
99 | | -static inline void debug_stack_usage_inc(void) |
---|
| 95 | +static __always_inline unsigned long local_db_save(void) |
---|
100 | 96 | { |
---|
101 | | - __this_cpu_inc(debug_stack_usage); |
---|
| 97 | + unsigned long dr7; |
---|
| 98 | + |
---|
| 99 | + if (static_cpu_has(X86_FEATURE_HYPERVISOR) && !hw_breakpoint_active()) |
---|
| 100 | + return 0; |
---|
| 101 | + |
---|
| 102 | + get_debugreg(dr7, 7); |
---|
| 103 | + dr7 &= ~0x400; /* architecturally set bit */ |
---|
| 104 | + if (dr7) |
---|
| 105 | + set_debugreg(0, 7); |
---|
| 106 | + /* |
---|
| 107 | + * Ensure the compiler doesn't lower the above statements into |
---|
| 108 | + * the critical section; disabling breakpoints late would not |
---|
| 109 | + * be good. |
---|
| 110 | + */ |
---|
| 111 | + barrier(); |
---|
| 112 | + |
---|
| 113 | + return dr7; |
---|
102 | 114 | } |
---|
103 | | -static inline void debug_stack_usage_dec(void) |
---|
| 115 | + |
---|
| 116 | +static __always_inline void local_db_restore(unsigned long dr7) |
---|
104 | 117 | { |
---|
105 | | - __this_cpu_dec(debug_stack_usage); |
---|
| 118 | + /* |
---|
| 119 | + * Ensure the compiler doesn't raise this statement into |
---|
| 120 | + * the critical section; enabling breakpoints early would |
---|
| 121 | + * not be good. |
---|
| 122 | + */ |
---|
| 123 | + barrier(); |
---|
| 124 | + if (dr7) |
---|
| 125 | + set_debugreg(dr7, 7); |
---|
106 | 126 | } |
---|
107 | | -int is_debug_stack(unsigned long addr); |
---|
108 | | -void debug_stack_set_zero(void); |
---|
109 | | -void debug_stack_reset(void); |
---|
110 | | -#else /* !X86_64 */ |
---|
111 | | -static inline int is_debug_stack(unsigned long addr) { return 0; } |
---|
112 | | -static inline void debug_stack_set_zero(void) { } |
---|
113 | | -static inline void debug_stack_reset(void) { } |
---|
114 | | -static inline void debug_stack_usage_inc(void) { } |
---|
115 | | -static inline void debug_stack_usage_dec(void) { } |
---|
116 | | -#endif /* X86_64 */ |
---|
117 | 127 | |
---|
118 | 128 | #ifdef CONFIG_CPU_SUP_AMD |
---|
119 | 129 | extern void set_dr_addr_mask(unsigned long mask, int dr); |
---|