| .. | .. |
|---|
| 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); |
|---|