aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/msr.h3
-rw-r--r--arch/x86/lib/msr.c26
-rw-r--r--drivers/edac/amd64_edac.c46
3 files changed, 42 insertions, 33 deletions
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 5bef931f8b14..2d228fc9b4b7 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -244,6 +244,9 @@ do { \
244 244
245#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0) 245#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
246 246
247struct msr *msrs_alloc(void);
248void msrs_free(struct msr *msrs);
249
247#ifdef CONFIG_SMP 250#ifdef CONFIG_SMP
248int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); 251int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
249int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); 252int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 41628b104b9e..872834177937 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -7,7 +7,6 @@ struct msr_info {
7 u32 msr_no; 7 u32 msr_no;
8 struct msr reg; 8 struct msr reg;
9 struct msr *msrs; 9 struct msr *msrs;
10 int off;
11 int err; 10 int err;
12}; 11};
13 12
@@ -18,7 +17,7 @@ static void __rdmsr_on_cpu(void *info)
18 int this_cpu = raw_smp_processor_id(); 17 int this_cpu = raw_smp_processor_id();
19 18
20 if (rv->msrs) 19 if (rv->msrs)
21 reg = &rv->msrs[this_cpu - rv->off]; 20 reg = per_cpu_ptr(rv->msrs, this_cpu);
22 else 21 else
23 reg = &rv->reg; 22 reg = &rv->reg;
24 23
@@ -32,7 +31,7 @@ static void __wrmsr_on_cpu(void *info)
32 int this_cpu = raw_smp_processor_id(); 31 int this_cpu = raw_smp_processor_id();
33 32
34 if (rv->msrs) 33 if (rv->msrs)
35 reg = &rv->msrs[this_cpu - rv->off]; 34 reg = per_cpu_ptr(rv->msrs, this_cpu);
36 else 35 else
37 reg = &rv->reg; 36 reg = &rv->reg;
38 37
@@ -80,7 +79,6 @@ static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
80 79
81 memset(&rv, 0, sizeof(rv)); 80 memset(&rv, 0, sizeof(rv));
82 81
83 rv.off = cpumask_first(mask);
84 rv.msrs = msrs; 82 rv.msrs = msrs;
85 rv.msr_no = msr_no; 83 rv.msr_no = msr_no;
86 84
@@ -120,6 +118,26 @@ void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
120} 118}
121EXPORT_SYMBOL(wrmsr_on_cpus); 119EXPORT_SYMBOL(wrmsr_on_cpus);
122 120
121struct msr *msrs_alloc(void)
122{
123 struct msr *msrs = NULL;
124
125 msrs = alloc_percpu(struct msr);
126 if (!msrs) {
127 pr_warning("%s: error allocating msrs\n", __func__);
128 return NULL;
129 }
130
131 return msrs;
132}
133EXPORT_SYMBOL(msrs_alloc);
134
135void msrs_free(struct msr *msrs)
136{
137 free_percpu(msrs);
138}
139EXPORT_SYMBOL(msrs_free);
140
123/* These "safe" variants are slower and should be used when the target MSR 141/* These "safe" variants are slower and should be used when the target MSR
124 may not actually exist. */ 142 may not actually exist. */
125static void __rdmsr_safe_on_cpu(void *info) 143static void __rdmsr_safe_on_cpu(void *info)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 5fdd6daa40ea..df5b68433f34 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -13,6 +13,8 @@ module_param(report_gart_errors, int, 0644);
13static int ecc_enable_override; 13static int ecc_enable_override;
14module_param(ecc_enable_override, int, 0644); 14module_param(ecc_enable_override, int, 0644);
15 15
16static struct msr *msrs;
17
16/* Lookup table for all possible MC control instances */ 18/* Lookup table for all possible MC control instances */
17struct amd64_pvt; 19struct amd64_pvt;
18static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES]; 20static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
@@ -2495,8 +2497,7 @@ static void get_cpus_on_this_dct_cpumask(struct cpumask *mask, int nid)
2495static bool amd64_nb_mce_bank_enabled_on_node(int nid) 2497static bool amd64_nb_mce_bank_enabled_on_node(int nid)
2496{ 2498{
2497 cpumask_var_t mask; 2499 cpumask_var_t mask;
2498 struct msr *msrs; 2500 int cpu, nbe;
2499 int cpu, nbe, idx = 0;
2500 bool ret = false; 2501 bool ret = false;
2501 2502
2502 if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) { 2503 if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
@@ -2507,32 +2508,22 @@ static bool amd64_nb_mce_bank_enabled_on_node(int nid)
2507 2508
2508 get_cpus_on_this_dct_cpumask(mask, nid); 2509 get_cpus_on_this_dct_cpumask(mask, nid);
2509 2510
2510 msrs = kzalloc(sizeof(struct msr) * cpumask_weight(mask), GFP_KERNEL);
2511 if (!msrs) {
2512 amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
2513 __func__);
2514 free_cpumask_var(mask);
2515 return false;
2516 }
2517
2518 rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs); 2511 rdmsr_on_cpus(mask, MSR_IA32_MCG_CTL, msrs);
2519 2512
2520 for_each_cpu(cpu, mask) { 2513 for_each_cpu(cpu, mask) {
2521 nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE; 2514 struct msr *reg = per_cpu_ptr(msrs, cpu);
2515 nbe = reg->l & K8_MSR_MCGCTL_NBE;
2522 2516
2523 debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n", 2517 debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
2524 cpu, msrs[idx].q, 2518 cpu, reg->q,
2525 (nbe ? "enabled" : "disabled")); 2519 (nbe ? "enabled" : "disabled"));
2526 2520
2527 if (!nbe) 2521 if (!nbe)
2528 goto out; 2522 goto out;
2529
2530 idx++;
2531 } 2523 }
2532 ret = true; 2524 ret = true;
2533 2525
2534out: 2526out:
2535 kfree(msrs);
2536 free_cpumask_var(mask); 2527 free_cpumask_var(mask);
2537 return ret; 2528 return ret;
2538} 2529}
@@ -2540,8 +2531,7 @@ out:
2540static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on) 2531static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
2541{ 2532{
2542 cpumask_var_t cmask; 2533 cpumask_var_t cmask;
2543 struct msr *msrs = NULL; 2534 int cpu;
2544 int cpu, idx = 0;
2545 2535
2546 if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) { 2536 if (!zalloc_cpumask_var(&cmask, GFP_KERNEL)) {
2547 amd64_printk(KERN_WARNING, "%s: error allocating mask\n", 2537 amd64_printk(KERN_WARNING, "%s: error allocating mask\n",
@@ -2551,34 +2541,27 @@ static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
2551 2541
2552 get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id); 2542 get_cpus_on_this_dct_cpumask(cmask, pvt->mc_node_id);
2553 2543
2554 msrs = kzalloc(sizeof(struct msr) * cpumask_weight(cmask), GFP_KERNEL);
2555 if (!msrs) {
2556 amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
2557 __func__);
2558 return -ENOMEM;
2559 }
2560
2561 rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs); 2544 rdmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
2562 2545
2563 for_each_cpu(cpu, cmask) { 2546 for_each_cpu(cpu, cmask) {
2564 2547
2548 struct msr *reg = per_cpu_ptr(msrs, cpu);
2549
2565 if (on) { 2550 if (on) {
2566 if (msrs[idx].l & K8_MSR_MCGCTL_NBE) 2551 if (reg->l & K8_MSR_MCGCTL_NBE)
2567 pvt->flags.ecc_report = 1; 2552 pvt->flags.ecc_report = 1;
2568 2553
2569 msrs[idx].l |= K8_MSR_MCGCTL_NBE; 2554 reg->l |= K8_MSR_MCGCTL_NBE;
2570 } else { 2555 } else {
2571 /* 2556 /*
2572 * Turn off ECC reporting only when it was off before 2557 * Turn off ECC reporting only when it was off before
2573 */ 2558 */
2574 if (!pvt->flags.ecc_report) 2559 if (!pvt->flags.ecc_report)
2575 msrs[idx].l &= ~K8_MSR_MCGCTL_NBE; 2560 reg->l &= ~K8_MSR_MCGCTL_NBE;
2576 } 2561 }
2577 idx++;
2578 } 2562 }
2579 wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs); 2563 wrmsr_on_cpus(cmask, MSR_IA32_MCG_CTL, msrs);
2580 2564
2581 kfree(msrs);
2582 free_cpumask_var(cmask); 2565 free_cpumask_var(cmask);
2583 2566
2584 return 0; 2567 return 0;
@@ -3036,6 +3019,8 @@ static int __init amd64_edac_init(void)
3036 if (cache_k8_northbridges() < 0) 3019 if (cache_k8_northbridges() < 0)
3037 return err; 3020 return err;
3038 3021
3022 msrs = msrs_alloc();
3023
3039 err = pci_register_driver(&amd64_pci_driver); 3024 err = pci_register_driver(&amd64_pci_driver);
3040 if (err) 3025 if (err)
3041 return err; 3026 return err;
@@ -3071,6 +3056,9 @@ static void __exit amd64_edac_exit(void)
3071 edac_pci_release_generic_ctl(amd64_ctl_pci); 3056 edac_pci_release_generic_ctl(amd64_ctl_pci);
3072 3057
3073 pci_unregister_driver(&amd64_pci_driver); 3058 pci_unregister_driver(&amd64_pci_driver);
3059
3060 msrs_free(msrs);
3061 msrs = NULL;
3074} 3062}
3075 3063
3076module_init(amd64_edac_init); 3064module_init(amd64_edac_init);