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