.. | .. |
---|
176 | 176 | } |
---|
177 | 177 | EXPORT_SYMBOL_GPL(mce_unregister_decode_chain); |
---|
178 | 178 | |
---|
179 | | -static inline u32 ctl_reg(int bank) |
---|
| 179 | +u32 mca_msr_reg(int bank, enum mca_msr reg) |
---|
180 | 180 | { |
---|
181 | | - return MSR_IA32_MCx_CTL(bank); |
---|
182 | | -} |
---|
| 181 | + if (mce_flags.smca) { |
---|
| 182 | + switch (reg) { |
---|
| 183 | + case MCA_CTL: return MSR_AMD64_SMCA_MCx_CTL(bank); |
---|
| 184 | + case MCA_ADDR: return MSR_AMD64_SMCA_MCx_ADDR(bank); |
---|
| 185 | + case MCA_MISC: return MSR_AMD64_SMCA_MCx_MISC(bank); |
---|
| 186 | + case MCA_STATUS: return MSR_AMD64_SMCA_MCx_STATUS(bank); |
---|
| 187 | + } |
---|
| 188 | + } |
---|
183 | 189 | |
---|
184 | | -static inline u32 status_reg(int bank) |
---|
185 | | -{ |
---|
186 | | - return MSR_IA32_MCx_STATUS(bank); |
---|
187 | | -} |
---|
| 190 | + switch (reg) { |
---|
| 191 | + case MCA_CTL: return MSR_IA32_MCx_CTL(bank); |
---|
| 192 | + case MCA_ADDR: return MSR_IA32_MCx_ADDR(bank); |
---|
| 193 | + case MCA_MISC: return MSR_IA32_MCx_MISC(bank); |
---|
| 194 | + case MCA_STATUS: return MSR_IA32_MCx_STATUS(bank); |
---|
| 195 | + } |
---|
188 | 196 | |
---|
189 | | -static inline u32 addr_reg(int bank) |
---|
190 | | -{ |
---|
191 | | - return MSR_IA32_MCx_ADDR(bank); |
---|
| 197 | + return 0; |
---|
192 | 198 | } |
---|
193 | | - |
---|
194 | | -static inline u32 misc_reg(int bank) |
---|
195 | | -{ |
---|
196 | | - return MSR_IA32_MCx_MISC(bank); |
---|
197 | | -} |
---|
198 | | - |
---|
199 | | -static inline u32 smca_ctl_reg(int bank) |
---|
200 | | -{ |
---|
201 | | - return MSR_AMD64_SMCA_MCx_CTL(bank); |
---|
202 | | -} |
---|
203 | | - |
---|
204 | | -static inline u32 smca_status_reg(int bank) |
---|
205 | | -{ |
---|
206 | | - return MSR_AMD64_SMCA_MCx_STATUS(bank); |
---|
207 | | -} |
---|
208 | | - |
---|
209 | | -static inline u32 smca_addr_reg(int bank) |
---|
210 | | -{ |
---|
211 | | - return MSR_AMD64_SMCA_MCx_ADDR(bank); |
---|
212 | | -} |
---|
213 | | - |
---|
214 | | -static inline u32 smca_misc_reg(int bank) |
---|
215 | | -{ |
---|
216 | | - return MSR_AMD64_SMCA_MCx_MISC(bank); |
---|
217 | | -} |
---|
218 | | - |
---|
219 | | -struct mca_msr_regs msr_ops = { |
---|
220 | | - .ctl = ctl_reg, |
---|
221 | | - .status = status_reg, |
---|
222 | | - .addr = addr_reg, |
---|
223 | | - .misc = misc_reg |
---|
224 | | -}; |
---|
225 | 199 | |
---|
226 | 200 | static void __print_mce(struct mce *m) |
---|
227 | 201 | { |
---|
.. | .. |
---|
371 | 345 | |
---|
372 | 346 | if (msr == mca_cfg.rip_msr) |
---|
373 | 347 | return offsetof(struct mce, ip); |
---|
374 | | - if (msr == msr_ops.status(bank)) |
---|
| 348 | + if (msr == mca_msr_reg(bank, MCA_STATUS)) |
---|
375 | 349 | return offsetof(struct mce, status); |
---|
376 | | - if (msr == msr_ops.addr(bank)) |
---|
| 350 | + if (msr == mca_msr_reg(bank, MCA_ADDR)) |
---|
377 | 351 | return offsetof(struct mce, addr); |
---|
378 | | - if (msr == msr_ops.misc(bank)) |
---|
| 352 | + if (msr == mca_msr_reg(bank, MCA_MISC)) |
---|
379 | 353 | return offsetof(struct mce, misc); |
---|
380 | 354 | if (msr == MSR_IA32_MCG_STATUS) |
---|
381 | 355 | return offsetof(struct mce, mcgstatus); |
---|
.. | .. |
---|
694 | 668 | static noinstr void mce_read_aux(struct mce *m, int i) |
---|
695 | 669 | { |
---|
696 | 670 | if (m->status & MCI_STATUS_MISCV) |
---|
697 | | - m->misc = mce_rdmsrl(msr_ops.misc(i)); |
---|
| 671 | + m->misc = mce_rdmsrl(mca_msr_reg(i, MCA_MISC)); |
---|
698 | 672 | |
---|
699 | 673 | if (m->status & MCI_STATUS_ADDRV) { |
---|
700 | | - m->addr = mce_rdmsrl(msr_ops.addr(i)); |
---|
| 674 | + m->addr = mce_rdmsrl(mca_msr_reg(i, MCA_ADDR)); |
---|
701 | 675 | |
---|
702 | 676 | /* |
---|
703 | 677 | * Mask the reported address by the reported granularity. |
---|
.. | .. |
---|
767 | 741 | m.bank = i; |
---|
768 | 742 | |
---|
769 | 743 | barrier(); |
---|
770 | | - m.status = mce_rdmsrl(msr_ops.status(i)); |
---|
| 744 | + m.status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS)); |
---|
771 | 745 | |
---|
772 | 746 | /* If this entry is not valid, ignore it */ |
---|
773 | 747 | if (!(m.status & MCI_STATUS_VAL)) |
---|
.. | .. |
---|
835 | 809 | /* |
---|
836 | 810 | * Clear state for this bank. |
---|
837 | 811 | */ |
---|
838 | | - mce_wrmsrl(msr_ops.status(i), 0); |
---|
| 812 | + mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0); |
---|
839 | 813 | } |
---|
840 | 814 | |
---|
841 | 815 | /* |
---|
.. | .. |
---|
860 | 834 | int i; |
---|
861 | 835 | |
---|
862 | 836 | for (i = 0; i < this_cpu_read(mce_num_banks); i++) { |
---|
863 | | - m->status = mce_rdmsrl(msr_ops.status(i)); |
---|
| 837 | + m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS)); |
---|
864 | 838 | if (!(m->status & MCI_STATUS_VAL)) |
---|
865 | 839 | continue; |
---|
866 | 840 | |
---|
.. | .. |
---|
1149 | 1123 | |
---|
1150 | 1124 | for (i = 0; i < this_cpu_read(mce_num_banks); i++) { |
---|
1151 | 1125 | if (test_bit(i, toclear)) |
---|
1152 | | - mce_wrmsrl(msr_ops.status(i), 0); |
---|
| 1126 | + mce_wrmsrl(mca_msr_reg(i, MCA_STATUS), 0); |
---|
1153 | 1127 | } |
---|
1154 | 1128 | } |
---|
1155 | 1129 | |
---|
.. | .. |
---|
1208 | 1182 | m->addr = 0; |
---|
1209 | 1183 | m->bank = i; |
---|
1210 | 1184 | |
---|
1211 | | - m->status = mce_rdmsrl(msr_ops.status(i)); |
---|
| 1185 | + m->status = mce_rdmsrl(mca_msr_reg(i, MCA_STATUS)); |
---|
1212 | 1186 | if (!(m->status & MCI_STATUS_VAL)) |
---|
1213 | 1187 | continue; |
---|
1214 | 1188 | |
---|
.. | .. |
---|
1704 | 1678 | |
---|
1705 | 1679 | if (!b->init) |
---|
1706 | 1680 | continue; |
---|
1707 | | - wrmsrl(msr_ops.ctl(i), b->ctl); |
---|
1708 | | - wrmsrl(msr_ops.status(i), 0); |
---|
| 1681 | + wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl); |
---|
| 1682 | + wrmsrl(mca_msr_reg(i, MCA_STATUS), 0); |
---|
1709 | 1683 | } |
---|
1710 | 1684 | } |
---|
1711 | 1685 | |
---|
.. | .. |
---|
1731 | 1705 | if (!b->init) |
---|
1732 | 1706 | continue; |
---|
1733 | 1707 | |
---|
1734 | | - rdmsrl(msr_ops.ctl(i), msrval); |
---|
| 1708 | + rdmsrl(mca_msr_reg(i, MCA_CTL), msrval); |
---|
1735 | 1709 | b->init = !!msrval; |
---|
1736 | 1710 | } |
---|
1737 | 1711 | } |
---|
.. | .. |
---|
1890 | 1864 | mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR); |
---|
1891 | 1865 | mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA); |
---|
1892 | 1866 | mce_flags.amd_threshold = 1; |
---|
1893 | | - |
---|
1894 | | - if (mce_flags.smca) { |
---|
1895 | | - msr_ops.ctl = smca_ctl_reg; |
---|
1896 | | - msr_ops.status = smca_status_reg; |
---|
1897 | | - msr_ops.addr = smca_addr_reg; |
---|
1898 | | - msr_ops.misc = smca_misc_reg; |
---|
1899 | | - } |
---|
1900 | 1867 | } |
---|
1901 | 1868 | } |
---|
1902 | 1869 | |
---|
.. | .. |
---|
2272 | 2239 | struct mce_bank *b = &mce_banks[i]; |
---|
2273 | 2240 | |
---|
2274 | 2241 | if (b->init) |
---|
2275 | | - wrmsrl(msr_ops.ctl(i), 0); |
---|
| 2242 | + wrmsrl(mca_msr_reg(i, MCA_CTL), 0); |
---|
2276 | 2243 | } |
---|
2277 | 2244 | return; |
---|
2278 | 2245 | } |
---|
.. | .. |
---|
2342 | 2309 | { |
---|
2343 | 2310 | mce_timer_delete_all(); |
---|
2344 | 2311 | on_each_cpu(mce_cpu_restart, NULL, 1); |
---|
| 2312 | + mce_schedule_work(); |
---|
2345 | 2313 | } |
---|
2346 | 2314 | |
---|
2347 | 2315 | /* Toggle features for corrected errors */ |
---|
.. | .. |
---|
2624 | 2592 | struct mce_bank *b = &mce_banks[i]; |
---|
2625 | 2593 | |
---|
2626 | 2594 | if (b->init) |
---|
2627 | | - wrmsrl(msr_ops.ctl(i), b->ctl); |
---|
| 2595 | + wrmsrl(mca_msr_reg(i, MCA_CTL), b->ctl); |
---|
2628 | 2596 | } |
---|
2629 | 2597 | } |
---|
2630 | 2598 | |
---|