]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
EDAC, sb_edac: Return early on ADDRV bit and address type test
authorQiuxu Zhuo <qiuxu.zhuo@intel.com>
Fri, 7 Sep 2018 23:08:27 +0000 (16:08 -0700)
committerBorislav Petkov <bp@suse.de>
Tue, 11 Sep 2018 08:59:21 +0000 (10:59 +0200)
Users of the mce_register_decode_chain() are called for every logged
error. EDAC drivers should check:

1) Is this a memory error? [bit 7 in status register]
2) Is there a valid address? [bit 58 in status register]
3) Is the address a system address? [bitfield 8:6 in misc register]

The sb_edac driver performed test "1" twice. Waited far too long to
perform check "2". Didn't do check "3" at all.

Fix it by moving the test for valid address from
sbridge_mce_output_error() into sbridge_mce_check_error() and add a test
for the type immediately after. Delete the redundant check for the type
of the error from sbridge_mce_output_error().

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Cc: Aristeu Rozanski <aris@redhat.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: http://lkml.kernel.org/r/20180907230828.13901-2-tony.luck@intel.com
[ Re-word commit message. ]
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
drivers/edac/sb_edac.c

index 6f3b763af7cdfeb8ecc74ee21c1b8a438ea98846..ee2e2e53935f67d08480d647513ff1a52d7b6eae 100644 (file)
@@ -2911,35 +2911,27 @@ static void sbridge_mce_output_error(struct mem_ctl_info *mci,
         *      cccc = channel
         * If the mask doesn't match, report an error to the parsing logic
         */
-       if (! ((errcode & 0xef80) == 0x80)) {
-               optype = "Can't parse: it is not a mem";
-       } else {
-               switch (optypenum) {
-               case 0:
-                       optype = "generic undef request error";
-                       break;
-               case 1:
-                       optype = "memory read error";
-                       break;
-               case 2:
-                       optype = "memory write error";
-                       break;
-               case 3:
-                       optype = "addr/cmd error";
-                       break;
-               case 4:
-                       optype = "memory scrubbing error";
-                       break;
-               default:
-                       optype = "reserved";
-                       break;
-               }
+       switch (optypenum) {
+       case 0:
+               optype = "generic undef request error";
+               break;
+       case 1:
+               optype = "memory read error";
+               break;
+       case 2:
+               optype = "memory write error";
+               break;
+       case 3:
+               optype = "addr/cmd error";
+               break;
+       case 4:
+               optype = "memory scrubbing error";
+               break;
+       default:
+               optype = "reserved";
+               break;
        }
 
-       /* Only decode errors with an valid address (ADDRV) */
-       if (!GET_BITFIELD(m->status, 58, 58))
-               return;
-
        if (pvt->info.type == KNIGHTS_LANDING) {
                if (channel == 14) {
                        edac_dbg(0, "%s%s err_code:%04x:%04x EDRAM bank %d\n",
@@ -3045,17 +3037,11 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
 {
        struct mce *mce = (struct mce *)data;
        struct mem_ctl_info *mci;
-       struct sbridge_pvt *pvt;
        char *type;
 
        if (edac_get_report_status() == EDAC_REPORTING_DISABLED)
                return NOTIFY_DONE;
 
-       mci = get_mci_for_node_id(mce->socketid, IMC0);
-       if (!mci)
-               return NOTIFY_DONE;
-       pvt = mci->pvt_info;
-
        /*
         * Just let mcelog handle it if the error is
         * outside the memory controller. A memory error
@@ -3065,6 +3051,22 @@ static int sbridge_mce_check_error(struct notifier_block *nb, unsigned long val,
        if ((mce->status & 0xefff) >> 7 != 1)
                return NOTIFY_DONE;
 
+       /* Check ADDRV bit in STATUS */
+       if (!GET_BITFIELD(mce->status, 58, 58))
+               return NOTIFY_DONE;
+
+       /* Check MISCV bit in STATUS */
+       if (!GET_BITFIELD(mce->status, 59, 59))
+               return NOTIFY_DONE;
+
+       /* Check address type in MISC (physical address only) */
+       if (GET_BITFIELD(mce->misc, 6, 8) != 2)
+               return NOTIFY_DONE;
+
+       mci = get_mci_for_node_id(mce->socketid, IMC0);
+       if (!mci)
+               return NOTIFY_DONE;
+
        if (mce->mcgstatus & MCG_STATUS_MCIP)
                type = "Exception";
        else