On Sun, 2013-07-21 at 09:54 +0100, Roger Leigh wrote:
> If the bug is in amd64_edac_mod, there are only two possible commits
> which could cause the problem:
> 
> 1eef12825 amd64_edac: Correct DIMM sizes
> 94c1acf2c amd64_edac: Add Family 16h support
> 
> Which are the only commits between 3.8 and 3.9 (and none made since)

The crash is at this line:

                        csrow->channels[1]->dimm->nr_pages = row_dct1_pages;

with csrow->channels[1]->dimm == NULL.

This code was introduced by the first commit above.  Does the patch
below fix this?

Ben.

---
[PATCH] amd64_edac: Fix crash in init_csrows() for memory controller in 64-bit 
mode

init_csrows() assumes all processesors after K8 have 2 memory channels.
But these processors support a mode where only one channel is used.
It seems that csrow_enabled() may still return true for the second
channel (BIOS bug?).

Check pvt->channel_count before csrow_enabled(), and remove the family
number conditions.

Reported-by: Roger Leigh <rle...@debian.org>
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
Cc: 717...@bugs.debian.org
---
 drivers/edac/amd64_edac.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 8b6a034..be9c2fe 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2084,10 +2084,8 @@ static int init_csrows(struct mem_ctl_info *mci)
         */
        for_each_chip_select(i, 0, pvt) {
                bool row_dct0 = !!csrow_enabled(i, 0, pvt);
-               bool row_dct1 = false;
-
-               if (boot_cpu_data.x86 != 0xf)
-                       row_dct1 = !!csrow_enabled(i, 1, pvt);
+               bool row_dct1 = (pvt->channel_count == 2 &&
+                                csrow_enabled(i, 1, pvt));
 
                if (!row_dct0 && !row_dct1)
                        continue;
@@ -2103,8 +2101,7 @@ static int init_csrows(struct mem_ctl_info *mci)
                        csrow->channels[0]->dimm->nr_pages = nr_pages;
                }
 
-               /* K8 has only one DCT */
-               if (boot_cpu_data.x86 != 0xf && row_dct1) {
+               if (row_dct1) {
                        int row_dct1_pages = amd64_csrow_nr_pages(pvt, 1, i);
 
                        csrow->channels[1]->dimm->nr_pages = row_dct1_pages;


-- 
Ben Hutchings
The most exhausting thing in life is being insincere. - Anne Morrow Lindberg

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to