diff options
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_intel.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index c5c003291861..1e8bb6c94f14 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
| @@ -146,6 +146,27 @@ void mce_intel_hcpu_update(unsigned long cpu) | |||
| 146 | per_cpu(cmci_storm_state, cpu) = CMCI_STORM_NONE; | 146 | per_cpu(cmci_storm_state, cpu) = CMCI_STORM_NONE; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static void cmci_toggle_interrupt_mode(bool on) | ||
| 150 | { | ||
| 151 | unsigned long flags, *owned; | ||
| 152 | int bank; | ||
| 153 | u64 val; | ||
| 154 | |||
| 155 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | ||
| 156 | owned = this_cpu_ptr(mce_banks_owned); | ||
| 157 | for_each_set_bit(bank, owned, MAX_NR_BANKS) { | ||
| 158 | rdmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
| 159 | |||
| 160 | if (on) | ||
| 161 | val |= MCI_CTL2_CMCI_EN; | ||
| 162 | else | ||
| 163 | val &= ~MCI_CTL2_CMCI_EN; | ||
| 164 | |||
| 165 | wrmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
| 166 | } | ||
| 167 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | ||
| 168 | } | ||
| 169 | |||
| 149 | unsigned long cmci_intel_adjust_timer(unsigned long interval) | 170 | unsigned long cmci_intel_adjust_timer(unsigned long interval) |
| 150 | { | 171 | { |
| 151 | if ((this_cpu_read(cmci_backoff_cnt) > 0) && | 172 | if ((this_cpu_read(cmci_backoff_cnt) > 0) && |
| @@ -175,7 +196,7 @@ unsigned long cmci_intel_adjust_timer(unsigned long interval) | |||
| 175 | */ | 196 | */ |
| 176 | if (!atomic_read(&cmci_storm_on_cpus)) { | 197 | if (!atomic_read(&cmci_storm_on_cpus)) { |
| 177 | __this_cpu_write(cmci_storm_state, CMCI_STORM_NONE); | 198 | __this_cpu_write(cmci_storm_state, CMCI_STORM_NONE); |
| 178 | cmci_reenable(); | 199 | cmci_toggle_interrupt_mode(true); |
| 179 | cmci_recheck(); | 200 | cmci_recheck(); |
| 180 | } | 201 | } |
| 181 | return CMCI_POLL_INTERVAL; | 202 | return CMCI_POLL_INTERVAL; |
| @@ -186,22 +207,6 @@ unsigned long cmci_intel_adjust_timer(unsigned long interval) | |||
| 186 | } | 207 | } |
| 187 | } | 208 | } |
| 188 | 209 | ||
| 189 | static void cmci_storm_disable_banks(void) | ||
| 190 | { | ||
| 191 | unsigned long flags, *owned; | ||
| 192 | int bank; | ||
| 193 | u64 val; | ||
| 194 | |||
| 195 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | ||
| 196 | owned = this_cpu_ptr(mce_banks_owned); | ||
| 197 | for_each_set_bit(bank, owned, MAX_NR_BANKS) { | ||
| 198 | rdmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
| 199 | val &= ~MCI_CTL2_CMCI_EN; | ||
| 200 | wrmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
| 201 | } | ||
| 202 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | ||
| 203 | } | ||
| 204 | |||
| 205 | static bool cmci_storm_detect(void) | 210 | static bool cmci_storm_detect(void) |
| 206 | { | 211 | { |
| 207 | unsigned int cnt = __this_cpu_read(cmci_storm_cnt); | 212 | unsigned int cnt = __this_cpu_read(cmci_storm_cnt); |
| @@ -223,7 +228,7 @@ static bool cmci_storm_detect(void) | |||
| 223 | if (cnt <= CMCI_STORM_THRESHOLD) | 228 | if (cnt <= CMCI_STORM_THRESHOLD) |
| 224 | return false; | 229 | return false; |
| 225 | 230 | ||
| 226 | cmci_storm_disable_banks(); | 231 | cmci_toggle_interrupt_mode(false); |
| 227 | __this_cpu_write(cmci_storm_state, CMCI_STORM_ACTIVE); | 232 | __this_cpu_write(cmci_storm_state, CMCI_STORM_ACTIVE); |
| 228 | r = atomic_add_return(1, &cmci_storm_on_cpus); | 233 | r = atomic_add_return(1, &cmci_storm_on_cpus); |
| 229 | mce_timer_kick(CMCI_STORM_INTERVAL); | 234 | mce_timer_kick(CMCI_STORM_INTERVAL); |
