Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic...
[safe/jmp/linux-2.6] / drivers / edac / amd64_edac.c
index a8af27a..cf17dbb 100644 (file)
@@ -13,7 +13,7 @@ module_param(report_gart_errors, int, 0644);
 static int ecc_enable_override;
 module_param(ecc_enable_override, int, 0644);
 
-static struct msr *msrs;
+static struct msr __percpu *msrs;
 
 /* Lookup table for all possible MC control instances */
 struct amd64_pvt;
@@ -197,7 +197,7 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
        edac_printk(KERN_DEBUG, EDAC_MC,
                    "pci-read, sdram scrub control value: %d \n", scrubval);
 
-       for (i = 0; ARRAY_SIZE(scrubrates); i++) {
+       for (i = 0; i < ARRAY_SIZE(scrubrates); i++) {
                if (scrubrates[i].scrubval == scrubval) {
                        *bw = scrubrates[i].bandwidth;
                        status = 0;
@@ -2349,7 +2349,7 @@ static void amd64_read_mc_registers(struct amd64_pvt *pvt)
        amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
        amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_0, &pvt->dchr0);
 
-       if (!dct_ganging_enabled(pvt)) {
+       if (!dct_ganging_enabled(pvt) && boot_cpu_data.x86 >= 0x10) {
                amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCLR_1, &pvt->dclr1);
                amd64_read_pci_cfg(pvt->dram_f2_ctl, F10_DCHR_1, &pvt->dchr1);
        }
@@ -2553,14 +2553,14 @@ static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
 
                if (on) {
                        if (reg->l & K8_MSR_MCGCTL_NBE)
-                               pvt->flags.ecc_report = 1;
+                               pvt->flags.nb_mce_enable = 1;
 
                        reg->l |= K8_MSR_MCGCTL_NBE;
                } else {
                        /*
-                        * Turn off ECC reporting only when it was off before
+                        * Turn off NB MCE reporting only when it was off before
                         */
-                       if (!pvt->flags.ecc_report)
+                       if (!pvt->flags.nb_mce_enable)
                                reg->l &= ~K8_MSR_MCGCTL_NBE;
                }
        }
@@ -2571,22 +2571,11 @@ static int amd64_toggle_ecc_err_reporting(struct amd64_pvt *pvt, bool on)
        return 0;
 }
 
-/*
- * Only if 'ecc_enable_override' is set AND BIOS had ECC disabled, do "we"
- * enable it.
- */
 static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
 {
        struct amd64_pvt *pvt = mci->pvt_info;
        u32 value, mask = K8_NBCTL_CECCEn | K8_NBCTL_UECCEn;
 
-       if (!ecc_enable_override)
-               return;
-
-       amd64_printk(KERN_WARNING,
-               "'ecc_enable_override' parameter is active, "
-               "Enabling AMD ECC hardware now: CAUTION\n");
-
        amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCTL, &value);
 
        /* turn on UECCn and CECCEn bits */
@@ -2611,6 +2600,8 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
                        "This node reports that DRAM ECC is "
                        "currently Disabled; ENABLING now\n");
 
+               pvt->flags.nb_ecc_prev = 0;
+
                /* Attempt to turn on DRAM ECC Enable */
                value |= K8_NBCFG_ECC_ENABLE;
                pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCFG, value);
@@ -2625,7 +2616,10 @@ static void amd64_enable_ecc_error_reporting(struct mem_ctl_info *mci)
                        amd64_printk(KERN_DEBUG,
                                "Hardware accepted DRAM ECC Enable\n");
                }
+       } else {
+               pvt->flags.nb_ecc_prev = 1;
        }
+
        debugf0("NBCFG(2)= 0x%x  CHIPKILL= %s ECC_ENABLE= %s\n", value,
                (value & K8_NBCFG_CHIPKILL) ? "Enabled" : "Disabled",
                (value & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled");
@@ -2644,12 +2638,18 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
        value &= ~mask;
        value |= pvt->old_nbctl;
 
-       /* restore the NB Enable MCGCTL bit */
        pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCTL, value);
 
+       /* restore previous BIOS DRAM ECC "off" setting which we force-enabled */
+       if (!pvt->flags.nb_ecc_prev) {
+               amd64_read_pci_cfg(pvt->misc_f3_ctl, K8_NBCFG, &value);
+               value &= ~K8_NBCFG_ECC_ENABLE;
+               pci_write_config_dword(pvt->misc_f3_ctl, K8_NBCFG, value);
+       }
+
+       /* restore the NB Enable MCGCTL bit */
        if (amd64_toggle_ecc_err_reporting(pvt, OFF))
-               amd64_printk(KERN_WARNING, "Error restoring ECC reporting over "
-                                          "MCGCTL!\n");
+               amd64_printk(KERN_WARNING, "Error restoring NB MCGCTL settings!\n");
 }
 
 /*
@@ -2658,10 +2658,11 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
  * the memory system completely. A command line option allows to force-enable
  * hardware ECC later in amd64_enable_ecc_error_reporting().
  */
-static const char *ecc_warning =
-       "WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n"
-       " Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n"
-       " Also, use of the override can cause unknown side effects.\n";
+static const char *ecc_msg =
+       "ECC disabled in the BIOS or no ECC capability, module will not load.\n"
+       " Either enable ECC checking or force module loading by setting "
+       "'ecc_enable_override'.\n"
+       " (Note that use of the override may cause unknown side effects.)\n";
 
 static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 {
@@ -2673,7 +2674,7 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 
        ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE);
        if (!ecc_enabled)
-               amd64_printk(KERN_WARNING, "This node reports that Memory ECC "
+               amd64_printk(KERN_NOTICE, "This node reports that Memory ECC "
                             "is currently disabled, set F3x%x[22] (%s).\n",
                             K8_NBCFG, pci_name(pvt->misc_f3_ctl));
        else
@@ -2681,18 +2682,18 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 
        nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id);
        if (!nb_mce_en)
-               amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR "
+               amd64_printk(KERN_NOTICE, "NB MCE bank disabled, set MSR "
                             "0x%08x[4] on node %d to enable.\n",
                             MSR_IA32_MCG_CTL, pvt->mc_node_id);
 
        if (!ecc_enabled || !nb_mce_en) {
                if (!ecc_enable_override) {
-                       amd64_printk(KERN_WARNING, "%s", ecc_warning);
+                       amd64_printk(KERN_NOTICE, "%s", ecc_msg);
                        return -ENODEV;
+               } else {
+                       amd64_printk(KERN_WARNING, "Forcing ECC checking on!\n");
                }
-       } else
-               /* CLEAR the override, since BIOS controlled it */
-               ecc_enable_override = 0;
+       }
 
        return 0;
 }