|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/broadwell_epex.c mcelog-d2e13bf0/broadwell_epex.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/broadwell_epex.c 2016-11-30 11:23:54.542909636 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/broadwell_epex.c 2016-11-30 11:24:12.203619329 -0500
|
|
|
bb432d |
@@ -23,6 +23,11 @@
|
|
|
bb432d |
#include "broadwell_epex.h"
|
|
|
bb432d |
#include "memdb.h"
|
|
|
bb432d |
|
|
|
bb432d |
+/* Memory error was corrected by mirroring with channel failover */
|
|
|
bb432d |
+#define BDW_MCI_MISC_FO (1ULL<<41)
|
|
|
bb432d |
+/* Memory error was corrected by mirroring and primary channel scrubbed successfully */
|
|
|
bb432d |
+#define BDW_MCI_MISC_MC (1ULL<<42)
|
|
|
bb432d |
+
|
|
|
bb432d |
/* See IA32 SDM Vol3B Table 16-20 */
|
|
|
bb432d |
|
|
|
bb432d |
static char *pcu_1[] = {
|
|
|
bb432d |
@@ -147,3 +152,23 @@ void bdw_epex_decode_model(int cputype,
|
|
|
bb432d |
break;
|
|
|
bb432d |
}
|
|
|
bb432d |
}
|
|
|
bb432d |
+
|
|
|
bb432d |
+/*
|
|
|
bb432d |
+ * return: 0 - CE by normal ECC
|
|
|
bb432d |
+ * 1 - CE by mirroring with channel failover
|
|
|
bb432d |
+ * 2 - CE by mirroring and primary channel scrubbed successfully
|
|
|
bb432d |
+ */
|
|
|
bb432d |
+int bdw_epex_ce_type(int bank, u64 status, u64 misc)
|
|
|
bb432d |
+{
|
|
|
bb432d |
+ if (!(bank == 7 || bank == 8))
|
|
|
bb432d |
+ return 0;
|
|
|
bb432d |
+
|
|
|
bb432d |
+ if (status & MCI_STATUS_MISCV) {
|
|
|
bb432d |
+ if (misc & BDW_MCI_MISC_FO)
|
|
|
bb432d |
+ return 1;
|
|
|
bb432d |
+ if (misc & BDW_MCI_MISC_MC)
|
|
|
bb432d |
+ return 2;
|
|
|
bb432d |
+ }
|
|
|
bb432d |
+
|
|
|
bb432d |
+ return 0;
|
|
|
bb432d |
+}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/broadwell_epex.h mcelog-d2e13bf0/broadwell_epex.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/broadwell_epex.h 2016-11-30 11:23:54.542909636 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/broadwell_epex.h 2016-11-30 11:24:12.203619329 -0500
|
|
|
bb432d |
@@ -1 +1,2 @@
|
|
|
bb432d |
void bdw_epex_decode_model(int cputype, int bank, u64 status, u64 misc);
|
|
|
bb432d |
+int bdw_epex_ce_type(int bank, u64 status, u64 misc);
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/client.c mcelog-d2e13bf0/client.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/client.c 2016-11-30 11:23:54.530909154 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/client.c 2016-11-30 11:24:12.203619329 -0500
|
|
|
bb432d |
@@ -67,3 +67,11 @@ void ask_server(char *command)
|
|
|
bb432d |
|
|
|
bb432d |
SYSERRprintf("client read");
|
|
|
bb432d |
}
|
|
|
bb432d |
+
|
|
|
bb432d |
+void client_cleanup(void)
|
|
|
bb432d |
+{
|
|
|
bb432d |
+ char *path = config_string("server", "socket-path");
|
|
|
bb432d |
+ if (!path)
|
|
|
bb432d |
+ path = SOCKET_PATH;
|
|
|
bb432d |
+ unlink(path);
|
|
|
bb432d |
+}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/client.h mcelog-d2e13bf0/client.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/client.h 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/client.h 2016-11-30 11:24:12.203619329 -0500
|
|
|
bb432d |
@@ -1 +1,2 @@
|
|
|
bb432d |
void ask_server(char *command);
|
|
|
bb432d |
+void client_cleanup(void);
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/db.c mcelog-d2e13bf0/db.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/db.c 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/db.c 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,599 +0,0 @@
|
|
|
bb432d |
-/* Copyright (C) 2006 Andi Kleen, SuSE Labs.
|
|
|
bb432d |
- Dumb database manager.
|
|
|
bb432d |
- not suitable for large datasets, but human readable files and simple.
|
|
|
bb432d |
- assumes groups and entries-per-group are max low double digits.
|
|
|
bb432d |
- the in memory presentation could be easily optimized with a few
|
|
|
bb432d |
- hashes, but that shouldn't be needed for now.
|
|
|
bb432d |
- Note: obsolete, new design uses in memory databases only
|
|
|
bb432d |
-
|
|
|
bb432d |
- mcelog is free software; you can redistribute it and/or
|
|
|
bb432d |
- modify it under the terms of the GNU General Public
|
|
|
bb432d |
- License as published by the Free Software Foundation; version
|
|
|
bb432d |
- 2.
|
|
|
bb432d |
-
|
|
|
bb432d |
- mcelog is distributed in the hope that it will be useful,
|
|
|
bb432d |
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
bb432d |
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
bb432d |
- General Public License for more details.
|
|
|
bb432d |
-
|
|
|
bb432d |
- You should find a copy of v2 of the GNU General Public License somewhere
|
|
|
bb432d |
- on your Linux system; if not, write to the Free Software Foundation,
|
|
|
bb432d |
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
bb432d |
-
|
|
|
bb432d |
-/* TBD:
|
|
|
bb432d |
- add lock file to protect final rename
|
|
|
bb432d |
- timeout for locks
|
|
|
bb432d |
-*/
|
|
|
bb432d |
-
|
|
|
bb432d |
-#define _GNU_SOURCE 1
|
|
|
bb432d |
-#include <stdio.h>
|
|
|
bb432d |
-#include <ctype.h>
|
|
|
bb432d |
-#include <string.h>
|
|
|
bb432d |
-#include <errno.h>
|
|
|
bb432d |
-#include <stdlib.h>
|
|
|
bb432d |
-#include <unistd.h>
|
|
|
bb432d |
-#include <stdarg.h>
|
|
|
bb432d |
-#include <sys/fcntl.h>
|
|
|
bb432d |
-#include <sys/file.h>
|
|
|
bb432d |
-#include <assert.h>
|
|
|
bb432d |
-
|
|
|
bb432d |
-#include "db.h"
|
|
|
bb432d |
-#include "memutil.h"
|
|
|
bb432d |
-
|
|
|
bb432d |
-/* file format
|
|
|
bb432d |
-
|
|
|
bb432d |
-# comment
|
|
|
bb432d |
-[group1]
|
|
|
bb432d |
-entry1: value
|
|
|
bb432d |
-entry2: value
|
|
|
bb432d |
-
|
|
|
bb432d |
-# comment
|
|
|
bb432d |
-# comment2
|
|
|
bb432d |
-[group2]
|
|
|
bb432d |
-entry: value
|
|
|
bb432d |
-
|
|
|
bb432d |
-value is anything before new line, but first will be skipped
|
|
|
bb432d |
-spaces are allowed in entry names or groups
|
|
|
bb432d |
-comments are preserved, but moved in front of the group
|
|
|
bb432d |
-blank lines allowed.
|
|
|
bb432d |
-
|
|
|
bb432d |
-code doesnt check for unique records/entries right now. first wins.
|
|
|
bb432d |
-
|
|
|
bb432d |
-*/
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct entry {
|
|
|
bb432d |
- char *name;
|
|
|
bb432d |
- char *val;
|
|
|
bb432d |
-};
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group {
|
|
|
bb432d |
- struct group *next;
|
|
|
bb432d |
- char *name;
|
|
|
bb432d |
- struct entry *entries;
|
|
|
bb432d |
- char *comment;
|
|
|
bb432d |
- int numentries;
|
|
|
bb432d |
-};
|
|
|
bb432d |
-
|
|
|
bb432d |
-#define ENTRY_CHUNK (128 / sizeof(struct entry))
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct database {
|
|
|
bb432d |
- struct group *groups;
|
|
|
bb432d |
- FILE *fh;
|
|
|
bb432d |
- char *fn;
|
|
|
bb432d |
- int dirty;
|
|
|
bb432d |
-};
|
|
|
bb432d |
-
|
|
|
bb432d |
-static int read_db(struct database *db);
|
|
|
bb432d |
-static FILE *open_file(char *fn, int wr);
|
|
|
bb432d |
-static void free_group(struct group *g);
|
|
|
bb432d |
-
|
|
|
bb432d |
-static void DBerror(char *fmt, ...)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- va_list ap;
|
|
|
bb432d |
- va_start(ap,fmt);
|
|
|
bb432d |
- vfprintf(stderr, fmt, ap);
|
|
|
bb432d |
- va_end(ap);
|
|
|
bb432d |
- exit(1);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-#define DB_NEW(p) ((p) = xalloc(sizeof(*(p))))
|
|
|
bb432d |
-
|
|
|
bb432d |
-static struct group *alloc_group(char *name)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g;
|
|
|
bb432d |
- DB_NEW(g);
|
|
|
bb432d |
- g->entries = xalloc(ENTRY_CHUNK * sizeof(struct entry));
|
|
|
bb432d |
- g->name = name;
|
|
|
bb432d |
- return g;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static char *cleanline(char *s)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char *p;
|
|
|
bb432d |
- while (isspace(*s))
|
|
|
bb432d |
- s++;
|
|
|
bb432d |
- if (*s == 0)
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
- p = strchr(s, '\n');
|
|
|
bb432d |
- if (p)
|
|
|
bb432d |
- *p = 0;
|
|
|
bb432d |
- return s;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct database *open_db(char *fn, int wr)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct database *db;
|
|
|
bb432d |
-
|
|
|
bb432d |
- DB_NEW(db);
|
|
|
bb432d |
- db->fh = open_file(fn, wr);
|
|
|
bb432d |
- if (!db->fh) {
|
|
|
bb432d |
- DBerror("Cannot open database %s\n", fn);
|
|
|
bb432d |
- free(db);
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- db->fn = xstrdup(fn);
|
|
|
bb432d |
- if (read_db(db) < 0) {
|
|
|
bb432d |
- free(db->fn);
|
|
|
bb432d |
- free(db);
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- return db;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static int read_db(struct database *db)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char *line = NULL;
|
|
|
bb432d |
- size_t linesz = 0;
|
|
|
bb432d |
- struct group *group = NULL, **pgroup = &db->groups;
|
|
|
bb432d |
- int linenr = 0;
|
|
|
bb432d |
-
|
|
|
bb432d |
- while (getline(&line, &linesz, db->fh) > 0) {
|
|
|
bb432d |
- char *s;
|
|
|
bb432d |
- s = strchr(line, '#');
|
|
|
bb432d |
- if (s) {
|
|
|
bb432d |
- struct group *cmt;
|
|
|
bb432d |
- DB_NEW(cmt);
|
|
|
bb432d |
- *pgroup = cmt;
|
|
|
bb432d |
- pgroup = &cmt->next;
|
|
|
bb432d |
- cmt->comment = xstrdup(s + 1);
|
|
|
bb432d |
- *s = 0;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- s = cleanline(line);
|
|
|
bb432d |
- linenr++;
|
|
|
bb432d |
- if (!s)
|
|
|
bb432d |
- continue;
|
|
|
bb432d |
- if (*s == '[') {
|
|
|
bb432d |
- int n;
|
|
|
bb432d |
- char *name;
|
|
|
bb432d |
- ++s;
|
|
|
bb432d |
- n = strcspn(s, "]");
|
|
|
bb432d |
- if (s[n] == 0)
|
|
|
bb432d |
- goto parse_error;
|
|
|
bb432d |
- name = xalloc(n + 1);
|
|
|
bb432d |
- memcpy(name, s, n);
|
|
|
bb432d |
- group = alloc_group(name);
|
|
|
bb432d |
- *pgroup = group;
|
|
|
bb432d |
- pgroup = &group->next;
|
|
|
bb432d |
- } else {
|
|
|
bb432d |
- char *p;
|
|
|
bb432d |
- if (!group)
|
|
|
bb432d |
- goto parse_error;
|
|
|
bb432d |
- p = s + strcspn(s, ":");
|
|
|
bb432d |
- if (*p != ':')
|
|
|
bb432d |
- goto parse_error;
|
|
|
bb432d |
- *p++ = 0;
|
|
|
bb432d |
- if (*p == ' ')
|
|
|
bb432d |
- p++;
|
|
|
bb432d |
- else
|
|
|
bb432d |
- goto parse_error;
|
|
|
bb432d |
- change_entry(db, group, line, p);
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
-
|
|
|
bb432d |
- if (ferror(db->fh)) {
|
|
|
bb432d |
- DBerror("IO error while reading database %s: %s\n", db->fn,
|
|
|
bb432d |
- strerror(errno));
|
|
|
bb432d |
- goto error;
|
|
|
bb432d |
- }
|
|
|
bb432d |
-
|
|
|
bb432d |
- free(line);
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
-
|
|
|
bb432d |
-parse_error:
|
|
|
bb432d |
- DBerror("Parse error in database %s at line %d\n", db->fn, linenr);
|
|
|
bb432d |
-error:
|
|
|
bb432d |
- free(line);
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-/*
|
|
|
bb432d |
-Crash safety strategy:
|
|
|
bb432d |
-
|
|
|
bb432d |
-While the database is opened hold a exclusive flock on the file
|
|
|
bb432d |
-When writing write to a temporary file (.out). Only when the file
|
|
|
bb432d |
-is written rename to another temporary file (.complete).
|
|
|
bb432d |
-
|
|
|
bb432d |
-Then sync and swap tmp file with main file, then sync directory
|
|
|
bb432d |
-(later is linux specific)
|
|
|
bb432d |
-
|
|
|
bb432d |
-During open if the main file doesn't exist and a .complete file does
|
|
|
bb432d |
-rename the .complete file to main first; or open the .complete
|
|
|
bb432d |
-file if the file system is read only.
|
|
|
bb432d |
-
|
|
|
bb432d |
-*/
|
|
|
bb432d |
-
|
|
|
bb432d |
-/* Flush directory. Useful on ext2, on journaling file systems
|
|
|
bb432d |
- the later fsync would usually force earlier transactions on the
|
|
|
bb432d |
- metadata too. */
|
|
|
bb432d |
-static int flush_dir(char *fn)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- int err, fd;
|
|
|
bb432d |
- char *p;
|
|
|
bb432d |
- char dir[strlen(fn) + 1];
|
|
|
bb432d |
- strcpy(dir, fn);
|
|
|
bb432d |
- p = strrchr(dir, '/');
|
|
|
bb432d |
- if (p)
|
|
|
bb432d |
- *p = 0;
|
|
|
bb432d |
- else
|
|
|
bb432d |
- strcpy(dir, ".");
|
|
|
bb432d |
- fd = open(dir, O_DIRECTORY|O_RDONLY);
|
|
|
bb432d |
- if (fd < 0)
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
- err = 0;
|
|
|
bb432d |
- if (fsync(fd) < 0)
|
|
|
bb432d |
- err = -1;
|
|
|
bb432d |
- if (close(fd) < 0)
|
|
|
bb432d |
- err = -1;
|
|
|
bb432d |
- return err;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static int force_rename(char *a, char *b)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- unlink(b); /* ignore error */
|
|
|
bb432d |
- return rename(a, b);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static int rewrite_db(struct database *db)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- FILE *fhtmp;
|
|
|
bb432d |
- int err;
|
|
|
bb432d |
-
|
|
|
bb432d |
- int tmplen = strlen(db->fn) + 10;
|
|
|
bb432d |
- char fn_complete[tmplen], fn_old[tmplen], fn_out[tmplen];
|
|
|
bb432d |
-
|
|
|
bb432d |
- sprintf(fn_complete, "%s.complete", db->fn);
|
|
|
bb432d |
- sprintf(fn_old, "%s~", db->fn);
|
|
|
bb432d |
- sprintf(fn_out, "%s.out", db->fn);
|
|
|
bb432d |
-
|
|
|
bb432d |
- fhtmp = fopen(fn_out, "w");
|
|
|
bb432d |
- if (!fhtmp) {
|
|
|
bb432d |
- DBerror("Cannot open `%s' output file: %s\n", fn_out,
|
|
|
bb432d |
- strerror(errno));
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
- }
|
|
|
bb432d |
-
|
|
|
bb432d |
- dump_database(db, fhtmp);
|
|
|
bb432d |
-
|
|
|
bb432d |
- err = 0;
|
|
|
bb432d |
- /* Finish the output file */
|
|
|
bb432d |
- if (ferror(fhtmp) || fflush(fhtmp) != 0 || fsync(fileno(fhtmp)) != 0 ||
|
|
|
bb432d |
- fclose(fhtmp))
|
|
|
bb432d |
- err = -1;
|
|
|
bb432d |
- /* Rename to .complete */
|
|
|
bb432d |
- else if (force_rename(fn_out, fn_complete))
|
|
|
bb432d |
- err = -1;
|
|
|
bb432d |
- /* RED-PEN: need to do retry for race */
|
|
|
bb432d |
- /* Move to final name */
|
|
|
bb432d |
- else if (force_rename(db->fn, fn_old) || rename(fn_complete, db->fn))
|
|
|
bb432d |
- err = -1;
|
|
|
bb432d |
- /* Hit disk */
|
|
|
bb432d |
- else if (flush_dir(db->fn))
|
|
|
bb432d |
- err = -1;
|
|
|
bb432d |
-
|
|
|
bb432d |
- if (err) {
|
|
|
bb432d |
- DBerror("Error writing to database %s: %s\n", db->fn,
|
|
|
bb432d |
- strerror(errno));
|
|
|
bb432d |
- }
|
|
|
bb432d |
-
|
|
|
bb432d |
- return err;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-int sync_db(struct database *db)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- if (!db->dirty)
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
- /* RED-PEN window without lock */
|
|
|
bb432d |
- if (rewrite_db(db))
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
- fclose(db->fh);
|
|
|
bb432d |
- db->dirty = 0;
|
|
|
bb432d |
- db->fh = open_file(db->fn, 1);
|
|
|
bb432d |
- if (!db->fh)
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static void free_group(struct group *g)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- free(g->entries);
|
|
|
bb432d |
- free(g->name);
|
|
|
bb432d |
- free(g->comment);
|
|
|
bb432d |
- free(g);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static void free_data(struct database *db)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g, *gnext;
|
|
|
bb432d |
- for (g = db->groups; g; g = gnext) {
|
|
|
bb432d |
- gnext = g->next;
|
|
|
bb432d |
- free_group(g);
|
|
|
bb432d |
- }
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-int close_db(struct database *db)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- if (db->dirty && rewrite_db(db))
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
- if (fclose(db->fh))
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
- free_data(db);
|
|
|
bb432d |
- free(db->fn);
|
|
|
bb432d |
- free(db);
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static FILE *open_file(char *fn, int wr)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char tmp[strlen(fn) + 10];
|
|
|
bb432d |
- FILE *fh;
|
|
|
bb432d |
- if (access(fn, wr ? (R_OK|W_OK) : R_OK)) {
|
|
|
bb432d |
- switch (errno) {
|
|
|
bb432d |
- case EROFS:
|
|
|
bb432d |
- wr = 0;
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case ENOENT:
|
|
|
bb432d |
- /* No main DB file */
|
|
|
bb432d |
- sprintf(tmp, "%s.complete", fn);
|
|
|
bb432d |
- /* Handle race */
|
|
|
bb432d |
- if (!access(tmp, R_OK)) {
|
|
|
bb432d |
- if (rename(tmp, fn) < 0 && errno == EEXIST)
|
|
|
bb432d |
- return open_file(fn, wr);
|
|
|
bb432d |
- } else
|
|
|
bb432d |
- creat(fn, 0644);
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- fh = fopen(fn, wr ? "r+" : "r");
|
|
|
bb432d |
- if (fh) {
|
|
|
bb432d |
- if (flock(fileno(fh), wr ? LOCK_EX : LOCK_SH) < 0) {
|
|
|
bb432d |
- fclose(fh);
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- return fh;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void dump_group(struct group *g, FILE *out)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct entry *e;
|
|
|
bb432d |
- fprintf(out, "[%s]\n", g->name);
|
|
|
bb432d |
- for (e = &g->entries[0]; e->name && !ferror(out); e++)
|
|
|
bb432d |
- fprintf(out, "%s: %s\n", e->name, e->val);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void dump_database(struct database *db, FILE *out)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g;
|
|
|
bb432d |
- for (g = db->groups; g && !ferror(out); g = g->next) {
|
|
|
bb432d |
- if (g->comment) {
|
|
|
bb432d |
- fprintf(out, "#%s", g->comment);
|
|
|
bb432d |
- continue;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- dump_group(g, out);
|
|
|
bb432d |
- }
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group *find_group(struct database *db, char *name)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g;
|
|
|
bb432d |
- for (g = db->groups; g; g = g->next)
|
|
|
bb432d |
- if (g->name && !strcmp(g->name, name))
|
|
|
bb432d |
- return g;
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-int delete_group(struct database *db, struct group *group)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g, **gprev;
|
|
|
bb432d |
- gprev = &db->groups;
|
|
|
bb432d |
- for (g = *gprev; g; gprev = &g->next, g = g->next) {
|
|
|
bb432d |
- if (g == group) {
|
|
|
bb432d |
- *gprev = g->next;
|
|
|
bb432d |
- free_group(g);
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- db->dirty = 1;
|
|
|
bb432d |
- return -1;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-char *entry_val(struct group *g, char *entry)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct entry *e;
|
|
|
bb432d |
- for (e = &g->entries[0]; e->name; e++)
|
|
|
bb432d |
- if (!strcmp(e->name, entry))
|
|
|
bb432d |
- return e->val;
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group *add_group(struct database *db, char *name, int *existed)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g, **gprev = &db->groups;
|
|
|
bb432d |
- for (g = *gprev; g; gprev = &g->next, g = g->next)
|
|
|
bb432d |
- if (g->name && !strcmp(g->name, name))
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- if (existed)
|
|
|
bb432d |
- *existed = (g != NULL);
|
|
|
bb432d |
- if (!g) {
|
|
|
bb432d |
- g = alloc_group(xstrdup(name));
|
|
|
bb432d |
- g->next = *gprev;
|
|
|
bb432d |
- *gprev = g;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- db->dirty = 1;
|
|
|
bb432d |
- return g;
|
|
|
bb432d |
-
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void change_entry(struct database *db, struct group *g,
|
|
|
bb432d |
- char *entry, char *newval)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- int i;
|
|
|
bb432d |
- struct entry *e, *entries;
|
|
|
bb432d |
- db->dirty = 1;
|
|
|
bb432d |
- entries = &g->entries[0];
|
|
|
bb432d |
- for (e = entries; e->name; e++) {
|
|
|
bb432d |
- if (!strcmp(e->name, entry)) {
|
|
|
bb432d |
- free(e->val);
|
|
|
bb432d |
- e->val = xstrdup(newval);
|
|
|
bb432d |
- return;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- i = e - entries;
|
|
|
bb432d |
- assert(i == g->numentries);
|
|
|
bb432d |
- if (i > 0 && (i % ENTRY_CHUNK) == 0) {
|
|
|
bb432d |
- int new = (i + ENTRY_CHUNK) * sizeof(struct entry);
|
|
|
bb432d |
- g->entries = xrealloc(g->entries, new);
|
|
|
bb432d |
- }
|
|
|
bb432d |
- entries = &g->entries[0];
|
|
|
bb432d |
- e = &entries[i];
|
|
|
bb432d |
- e->name = xstrdup(entry);
|
|
|
bb432d |
- e->val = xstrdup(newval);
|
|
|
bb432d |
- g->numentries++;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void delete_entry(struct database *db, struct group *g, char *entry)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct entry *e;
|
|
|
bb432d |
- for (e = &g->entries[0]; e->name; e++)
|
|
|
bb432d |
- if (!strcmp(e->name, entry))
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- if (e->name == NULL)
|
|
|
bb432d |
- return;
|
|
|
bb432d |
- while ((++e)->name)
|
|
|
bb432d |
- e[-1] = e[0];
|
|
|
bb432d |
- g->numentries--;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group *
|
|
|
bb432d |
-clone_group(struct database *db, struct group *gold, char *newname)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct entry *e;
|
|
|
bb432d |
- struct group *gnew = add_group(db, newname, NULL);
|
|
|
bb432d |
- for (e = &gold->entries[0]; e->name; e++)
|
|
|
bb432d |
- change_entry(db, gnew, e->name, e->val);
|
|
|
bb432d |
- return gnew;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-static char *save_comment(char *c)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- int len = strlen(c);
|
|
|
bb432d |
- char *s = xalloc(len + 2);
|
|
|
bb432d |
- strcpy(s, c);
|
|
|
bb432d |
- if (len == 0 || c[len - 1] != '\n')
|
|
|
bb432d |
- s[len] = '\n';
|
|
|
bb432d |
- return s;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void add_comment(struct database *db, struct group *group, char *comment)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *g;
|
|
|
bb432d |
- struct group **gprev = &db->groups;
|
|
|
bb432d |
- for (g = *gprev; g; gprev = &g->next, g = g->next) {
|
|
|
bb432d |
- if ((group && g == group) || (!group && g->comment == NULL))
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- DB_NEW(g);
|
|
|
bb432d |
- g->comment = save_comment(comment);
|
|
|
bb432d |
- g->next = *gprev;
|
|
|
bb432d |
- *gprev = g;
|
|
|
bb432d |
- db->dirty = 1;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group *first_group(struct database *db)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- return next_group(db->groups);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group *next_group(struct group *g)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct group *n;
|
|
|
bb432d |
- if (!g)
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
- n = g->next;
|
|
|
bb432d |
- while (n && n->comment)
|
|
|
bb432d |
- n = n->next;
|
|
|
bb432d |
- return n;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-char *group_name(struct group *g)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- return g->name;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct group *find_entry(struct database *db, struct group *prev,
|
|
|
bb432d |
- char *entry, char *value)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- int previ = 0;
|
|
|
bb432d |
- struct entry *e;
|
|
|
bb432d |
- struct group *g;
|
|
|
bb432d |
- if (prev)
|
|
|
bb432d |
- g = prev->next;
|
|
|
bb432d |
- else
|
|
|
bb432d |
- g = db->groups;
|
|
|
bb432d |
- for (; g; g = g->next) {
|
|
|
bb432d |
- if (g->comment)
|
|
|
bb432d |
- continue;
|
|
|
bb432d |
- /* Short cut when entry is at the same place as previous */
|
|
|
bb432d |
- if (previ < g->numentries) {
|
|
|
bb432d |
- e = &g->entries[previ];
|
|
|
bb432d |
- if (!strcmp(e->name, entry)) {
|
|
|
bb432d |
- if (!strcmp(e->val, value))
|
|
|
bb432d |
- return g;
|
|
|
bb432d |
- continue;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- for (e = &g->entries[0]; e->name; e++) {
|
|
|
bb432d |
- if (strcmp(e->name, entry))
|
|
|
bb432d |
- continue;
|
|
|
bb432d |
- if (!strcmp(e->val, value))
|
|
|
bb432d |
- return g;
|
|
|
bb432d |
- previ = e - &g->entries[0];
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- return NULL;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void rename_group(struct database *db, struct group *g, char *newname)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- free(g->name);
|
|
|
bb432d |
- g->name = xstrdup(newname);
|
|
|
bb432d |
- db->dirty = 1;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-unsigned long entry_num(struct group *g, char *entry)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char *e = entry_val(g, entry);
|
|
|
bb432d |
- unsigned long val = 0;
|
|
|
bb432d |
- if (e)
|
|
|
bb432d |
- sscanf(e, "%lu", &val;;
|
|
|
bb432d |
- return val;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void change_entry_num(struct database *db, struct group *g,
|
|
|
bb432d |
- char *entry, unsigned long val)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char buf[20];
|
|
|
bb432d |
- sprintf(buf, "%lu", val);
|
|
|
bb432d |
- change_entry(db, g, entry, buf);
|
|
|
bb432d |
-}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/db.h mcelog-d2e13bf0/db.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/db.h 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/db.h 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,29 +0,0 @@
|
|
|
bb432d |
-#include <stdio.h>
|
|
|
bb432d |
-struct database;
|
|
|
bb432d |
-struct group;
|
|
|
bb432d |
-
|
|
|
bb432d |
-struct database *open_db(char *fn, int wr);
|
|
|
bb432d |
-int sync_db(struct database *db);
|
|
|
bb432d |
-int close_db(struct database *db);
|
|
|
bb432d |
-struct group *find_group(struct database *db, char *name);
|
|
|
bb432d |
-char *entry_val(struct group *g, char *entry);
|
|
|
bb432d |
-struct group *add_group(struct database *db, char *name, int *existed);
|
|
|
bb432d |
-int delete_group(struct database *db, struct group *g);
|
|
|
bb432d |
-void change_entry(struct database *db, struct group *g,
|
|
|
bb432d |
- char *entry, char *newval);
|
|
|
bb432d |
-void add_comment(struct database *db, struct group *group, char *comment);
|
|
|
bb432d |
-struct group *first_group(struct database *db);
|
|
|
bb432d |
-struct group *next_group(struct group *g);
|
|
|
bb432d |
-void dump_group(struct group *g, FILE *out);
|
|
|
bb432d |
-void dump_database(struct database *db, FILE *out);
|
|
|
bb432d |
-struct group *find_entry(struct database *db, struct group *prev,
|
|
|
bb432d |
- char *entry, char *value);
|
|
|
bb432d |
-void rename_group(struct database *db, struct group *group, char *newname);
|
|
|
bb432d |
-char *group_name(struct group *g);
|
|
|
bb432d |
-unsigned long entry_num(struct group *g, char *entry);
|
|
|
bb432d |
-void change_entry_num(struct database *db, struct group *g, char *entry,
|
|
|
bb432d |
- unsigned long val);
|
|
|
bb432d |
-void delete_entry(struct database *db, struct group *g, char *entry);
|
|
|
bb432d |
-struct group *
|
|
|
bb432d |
-clone_group(struct database *db, struct group *gold, char *newname);
|
|
|
bb432d |
-
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/dbquery.c mcelog-d2e13bf0/dbquery.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/dbquery.c 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/dbquery.c 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,130 +0,0 @@
|
|
|
bb432d |
-/* Access db files. This is for testing and debugging only. */
|
|
|
bb432d |
-#define _GNU_SOURCE 1
|
|
|
bb432d |
-#include <stdio.h>
|
|
|
bb432d |
-#include <string.h>
|
|
|
bb432d |
-#include <ctype.h>
|
|
|
bb432d |
-#include <stdlib.h>
|
|
|
bb432d |
-#include <errno.h>
|
|
|
bb432d |
-#include <stdarg.h>
|
|
|
bb432d |
-#include "db.h"
|
|
|
bb432d |
-
|
|
|
bb432d |
-#define C(x) if (x) printf(#x " failed: %s\n", strerror(errno))
|
|
|
bb432d |
-#define NEEDGROUP if (!group) { printf("need group first\n"); break; }
|
|
|
bb432d |
-
|
|
|
bb432d |
-void Eprintf(char *fmt, ...)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- va_list ap;
|
|
|
bb432d |
- va_start(ap, fmt);
|
|
|
bb432d |
- vfprintf(stderr, fmt, ap);
|
|
|
bb432d |
- va_end(ap);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void usage(void)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- printf(
|
|
|
bb432d |
- "s sync\n"
|
|
|
bb432d |
- "q close/quit\n"
|
|
|
bb432d |
- "ggroup find group\n"
|
|
|
bb432d |
- "G delete group\n"
|
|
|
bb432d |
- "agroup add group\n"
|
|
|
bb432d |
- "ventry dump entry\n"
|
|
|
bb432d |
- "centry,val change entry to val\n"
|
|
|
bb432d |
- "fentry,val find entry with value and dump its group\n"
|
|
|
bb432d |
- "Ccomment add comment\n"
|
|
|
bb432d |
- "Lnewname clone group to newname\n"
|
|
|
bb432d |
- "d dump group\n"
|
|
|
bb432d |
- "D dump database\n");
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-int main(int ac, char **av)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- struct database *db;
|
|
|
bb432d |
- struct group *group = NULL;
|
|
|
bb432d |
- char *line = NULL;
|
|
|
bb432d |
- size_t linesz = 0;
|
|
|
bb432d |
- if (!av[1]) {
|
|
|
bb432d |
- printf("%s database\n", av[0]);
|
|
|
bb432d |
- exit(1);
|
|
|
bb432d |
- }
|
|
|
bb432d |
- printf("dbtest\n");
|
|
|
bb432d |
- db = open_db(av[1], 1);
|
|
|
bb432d |
- while (printf("> "),
|
|
|
bb432d |
- fflush(stdout),
|
|
|
bb432d |
- getline(&line, &linesz, stdin) > 0) {
|
|
|
bb432d |
- char *p = line + strlen(line) - 1;
|
|
|
bb432d |
- while (p >= line && isspace(*p))
|
|
|
bb432d |
- *p-- = 0;
|
|
|
bb432d |
- switch (line[0]) {
|
|
|
bb432d |
- case 's':
|
|
|
bb432d |
- C(sync_db(db));
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'q':
|
|
|
bb432d |
- C(close_db(db));
|
|
|
bb432d |
- exit(0);
|
|
|
bb432d |
- case 'g':
|
|
|
bb432d |
- group = find_group(db, line + 1);
|
|
|
bb432d |
- if (group)
|
|
|
bb432d |
- printf("found\n");
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'G':
|
|
|
bb432d |
- NEEDGROUP;
|
|
|
bb432d |
- C(delete_group(db, group));
|
|
|
bb432d |
- group = NULL;
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'a': {
|
|
|
bb432d |
- int existed = 0;
|
|
|
bb432d |
- group = add_group(db, line + 1, &existed);
|
|
|
bb432d |
- if (existed)
|
|
|
bb432d |
- printf("existed\n");
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- case 'v':
|
|
|
bb432d |
- NEEDGROUP;
|
|
|
bb432d |
- printf("%s\n", entry_val(group, line + 1));
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'c': {
|
|
|
bb432d |
- p = line + 1;
|
|
|
bb432d |
- char *entry = strsep(&p, ",");
|
|
|
bb432d |
- NEEDGROUP;
|
|
|
bb432d |
- change_entry(db, group, entry, strsep(&p, ""));
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- case 'L':
|
|
|
bb432d |
- NEEDGROUP;
|
|
|
bb432d |
- clone_group(db, group, line + 1);
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'f': {
|
|
|
bb432d |
- struct group *g;
|
|
|
bb432d |
- p = line + 1;
|
|
|
bb432d |
- char *entry = strsep(&p, ",");
|
|
|
bb432d |
- char *val = strsep(&p, "");
|
|
|
bb432d |
- g = NULL;
|
|
|
bb432d |
- int nr = 0;
|
|
|
bb432d |
- while ((g = find_entry(db, g, entry, val)) != NULL) {
|
|
|
bb432d |
- if (nr == 0)
|
|
|
bb432d |
- group = g;
|
|
|
bb432d |
- nr++;
|
|
|
bb432d |
- dump_group(group, stdout);
|
|
|
bb432d |
- }
|
|
|
bb432d |
- if (nr == 0)
|
|
|
bb432d |
- printf("not found\n");
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- case 'C':
|
|
|
bb432d |
- NEEDGROUP;
|
|
|
bb432d |
- add_comment(db, group, line + 1);
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'd':
|
|
|
bb432d |
- NEEDGROUP;
|
|
|
bb432d |
- dump_group(group, stdout);
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case 'D':
|
|
|
bb432d |
- dump_database(db, stdout);
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- default:
|
|
|
bb432d |
- usage();
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- }
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
-}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/denverton.c mcelog-d2e13bf0/denverton.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/denverton.c 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/denverton.c 2016-11-30 11:24:12.204619369 -0500
|
|
|
bb432d |
@@ -0,0 +1,45 @@
|
|
|
bb432d |
+/* Copyright (C) 2016 Intel Corporation
|
|
|
bb432d |
+ Decode Intel Denverton specific machine check errors.
|
|
|
bb432d |
+
|
|
|
bb432d |
+ mcelog is free software; you can redistribute it and/or
|
|
|
bb432d |
+ modify it under the terms of the GNU General Public
|
|
|
bb432d |
+ License as published by the Free Software Foundation; version
|
|
|
bb432d |
+ 2.
|
|
|
bb432d |
+
|
|
|
bb432d |
+ mcelog is distributed in the hope that it will be useful,
|
|
|
bb432d |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
bb432d |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
bb432d |
+ General Public License for more details.
|
|
|
bb432d |
+
|
|
|
bb432d |
+ You should find a copy of v2 of the GNU General Public License somewhere
|
|
|
bb432d |
+ on your Linux system; if not, write to the Free Software Foundation,
|
|
|
bb432d |
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
bb432d |
+
|
|
|
bb432d |
+ Author: Tony Luck
|
|
|
bb432d |
+*/
|
|
|
bb432d |
+
|
|
|
bb432d |
+#include "mcelog.h"
|
|
|
bb432d |
+#include "bitfield.h"
|
|
|
bb432d |
+#include "denverton.h"
|
|
|
bb432d |
+#include "memdb.h"
|
|
|
bb432d |
+
|
|
|
bb432d |
+/* See IA32 SDM Vol3B Table 16-33 */
|
|
|
bb432d |
+
|
|
|
bb432d |
+static struct field mc_bits[] = {
|
|
|
bb432d |
+ SBITFIELD(16, "Cmd/Addr parity"),
|
|
|
bb432d |
+ SBITFIELD(17, "Corrected Demand/Patrol Scrub Error"),
|
|
|
bb432d |
+ SBITFIELD(18, "Uncorrected patrol scrub error"),
|
|
|
bb432d |
+ SBITFIELD(19, "Uncorrected demand read error"),
|
|
|
bb432d |
+ SBITFIELD(20, "WDB read ECC"),
|
|
|
bb432d |
+ {}
|
|
|
bb432d |
+};
|
|
|
bb432d |
+
|
|
|
bb432d |
+void denverton_decode_model(int cputype, int bank, u64 status, u64 misc)
|
|
|
bb432d |
+{
|
|
|
bb432d |
+ switch (bank) {
|
|
|
bb432d |
+ case 6: case 7:
|
|
|
bb432d |
+ Wprintf("MemCtrl: ");
|
|
|
bb432d |
+ decode_bitfield(status, mc_bits);
|
|
|
bb432d |
+ break;
|
|
|
bb432d |
+ }
|
|
|
bb432d |
+}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/denverton.h mcelog-d2e13bf0/denverton.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/denverton.h 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/denverton.h 2016-11-30 11:24:12.204619369 -0500
|
|
|
bb432d |
@@ -0,0 +1 @@
|
|
|
bb432d |
+void denverton_decode_model(int cputype, int bank, u64 status, u64 misc);
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/diskdb.c mcelog-d2e13bf0/diskdb.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/diskdb.c 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/diskdb.c 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,96 +0,0 @@
|
|
|
bb432d |
-/* High level interface to disk based DIMM database */
|
|
|
bb432d |
-/* Note: obsolete: new design is in memdb.c */
|
|
|
bb432d |
-#include <stdlib.h>
|
|
|
bb432d |
-#include <getopt.h>
|
|
|
bb432d |
-#include <stdio.h>
|
|
|
bb432d |
-#include "mcelog.h"
|
|
|
bb432d |
-#include "diskdb.h"
|
|
|
bb432d |
-#include "paths.h"
|
|
|
bb432d |
-#include "dimm.h"
|
|
|
bb432d |
-#include "dmi.h"
|
|
|
bb432d |
-
|
|
|
bb432d |
-char *error_trigger;
|
|
|
bb432d |
-unsigned error_thresh = 20;
|
|
|
bb432d |
-char *dimm_db_fn = DIMM_DB_FILENAME;
|
|
|
bb432d |
-
|
|
|
bb432d |
-static void checkdimmdb(void)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- if (open_dimm_db(dimm_db_fn) < 0)
|
|
|
bb432d |
- exit(1);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-int diskdb_modifier(int opt)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char *end;
|
|
|
bb432d |
-
|
|
|
bb432d |
- switch (opt) {
|
|
|
bb432d |
- case O_DATABASE:
|
|
|
bb432d |
- dimm_db_fn = optarg;
|
|
|
bb432d |
- checkdmi();
|
|
|
bb432d |
- checkdimmdb();
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- case O_ERROR_TRIGGER:
|
|
|
bb432d |
- checkdmi();
|
|
|
bb432d |
- open_dimm_db(dimm_db_fn);
|
|
|
bb432d |
- error_thresh = strtoul(optarg, &end, 0);
|
|
|
bb432d |
- if (end == optarg || *end != ',')
|
|
|
bb432d |
- usage();
|
|
|
bb432d |
- error_trigger = end + 1;
|
|
|
bb432d |
- break;
|
|
|
bb432d |
- default:
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- return 1;
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-void diskdb_resolve_addr(u64 addr)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- if (open_dimm_db(dimm_db_fn) >= 0)
|
|
|
bb432d |
- new_error(addr, error_thresh, error_trigger);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-
|
|
|
bb432d |
-void diskdb_usage(void)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- fprintf(stderr,
|
|
|
bb432d |
- "Manage disk DIMM error database\n"
|
|
|
bb432d |
- " mcelog [options] --drop-old-memory|--reset-memory locator\n"
|
|
|
bb432d |
- " mcelog --dump-memory locator\n"
|
|
|
bb432d |
- " old can be either locator or name\n"
|
|
|
bb432d |
- "Disk database options:"
|
|
|
bb432d |
- "--database fn Set filename of DIMM database (default " DIMM_DB_FILENAME ")\n"
|
|
|
bb432d |
- "--error-trigger cmd,thresh Run cmd on exceeding thresh errors per DIMM\n");
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-
|
|
|
bb432d |
-static void dimm_common(int ac, char **av)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- no_syslog();
|
|
|
bb432d |
- checkdmi();
|
|
|
bb432d |
- checkdimmdb();
|
|
|
bb432d |
- argsleft(ac, av);
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-int diskdb_cmd(int opt, int ac, char **av)
|
|
|
bb432d |
-{
|
|
|
bb432d |
- char *arg = optarg;
|
|
|
bb432d |
-
|
|
|
bb432d |
- switch (opt) {
|
|
|
bb432d |
- case O_DUMP_MEMORY:
|
|
|
bb432d |
- dimm_common(ac, av);
|
|
|
bb432d |
- if (arg)
|
|
|
bb432d |
- dump_dimm(arg);
|
|
|
bb432d |
- else
|
|
|
bb432d |
- dump_all_dimms();
|
|
|
bb432d |
- return 1;
|
|
|
bb432d |
- case O_RESET_MEMORY:
|
|
|
bb432d |
- dimm_common(ac, av);
|
|
|
bb432d |
- reset_dimm(arg);
|
|
|
bb432d |
- return 1;
|
|
|
bb432d |
- case O_DROP_OLD_MEMORY:
|
|
|
bb432d |
- dimm_common(ac, av);
|
|
|
bb432d |
- gc_dimms();
|
|
|
bb432d |
- return 1;
|
|
|
bb432d |
- }
|
|
|
bb432d |
- return 0;
|
|
|
bb432d |
-}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/diskdb.h mcelog-d2e13bf0/diskdb.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/diskdb.h 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/diskdb.h 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,32 +0,0 @@
|
|
|
bb432d |
-
|
|
|
bb432d |
-#ifdef CONFIG_DISKDB
|
|
|
bb432d |
-enum diskdb_options {
|
|
|
bb432d |
- O_DATABASE = O_DISKDB,
|
|
|
bb432d |
- O_ERROR_TRIGGER,
|
|
|
bb432d |
- O_DUMP_MEMORY,
|
|
|
bb432d |
- O_RESET_MEMORY,
|
|
|
bb432d |
- O_DROP_OLD_MEMORY,
|
|
|
bb432d |
-};
|
|
|
bb432d |
-
|
|
|
bb432d |
-void diskdb_resolve_addr(u64 addr);
|
|
|
bb432d |
-int diskdb_modifier(int opt);
|
|
|
bb432d |
-int diskdb_cmd(int opt, int ac, char **av);
|
|
|
bb432d |
-void diskdb_usage(void);
|
|
|
bb432d |
-
|
|
|
bb432d |
-#define DISKDB_OPTIONS \
|
|
|
bb432d |
- { "database", 1, NULL, O_DATABASE }, \
|
|
|
bb432d |
- { "error-trigger", 1, NULL, O_ERROR_TRIGGER }, \
|
|
|
bb432d |
- { "dump-memory", 2, NULL, O_DUMP_MEMORY }, \
|
|
|
bb432d |
- { "reset-memory", 2, NULL, O_RESET_MEMORY }, \
|
|
|
bb432d |
- { "drop-old-memory", 0, NULL, O_DROP_OLD_MEMORY },
|
|
|
bb432d |
-
|
|
|
bb432d |
-#else
|
|
|
bb432d |
-
|
|
|
bb432d |
-static inline void diskdb_resolve_addr(u64 addr) {}
|
|
|
bb432d |
-static inline int diskdb_modifier(int opt) { return 0; }
|
|
|
bb432d |
-static inline int diskdb_cmd(int opt, int ac, char **av) { return 0; }
|
|
|
bb432d |
-static inline void diskdb_usage(void) {}
|
|
|
bb432d |
-
|
|
|
bb432d |
-#define DISKDB_OPTIONS
|
|
|
bb432d |
-
|
|
|
bb432d |
-#endif
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/dmi.h mcelog-d2e13bf0/dmi.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/dmi.h 2016-11-30 11:23:54.534909314 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/dmi.h 2016-11-30 11:24:12.205619409 -0500
|
|
|
bb432d |
@@ -3,7 +3,7 @@ struct dmi_entry {
|
|
|
bb432d |
unsigned char type;
|
|
|
bb432d |
unsigned char length;
|
|
|
bb432d |
unsigned short handle;
|
|
|
bb432d |
-};
|
|
|
bb432d |
+} __attribute__((packed));
|
|
|
bb432d |
|
|
|
bb432d |
enum {
|
|
|
bb432d |
DMI_MEMORY_ARRAY = 16,
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/.gitignore mcelog-d2e13bf0/.gitignore
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/.gitignore 2016-11-30 11:23:54.530909154 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/.gitignore 2016-11-30 11:24:12.202619289 -0500
|
|
|
bb432d |
@@ -8,3 +8,5 @@ dbquery
|
|
|
bb432d |
.depend
|
|
|
bb432d |
tsc
|
|
|
bb432d |
core
|
|
|
bb432d |
+version.c
|
|
|
bb432d |
+version.tmp
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/input/bdw_mirror1 mcelog-d2e13bf0/input/bdw_mirror1
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/input/bdw_mirror1 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/input/bdw_mirror1 2016-11-30 11:24:12.205619409 -0500
|
|
|
bb432d |
@@ -0,0 +1,6 @@
|
|
|
bb432d |
+# Broadwell mirror corrected with mirror failover
|
|
|
bb432d |
+CPU 0 7
|
|
|
bb432d |
+PROCESSOR 0:0x406f0
|
|
|
bb432d |
+STATUS 0x8800000000000080
|
|
|
bb432d |
+MISC 20000000000
|
|
|
bb432d |
+
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/input/bdw_mirror2 mcelog-d2e13bf0/input/bdw_mirror2
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/input/bdw_mirror2 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/input/bdw_mirror2 2016-11-30 11:24:12.205619409 -0500
|
|
|
bb432d |
@@ -0,0 +1,6 @@
|
|
|
bb432d |
+# Broadwell mirror corrected with successful scrub
|
|
|
bb432d |
+CPU 0 7
|
|
|
bb432d |
+PROCESSOR 0:0x406f0
|
|
|
bb432d |
+STATUS 0x8800000000000080
|
|
|
bb432d |
+MISC 40000000000
|
|
|
bb432d |
+
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/input/GENMEM mcelog-d2e13bf0/input/GENMEM
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/input/GENMEM 2016-11-30 11:23:54.532909234 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/input/GENMEM 2016-11-30 11:24:12.205619409 -0500
|
|
|
bb432d |
@@ -11,7 +11,7 @@ dimm=${3:-0}
|
|
|
bb432d |
corr_err_cnt=${4:-0}
|
|
|
bb432d |
|
|
|
bb432d |
if [ ! -z "$5" ] ; then
|
|
|
bb432d |
- ucflag=$[1 << (61-32)]
|
|
|
bb432d |
+ ucflag=$[(1 << (61-32)) | (1 << (60-32)) | (1 << (56-32))]
|
|
|
bb432d |
else
|
|
|
bb432d |
ucflag=0
|
|
|
bb432d |
fi
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/input/skx_mirror1 mcelog-d2e13bf0/input/skx_mirror1
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/input/skx_mirror1 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/input/skx_mirror1 2016-11-30 11:24:12.205619409 -0500
|
|
|
bb432d |
@@ -0,0 +1,6 @@
|
|
|
bb432d |
+# Skylake mirror corrected with mirror failover
|
|
|
bb432d |
+CPU 0 7
|
|
|
bb432d |
+PROCESSOR 0:0x50650
|
|
|
bb432d |
+STATUS 0x8800000000000080
|
|
|
bb432d |
+MISC 8000000000000000
|
|
|
bb432d |
+
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/input/skx_mirror2 mcelog-d2e13bf0/input/skx_mirror2
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/input/skx_mirror2 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/input/skx_mirror2 2016-11-30 11:24:12.205619409 -0500
|
|
|
bb432d |
@@ -0,0 +1,6 @@
|
|
|
bb432d |
+# Skylake mirror corrected with successful scrub
|
|
|
bb432d |
+CPU 0 7
|
|
|
bb432d |
+PROCESSOR 0:0x50650
|
|
|
bb432d |
+STATUS 0x8800000000000080
|
|
|
bb432d |
+MISC 4000000000000000
|
|
|
bb432d |
+
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/intel.c mcelog-d2e13bf0/intel.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/intel.c 2016-11-30 11:23:54.538909475 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/intel.c 2016-11-30 11:24:12.206619450 -0500
|
|
|
bb432d |
@@ -25,7 +25,6 @@
|
|
|
bb432d |
#include "sandy-bridge.h"
|
|
|
bb432d |
#include "ivy-bridge.h"
|
|
|
bb432d |
#include "haswell.h"
|
|
|
bb432d |
-#include "xeon75xx.h"
|
|
|
bb432d |
|
|
|
bb432d |
int memory_error_support;
|
|
|
bb432d |
|
|
|
bb432d |
@@ -36,7 +35,9 @@ void intel_cpu_init(enum cputype cpu)
|
|
|
bb432d |
cpu == CPU_IVY_BRIDGE || cpu == CPU_IVY_BRIDGE_EPEX ||
|
|
|
bb432d |
cpu == CPU_HASWELL || cpu == CPU_HASWELL_EPEX || cpu == CPU_BROADWELL ||
|
|
|
bb432d |
cpu == CPU_BROADWELL_DE || cpu == CPU_BROADWELL_EPEX ||
|
|
|
bb432d |
- cpu == CPU_KNIGHTS_LANDING || cpu == CPU_SKYLAKE || cpu == CPU_SKYLAKE_XEON)
|
|
|
bb432d |
+ cpu == CPU_KNIGHTS_LANDING || cpu == CPU_KNIGHTS_MILL ||
|
|
|
bb432d |
+ cpu == CPU_SKYLAKE || cpu == CPU_SKYLAKE_XEON ||
|
|
|
bb432d |
+ cpu == CPU_KABYLAKE || cpu == CPU_DENVERTON)
|
|
|
bb432d |
memory_error_support = 1;
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
@@ -82,6 +83,8 @@ enum cputype select_intel_cputype(int fa
|
|
|
bb432d |
return CPU_BROADWELL_DE;
|
|
|
bb432d |
else if (model == 0x57)
|
|
|
bb432d |
return CPU_KNIGHTS_LANDING;
|
|
|
bb432d |
+ else if (model == 0x85)
|
|
|
bb432d |
+ return CPU_KNIGHTS_MILL;
|
|
|
bb432d |
else if (model == 0x1c || model == 0x26 || model == 0x27 ||
|
|
|
bb432d |
model == 0x35 || model == 0x36 || model == 0x36 ||
|
|
|
bb432d |
model == 0x37 || model == 0x4a || model == 0x4c ||
|
|
|
bb432d |
@@ -91,18 +94,22 @@ enum cputype select_intel_cputype(int fa
|
|
|
bb432d |
return CPU_SKYLAKE;
|
|
|
bb432d |
else if (model == 0x55)
|
|
|
bb432d |
return CPU_SKYLAKE_XEON;
|
|
|
bb432d |
+ else if (model == 0x8E || model == 0x9E)
|
|
|
bb432d |
+ return CPU_KABYLAKE;
|
|
|
bb432d |
+ else if (model == 0x5f)
|
|
|
bb432d |
+ return CPU_DENVERTON;
|
|
|
bb432d |
if (model > 0x1a) {
|
|
|
bb432d |
- Eprintf("Family 6 Model %x CPU: only decoding architectural errors\n",
|
|
|
bb432d |
+ Eprintf("Family 6 Model %u CPU: only decoding architectural errors\n",
|
|
|
bb432d |
model);
|
|
|
bb432d |
return CPU_INTEL;
|
|
|
bb432d |
}
|
|
|
bb432d |
}
|
|
|
bb432d |
if (family > 6) {
|
|
|
bb432d |
- Eprintf("Family %u Model %x CPU: only decoding architectural errors\n",
|
|
|
bb432d |
+ Eprintf("Family %u Model %u CPU: only decoding architectural errors\n",
|
|
|
bb432d |
family, model);
|
|
|
bb432d |
return CPU_INTEL;
|
|
|
bb432d |
}
|
|
|
bb432d |
- Eprintf("Unknown Intel CPU type family %x model %x\n", family, model);
|
|
|
bb432d |
+ Eprintf("Unknown Intel CPU type family %u model %u\n", family, model);
|
|
|
bb432d |
return family == 6 ? CPU_P6OLD : CPU_GENERIC;
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
@@ -127,9 +134,6 @@ static int intel_memory_error(struct mce
|
|
|
bb432d |
case CPU_NEHALEM:
|
|
|
bb432d |
nehalem_memerr_misc(m, channel, dimm);
|
|
|
bb432d |
break;
|
|
|
bb432d |
- case CPU_XEON75XX:
|
|
|
bb432d |
- xeon75xx_memory_error(m, recordlen, channel, dimm);
|
|
|
bb432d |
- break;
|
|
|
bb432d |
case CPU_SANDY_BRIDGE_EP:
|
|
|
bb432d |
sandy_bridge_ep_memerr_misc(m, channel, dimm);
|
|
|
bb432d |
break;
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/intel.c.orig mcelog-d2e13bf0/intel.c.orig
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/intel.c.orig 2016-11-30 11:23:54.539909515 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/intel.c.orig 2016-11-30 11:23:40.052327334 -0500
|
|
|
bb432d |
@@ -35,7 +35,8 @@ void intel_cpu_init(enum cputype cpu)
|
|
|
bb432d |
cpu == CPU_SANDY_BRIDGE || cpu == CPU_SANDY_BRIDGE_EP ||
|
|
|
bb432d |
cpu == CPU_IVY_BRIDGE || cpu == CPU_IVY_BRIDGE_EPEX ||
|
|
|
bb432d |
cpu == CPU_HASWELL || cpu == CPU_HASWELL_EPEX || cpu == CPU_BROADWELL ||
|
|
|
bb432d |
- cpu == CPU_KNIGHTS_LANDING)
|
|
|
bb432d |
+ cpu == CPU_BROADWELL_DE || cpu == CPU_BROADWELL_EPEX ||
|
|
|
bb432d |
+ cpu == CPU_KNIGHTS_LANDING || cpu == CPU_SKYLAKE || cpu == CPU_SKYLAKE_XEON)
|
|
|
bb432d |
memory_error_support = 1;
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
@@ -73,15 +74,23 @@ enum cputype select_intel_cputype(int fa
|
|
|
bb432d |
return CPU_HASWELL;
|
|
|
bb432d |
else if (model == 0x3f)
|
|
|
bb432d |
return CPU_HASWELL_EPEX;
|
|
|
bb432d |
- else if (model == 0x3d || model == 0x56)
|
|
|
bb432d |
+ else if (model == 0x3d)
|
|
|
bb432d |
return CPU_BROADWELL;
|
|
|
bb432d |
- else if (model == 0x57)
|
|
|
bb432d |
+ else if (model == 0x4f)
|
|
|
bb432d |
+ return CPU_BROADWELL_EPEX;
|
|
|
bb432d |
+ else if (model == 0x56)
|
|
|
bb432d |
+ return CPU_BROADWELL_DE;
|
|
|
bb432d |
+ else if (model == 0x57)
|
|
|
bb432d |
return CPU_KNIGHTS_LANDING;
|
|
|
bb432d |
else if (model == 0x1c || model == 0x26 || model == 0x27 ||
|
|
|
bb432d |
model == 0x35 || model == 0x36 || model == 0x36 ||
|
|
|
bb432d |
model == 0x37 || model == 0x4a || model == 0x4c ||
|
|
|
bb432d |
model == 0x4d || model == 0x5a || model == 0x5d)
|
|
|
bb432d |
return CPU_ATOM;
|
|
|
bb432d |
+ else if (model == 0x4e || model == 0x5e)
|
|
|
bb432d |
+ return CPU_SKYLAKE;
|
|
|
bb432d |
+ else if (model == 0x55)
|
|
|
bb432d |
+ return CPU_SKYLAKE_XEON;
|
|
|
bb432d |
if (model > 0x1a) {
|
|
|
bb432d |
Eprintf("Family 6 Model %x CPU: only decoding architectural errors\n",
|
|
|
bb432d |
model);
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/intel.h mcelog-d2e13bf0/intel.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/intel.h 2016-11-30 11:23:54.530909154 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/intel.h 2016-11-30 11:24:12.206619450 -0500
|
|
|
bb432d |
@@ -25,6 +25,9 @@ extern int memory_error_support;
|
|
|
bb432d |
case CPU_BROADWELL_EPEX: \
|
|
|
bb432d |
case CPU_ATOM: \
|
|
|
bb432d |
case CPU_KNIGHTS_LANDING: \
|
|
|
bb432d |
+ case CPU_KNIGHTS_MILL: \
|
|
|
bb432d |
case CPU_SKYLAKE: \
|
|
|
bb432d |
- case CPU_SKYLAKE_XEON
|
|
|
bb432d |
+ case CPU_SKYLAKE_XEON: \
|
|
|
bb432d |
+ case CPU_KABYLAKE: \
|
|
|
bb432d |
+ case CPU_DENVERTON
|
|
|
bb432d |
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/leaky-bucket.c mcelog-d2e13bf0/leaky-bucket.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/leaky-bucket.c 2016-11-30 11:23:54.537909435 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/leaky-bucket.c 2016-11-30 11:24:12.206619450 -0500
|
|
|
bb432d |
@@ -72,7 +72,9 @@ static int timeconv(char unit, int *out)
|
|
|
bb432d |
case 'h': corr *= 60;
|
|
|
bb432d |
case 'm': corr *= 60;
|
|
|
bb432d |
case 0: break;
|
|
|
bb432d |
- default: return -1;
|
|
|
bb432d |
+ default:
|
|
|
bb432d |
+ *out = 1;
|
|
|
bb432d |
+ return -1;
|
|
|
bb432d |
}
|
|
|
bb432d |
*out = corr;
|
|
|
bb432d |
return 0;
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/Makefile mcelog-d2e13bf0/Makefile
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/Makefile 2016-11-30 11:23:54.538909475 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/Makefile 2016-11-30 11:24:12.202619289 -0500
|
|
|
bb432d |
@@ -17,11 +17,6 @@ WARNINGS := -Wall -Wextra -Wno-missing-f
|
|
|
bb432d |
-Wstrict-prototypes -Wformat-security -Wmissing-declarations \
|
|
|
bb432d |
-Wdeclaration-after-statement
|
|
|
bb432d |
|
|
|
bb432d |
-# The on disk database has still many problems (partly in this code and partly
|
|
|
bb432d |
-# due to missing support from BIOS), so it's disabled by default. You can
|
|
|
bb432d |
-# enable it here by uncommenting the following line
|
|
|
bb432d |
-# CONFIG_DISKDB = 1
|
|
|
bb432d |
-
|
|
|
bb432d |
TRIGGERS=cache-error-trigger dimm-error-trigger page-error-trigger \
|
|
|
bb432d |
socket-memory-error-trigger \
|
|
|
bb432d |
bus-error-trigger \
|
|
|
bb432d |
@@ -36,23 +31,16 @@ OBJ := p4.o k8.o mcelog.o dmi.o tsc.o co
|
|
|
bb432d |
nehalem.o dunnington.o tulsa.o config.o memutil.o msg.o \
|
|
|
bb432d |
eventloop.o leaky-bucket.o memdb.o server.o trigger.o \
|
|
|
bb432d |
client.o cache.o sysfs.o yellow.o page.o rbtree.o \
|
|
|
bb432d |
- xeon75xx.o sandy-bridge.o ivy-bridge.o haswell.o \
|
|
|
bb432d |
+ sandy-bridge.o ivy-bridge.o haswell.o \
|
|
|
bb432d |
broadwell_de.o broadwell_epex.o skylake_xeon.o \
|
|
|
bb432d |
+ denverton.o \
|
|
|
bb432d |
msr.o bus.o unknown.o
|
|
|
bb432d |
-DISKDB_OBJ := diskdb.o dimm.o db.o
|
|
|
bb432d |
-CLEAN := mcelog dmi tsc dbquery .depend .depend.X dbquery.o ${DISKDB_OBJ} \
|
|
|
bb432d |
+CLEAN := mcelog dmi tsc dbquery .depend .depend.X dbquery.o \
|
|
|
bb432d |
version.o version.c version.tmp
|
|
|
bb432d |
DOC := mce.pdf
|
|
|
bb432d |
|
|
|
bb432d |
ADD_DEFINES :=
|
|
|
bb432d |
|
|
|
bb432d |
-ifdef CONFIG_DISKDB
|
|
|
bb432d |
-ADD_DEFINES := -DCONFIG_DISKDB=1
|
|
|
bb432d |
-OBJ += ${DISKDB_OBJ}
|
|
|
bb432d |
-
|
|
|
bb432d |
-all: dbquery
|
|
|
bb432d |
-endif
|
|
|
bb432d |
-
|
|
|
bb432d |
SRC := $(OBJ:.o=.c)
|
|
|
bb432d |
|
|
|
bb432d |
mcelog: ${OBJ} version.o
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/mcelog.c mcelog-d2e13bf0/mcelog.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/mcelog.c 2016-11-30 11:23:54.531909194 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/mcelog.c 2016-11-30 11:25:24.563516902 -0500
|
|
|
bb432d |
@@ -48,7 +48,6 @@
|
|
|
bb432d |
#include "tsc.h"
|
|
|
bb432d |
#include "version.h"
|
|
|
bb432d |
#include "config.h"
|
|
|
bb432d |
-#include "diskdb.h"
|
|
|
bb432d |
#include "memutil.h"
|
|
|
bb432d |
#include "eventloop.h"
|
|
|
bb432d |
#include "memdb.h"
|
|
|
bb432d |
@@ -236,9 +235,12 @@ static char *cputype_name[] = {
|
|
|
bb432d |
[CPU_BROADWELL_DE] = "Intel Xeon (Broadwell) D family",
|
|
|
bb432d |
[CPU_BROADWELL_EPEX] = "Intel Xeon v4 (Broadwell) EP/EX",
|
|
|
bb432d |
[CPU_KNIGHTS_LANDING] = "Knights Landing",
|
|
|
bb432d |
+ [CPU_KNIGHTS_MILL] = "Knights Mill",
|
|
|
bb432d |
[CPU_ATOM] = "ATOM",
|
|
|
bb432d |
[CPU_SKYLAKE] = "Skylake",
|
|
|
bb432d |
[CPU_SKYLAKE_XEON] = "Skylake server",
|
|
|
bb432d |
+ [CPU_KABYLAKE] = "Kabylake",
|
|
|
bb432d |
+ [CPU_DENVERTON] = "Denverton",
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
static struct config_choice cpu_choices[] = {
|
|
|
bb432d |
@@ -282,10 +284,13 @@ static struct config_choice cpu_choices[
|
|
|
bb432d |
{ "broadwell-ep", CPU_BROADWELL_EPEX },
|
|
|
bb432d |
{ "broadwell-ex", CPU_BROADWELL_EPEX },
|
|
|
bb432d |
{ "knightslanding", CPU_KNIGHTS_LANDING },
|
|
|
bb432d |
+ { "knightsmill", CPU_KNIGHTS_MILL },
|
|
|
bb432d |
{ "xeon-v4", CPU_BROADWELL_EPEX },
|
|
|
bb432d |
{ "atom", CPU_ATOM },
|
|
|
bb432d |
{ "skylake", CPU_SKYLAKE },
|
|
|
bb432d |
{ "skylake_server", CPU_SKYLAKE_XEON },
|
|
|
bb432d |
+ { "kabylake", CPU_KABYLAKE },
|
|
|
bb432d |
+ { "denverton", CPU_DENVERTON },
|
|
|
bb432d |
{ NULL }
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
@@ -356,7 +361,7 @@ static enum cputype setup_cpuid(u32 cpuv
|
|
|
bb432d |
return CPU_K8;
|
|
|
bb432d |
/* FALL THROUGH */
|
|
|
bb432d |
default:
|
|
|
bb432d |
- Eprintf("Unknown CPU type vendor %u family %x model %x",
|
|
|
bb432d |
+ Eprintf("Unknown CPU type vendor %u family %u model %u",
|
|
|
bb432d |
cpuvendor, family, model);
|
|
|
bb432d |
return CPU_GENERIC;
|
|
|
bb432d |
}
|
|
|
bb432d |
@@ -449,12 +454,10 @@ static void dump_mce(struct mce *m, unsi
|
|
|
bb432d |
if (cputype != CPU_SANDY_BRIDGE_EP && cputype != CPU_IVY_BRIDGE_EPEX &&
|
|
|
bb432d |
cputype != CPU_HASWELL_EPEX && cputype != CPU_BROADWELL &&
|
|
|
bb432d |
cputype != CPU_BROADWELL_DE && cputype != CPU_BROADWELL_EPEX &&
|
|
|
bb432d |
- cputype != CPU_KNIGHTS_LANDING && cputype != CPU_SKYLAKE &&
|
|
|
bb432d |
- cputype != CPU_SKYLAKE_XEON)
|
|
|
bb432d |
+ cputype != CPU_KNIGHTS_LANDING && cputype != CPU_KNIGHTS_MILL &&
|
|
|
bb432d |
+ cputype != CPU_SKYLAKE && cputype != CPU_SKYLAKE_XEON &&
|
|
|
bb432d |
+ cputype != CPU_KABYLAKE && cputype != CPU_DENVERTON)
|
|
|
bb432d |
resolveaddr(m->addr);
|
|
|
bb432d |
- if (!ascii_mode && ismemerr && (m->status & MCI_STATUS_ADDRV)) {
|
|
|
bb432d |
- diskdb_resolve_addr(m->addr);
|
|
|
bb432d |
- }
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
static void dump_mce_raw_ascii(struct mce *m, unsigned recordlen)
|
|
|
bb432d |
@@ -889,6 +892,7 @@ static void remove_pidfile(void)
|
|
|
bb432d |
static void signal_exit(int sig)
|
|
|
bb432d |
{
|
|
|
bb432d |
remove_pidfile();
|
|
|
bb432d |
+ client_cleanup();
|
|
|
bb432d |
_exit(sig);
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
@@ -974,7 +978,6 @@ void usage(void)
|
|
|
bb432d |
"--no-imc-log Disable extended iMC logging\n"
|
|
|
bb432d |
"--is-cpu-supported Exit with return code indicating whether the CPU is supported\n"
|
|
|
bb432d |
);
|
|
|
bb432d |
- diskdb_usage();
|
|
|
bb432d |
printf("\n");
|
|
|
bb432d |
print_cputypes();
|
|
|
bb432d |
exit(1);
|
|
|
bb432d |
@@ -1043,7 +1046,6 @@ static struct option options[] = {
|
|
|
bb432d |
{ "debug-numerrors", 0, NULL, O_DEBUG_NUMERRORS }, /* undocumented: for testing */
|
|
|
bb432d |
{ "no-imc-log", 0, NULL, O_NO_IMC_LOG },
|
|
|
bb432d |
{ "is-cpu-supported", 0, NULL, O_IS_CPU_SUPPORTED },
|
|
|
bb432d |
- DISKDB_OPTIONS
|
|
|
bb432d |
{}
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
@@ -1191,8 +1193,6 @@ void no_syslog(void)
|
|
|
bb432d |
static int combined_modifier(int opt)
|
|
|
bb432d |
{
|
|
|
bb432d |
int r = modifier(opt);
|
|
|
bb432d |
- if (r == 0)
|
|
|
bb432d |
- r = diskdb_modifier(opt);
|
|
|
bb432d |
return r;
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
@@ -1369,8 +1369,6 @@ int main(int ac, char **av)
|
|
|
bb432d |
noargs(ac, av);
|
|
|
bb432d |
fprintf(stderr, "mcelog %s\n", MCELOG_VERSION);
|
|
|
bb432d |
exit(0);
|
|
|
bb432d |
- } else if (diskdb_cmd(opt, ac, av)) {
|
|
|
bb432d |
- exit(0);
|
|
|
bb432d |
} else if (opt == 0)
|
|
|
bb432d |
break;
|
|
|
bb432d |
}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/mcelog.c.orig mcelog-d2e13bf0/mcelog.c.orig
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/mcelog.c.orig 2016-11-30 11:23:54.540909556 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/mcelog.c.orig 2016-11-30 11:23:40.054327414 -0500
|
|
|
bb432d |
@@ -85,6 +85,7 @@ static char *pidfile = pidfile_default;
|
|
|
bb432d |
static char *logfile;
|
|
|
bb432d |
static int debug_numerrors;
|
|
|
bb432d |
int imc_log = -1;
|
|
|
bb432d |
+static int check_only = 0;
|
|
|
bb432d |
|
|
|
bb432d |
static int is_cpu_supported(void);
|
|
|
bb432d |
|
|
|
bb432d |
@@ -131,7 +132,7 @@ static char *bankname(unsigned bank)
|
|
|
bb432d |
}
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
-static void resolveaddr(unsigned long addr)
|
|
|
bb432d |
+static void resolveaddr(unsigned long long addr)
|
|
|
bb432d |
{
|
|
|
bb432d |
if (addr && do_dmi && dmi_forced)
|
|
|
bb432d |
dmi_decodeaddr(addr);
|
|
|
bb432d |
@@ -232,8 +233,12 @@ static char *cputype_name[] = {
|
|
|
bb432d |
[CPU_HASWELL] = "Haswell", /* Fill in better name */
|
|
|
bb432d |
[CPU_HASWELL_EPEX] = "Haswell EP/EX", /* Fill in better name */
|
|
|
bb432d |
[CPU_BROADWELL] = "Broadwell",
|
|
|
bb432d |
+ [CPU_BROADWELL_DE] = "Intel Xeon (Broadwell) D family",
|
|
|
bb432d |
+ [CPU_BROADWELL_EPEX] = "Intel Xeon v4 (Broadwell) EP/EX",
|
|
|
bb432d |
[CPU_KNIGHTS_LANDING] = "Knights Landing",
|
|
|
bb432d |
[CPU_ATOM] = "ATOM",
|
|
|
bb432d |
+ [CPU_SKYLAKE] = "Skylake",
|
|
|
bb432d |
+ [CPU_SKYLAKE_XEON] = "Skylake server",
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
static struct config_choice cpu_choices[] = {
|
|
|
bb432d |
@@ -273,8 +278,14 @@ static struct config_choice cpu_choices[
|
|
|
bb432d |
{ "haswell-ep", CPU_HASWELL_EPEX }, /* Fill in better name */
|
|
|
bb432d |
{ "haswell-ex", CPU_HASWELL_EPEX }, /* Fill in better name */
|
|
|
bb432d |
{ "broadwell", CPU_BROADWELL },
|
|
|
bb432d |
+ { "broadwell-d", CPU_BROADWELL_DE },
|
|
|
bb432d |
+ { "broadwell-ep", CPU_BROADWELL_EPEX },
|
|
|
bb432d |
+ { "broadwell-ex", CPU_BROADWELL_EPEX },
|
|
|
bb432d |
{ "knightslanding", CPU_KNIGHTS_LANDING },
|
|
|
bb432d |
+ { "xeon-v4", CPU_BROADWELL_EPEX },
|
|
|
bb432d |
{ "atom", CPU_ATOM },
|
|
|
bb432d |
+ { "skylake", CPU_SKYLAKE },
|
|
|
bb432d |
+ { "skylake_server", CPU_SKYLAKE_XEON },
|
|
|
bb432d |
{ NULL }
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
@@ -437,7 +448,9 @@ static void dump_mce(struct mce *m, unsi
|
|
|
bb432d |
}
|
|
|
bb432d |
if (cputype != CPU_SANDY_BRIDGE_EP && cputype != CPU_IVY_BRIDGE_EPEX &&
|
|
|
bb432d |
cputype != CPU_HASWELL_EPEX && cputype != CPU_BROADWELL &&
|
|
|
bb432d |
- cputype != CPU_KNIGHTS_LANDING)
|
|
|
bb432d |
+ cputype != CPU_BROADWELL_DE && cputype != CPU_BROADWELL_EPEX &&
|
|
|
bb432d |
+ cputype != CPU_KNIGHTS_LANDING && cputype != CPU_SKYLAKE &&
|
|
|
bb432d |
+ cputype != CPU_SKYLAKE_XEON)
|
|
|
bb432d |
resolveaddr(m->addr);
|
|
|
bb432d |
if (!ascii_mode && ismemerr && (m->status & MCI_STATUS_ADDRV)) {
|
|
|
bb432d |
diskdb_resolve_addr(m->addr);
|
|
|
bb432d |
@@ -916,22 +929,35 @@ void usage(void)
|
|
|
bb432d |
{
|
|
|
bb432d |
fprintf(stderr,
|
|
|
bb432d |
"Usage:\n"
|
|
|
bb432d |
+"\n"
|
|
|
bb432d |
" mcelog [options] [mcelogdevice]\n"
|
|
|
bb432d |
"Decode machine check error records from current kernel.\n"
|
|
|
bb432d |
+"\n"
|
|
|
bb432d |
" mcelog [options] --daemon\n"
|
|
|
bb432d |
"Run mcelog in daemon mode, waiting for errors from the kernel.\n"
|
|
|
bb432d |
+"\n"
|
|
|
bb432d |
" mcelog [options] --client\n"
|
|
|
bb432d |
"Query a currently running mcelog daemon for errors\n"
|
|
|
bb432d |
+"\n"
|
|
|
bb432d |
" mcelog [options] --ascii < log\n"
|
|
|
bb432d |
" mcelog [options] --ascii --file log\n"
|
|
|
bb432d |
"Decode machine check ASCII output from kernel logs\n"
|
|
|
bb432d |
+"\n"
|
|
|
bb432d |
"Options:\n"
|
|
|
bb432d |
+"--version Show the version of mcelog and exit\n"
|
|
|
bb432d |
"--cpu CPU Set CPU type CPU to decode (see below for valid types)\n"
|
|
|
bb432d |
+"--intel-cpu FAMILY,MODEL Set CPU type for an Intel CPU based on family and model from cpuid\n"
|
|
|
bb432d |
+"--k8 Set the CPU to be an AMD K8\n"
|
|
|
bb432d |
+"--p4 Set the CPU to be an Intel Pentium4\n"
|
|
|
bb432d |
+"--core2 Set the CPU to be an Intel Core2\n"
|
|
|
bb432d |
+"--generic Set the CPU to a generic version\n"
|
|
|
bb432d |
"--cpumhz MHZ Set CPU Mhz to decode time (output unreliable, not needed on new kernels)\n"
|
|
|
bb432d |
"--raw (with --ascii) Dump in raw ASCII format for machine processing\n"
|
|
|
bb432d |
"--daemon Run in background waiting for events (needs newer kernel)\n"
|
|
|
bb432d |
+"--client Query a currently running mcelog daemon for errors\n"
|
|
|
bb432d |
"--ignorenodev Exit silently when the device cannot be opened\n"
|
|
|
bb432d |
"--file filename With --ascii read machine check log from filename instead of stdin\n"
|
|
|
bb432d |
+"--logfile filename Log decoded machine checks in file filename\n"
|
|
|
bb432d |
"--syslog Log decoded machine checks in syslog (default stdout or syslog for daemon)\n"
|
|
|
bb432d |
"--syslog-error Log decoded machine checks in syslog with error level\n"
|
|
|
bb432d |
"--no-syslog Never log anything to syslog\n"
|
|
|
bb432d |
@@ -946,8 +972,10 @@ void usage(void)
|
|
|
bb432d |
"--num-errors N Only process N errors (for testing)\n"
|
|
|
bb432d |
"--pidfile file Write pid of daemon into file\n"
|
|
|
bb432d |
"--no-imc-log Disable extended iMC logging\n"
|
|
|
bb432d |
+"--is-cpu-supported Exit with return code indicating whether the CPU is supported\n"
|
|
|
bb432d |
);
|
|
|
bb432d |
diskdb_usage();
|
|
|
bb432d |
+ printf("\n");
|
|
|
bb432d |
print_cputypes();
|
|
|
bb432d |
exit(1);
|
|
|
bb432d |
}
|
|
|
bb432d |
@@ -980,6 +1008,7 @@ enum options {
|
|
|
bb432d |
O_PIDFILE,
|
|
|
bb432d |
O_DEBUG_NUMERRORS,
|
|
|
bb432d |
O_NO_IMC_LOG,
|
|
|
bb432d |
+ O_IS_CPU_SUPPORTED,
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
static struct option options[] = {
|
|
|
bb432d |
@@ -1013,6 +1042,7 @@ static struct option options[] = {
|
|
|
bb432d |
{ "pidfile", 1, NULL, O_PIDFILE },
|
|
|
bb432d |
{ "debug-numerrors", 0, NULL, O_DEBUG_NUMERRORS }, /* undocumented: for testing */
|
|
|
bb432d |
{ "no-imc-log", 0, NULL, O_NO_IMC_LOG },
|
|
|
bb432d |
+ { "is-cpu-supported", 0, NULL, O_IS_CPU_SUPPORTED },
|
|
|
bb432d |
DISKDB_OPTIONS
|
|
|
bb432d |
{}
|
|
|
bb432d |
};
|
|
|
bb432d |
@@ -1115,6 +1145,9 @@ static int modifier(int opt)
|
|
|
bb432d |
case O_NO_IMC_LOG:
|
|
|
bb432d |
imc_log = 0;
|
|
|
bb432d |
break;
|
|
|
bb432d |
+ case O_IS_CPU_SUPPORTED:
|
|
|
bb432d |
+ check_only = 1;
|
|
|
bb432d |
+ break;
|
|
|
bb432d |
case 0:
|
|
|
bb432d |
break;
|
|
|
bb432d |
default:
|
|
|
bb432d |
@@ -1344,15 +1377,19 @@ int main(int ac, char **av)
|
|
|
bb432d |
|
|
|
bb432d |
/* before doing anything else let's see if the CPUs are supported */
|
|
|
bb432d |
if (!cpu_forced && !is_cpu_supported()) {
|
|
|
bb432d |
- fprintf(stderr, "CPU is unsupported\n");
|
|
|
bb432d |
+ if (!check_only)
|
|
|
bb432d |
+ fprintf(stderr, "CPU is unsupported\n");
|
|
|
bb432d |
exit(1);
|
|
|
bb432d |
}
|
|
|
bb432d |
+ if (check_only)
|
|
|
bb432d |
+ exit(0);
|
|
|
bb432d |
|
|
|
bb432d |
/* If the user didn't tell us not to use iMC logging, check if CPU supports it */
|
|
|
bb432d |
if (imc_log == -1) {
|
|
|
bb432d |
switch (cputype) {
|
|
|
bb432d |
case CPU_SANDY_BRIDGE_EP:
|
|
|
bb432d |
case CPU_IVY_BRIDGE_EPEX:
|
|
|
bb432d |
+ case CPU_HASWELL_EPEX:
|
|
|
bb432d |
imc_log = 1;
|
|
|
bb432d |
break;
|
|
|
bb432d |
default:
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/mcelog.h mcelog-d2e13bf0/mcelog.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/mcelog.h 2016-11-30 11:23:54.539909515 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/mcelog.h 2016-11-30 11:24:12.207619490 -0500
|
|
|
bb432d |
@@ -127,9 +127,12 @@ enum cputype {
|
|
|
bb432d |
CPU_BROADWELL_DE,
|
|
|
bb432d |
CPU_BROADWELL_EPEX,
|
|
|
bb432d |
CPU_KNIGHTS_LANDING,
|
|
|
bb432d |
+ CPU_KNIGHTS_MILL,
|
|
|
bb432d |
CPU_ATOM,
|
|
|
bb432d |
CPU_SKYLAKE,
|
|
|
bb432d |
CPU_SKYLAKE_XEON,
|
|
|
bb432d |
+ CPU_KABYLAKE,
|
|
|
bb432d |
+ CPU_DENVERTON,
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
enum option_ranges {
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/mcelog.service mcelog-d2e13bf0/mcelog.service
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/mcelog.service 2016-11-30 11:23:54.540909556 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/mcelog.service 2016-11-30 11:24:12.207619490 -0500
|
|
|
bb432d |
@@ -5,6 +5,7 @@ After=syslog.target
|
|
|
bb432d |
[Service]
|
|
|
bb432d |
ExecStart=/usr/sbin/mcelog --ignorenodev --daemon --foreground
|
|
|
bb432d |
StandardOutput=syslog
|
|
|
bb432d |
+SuccessExitStatus=0 15
|
|
|
bb432d |
|
|
|
bb432d |
[Install]
|
|
|
bb432d |
WantedBy=multi-user.target
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/msr.c mcelog-d2e13bf0/msr.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/msr.c 2016-11-30 11:23:54.538909475 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/msr.c 2016-11-30 11:24:12.207619490 -0500
|
|
|
bb432d |
@@ -25,19 +25,20 @@ static void domsr(int cpu, int msr, int
|
|
|
bb432d |
}
|
|
|
bb432d |
if (pread(fd, &data, sizeof data, msr) != sizeof data) {
|
|
|
bb432d |
SYSERRprintf("Cannot read MSR_ERROR_CONTROL from %s\n", fpath);
|
|
|
bb432d |
- return;
|
|
|
bb432d |
+ goto out;
|
|
|
bb432d |
}
|
|
|
bb432d |
data |= bit;
|
|
|
bb432d |
if (pwrite(fd, &data, sizeof data, msr) != sizeof data) {
|
|
|
bb432d |
SYSERRprintf("Cannot write MSR_ERROR_CONTROL to %s\n", fpath);
|
|
|
bb432d |
- return;
|
|
|
bb432d |
+ goto out;
|
|
|
bb432d |
}
|
|
|
bb432d |
if (pread(fd, &data, sizeof data, msr) != sizeof data) {
|
|
|
bb432d |
SYSERRprintf("Cannot re-read MSR_ERROR_CONTROL from %s\n", fpath);
|
|
|
bb432d |
- return;
|
|
|
bb432d |
+ goto out;
|
|
|
bb432d |
}
|
|
|
bb432d |
if ((data & bit) == 0)
|
|
|
bb432d |
Lprintf("No DIMM detection available on cpu %d (normal in virtual environments)\n", cpu);
|
|
|
bb432d |
+out:
|
|
|
bb432d |
close(fd);
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/nehalem.c mcelog-d2e13bf0/nehalem.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/nehalem.c 2016-11-30 11:23:54.537909435 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/nehalem.c 2016-11-30 11:24:12.207619490 -0500
|
|
|
bb432d |
@@ -24,7 +24,6 @@
|
|
|
bb432d |
#include "nehalem.h"
|
|
|
bb432d |
#include "bitfield.h"
|
|
|
bb432d |
#include "memdb.h"
|
|
|
bb432d |
-#include "xeon75xx.h"
|
|
|
bb432d |
|
|
|
bb432d |
/* See IA32 SDM Vol3B Appendix E.3.2 ff */
|
|
|
bb432d |
|
|
|
bb432d |
@@ -130,7 +129,8 @@ void decode_memory_controller(u32 status
|
|
|
bb432d |
if ((status & 0xf) == 0xf)
|
|
|
bb432d |
strcpy(channel, "unspecified");
|
|
|
bb432d |
else {
|
|
|
bb432d |
- if (cputype == CPU_KNIGHTS_LANDING) /* Fix for Knights Landing MIC */
|
|
|
bb432d |
+ /* Fix for Knights Landing/Mill MIC */
|
|
|
bb432d |
+ if (cputype == CPU_KNIGHTS_LANDING || cputype == CPU_KNIGHTS_MILL)
|
|
|
bb432d |
sprintf(channel, "%u", (status & 0xf) + 3 * (bank == 15));
|
|
|
bb432d |
else
|
|
|
bb432d |
sprintf(channel, "%u", status & 0xf);
|
|
|
bb432d |
@@ -170,7 +170,6 @@ void xeon75xx_decode_model(struct mce *m
|
|
|
bb432d |
decode_bitfield(status, internal_error_status);
|
|
|
bb432d |
decode_numfield(status, internal_error_numbers);
|
|
|
bb432d |
}
|
|
|
bb432d |
- xeon75xx_decode_dimm(m, msize);
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
/* Nehalem-EP specific DIMM decoding */
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/p4.c mcelog-d2e13bf0/p4.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/p4.c 2016-11-30 11:23:54.534909314 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/p4.c 2016-11-30 11:24:12.208619530 -0500
|
|
|
bb432d |
@@ -39,6 +39,7 @@
|
|
|
bb432d |
#include "broadwell_de.h"
|
|
|
bb432d |
#include "broadwell_epex.h"
|
|
|
bb432d |
#include "skylake_xeon.h"
|
|
|
bb432d |
+#include "denverton.h"
|
|
|
bb432d |
|
|
|
bb432d |
/* decode mce for P4/Xeon and Core2 family */
|
|
|
bb432d |
|
|
|
bb432d |
@@ -289,10 +290,29 @@ static const char *arstate[4] = {
|
|
|
bb432d |
[3] = "SRAR"
|
|
|
bb432d |
};
|
|
|
bb432d |
|
|
|
bb432d |
+static const char *ce_types[] = {
|
|
|
bb432d |
+ [0] = "ecc",
|
|
|
bb432d |
+ [1] = "mirroring with channel failover",
|
|
|
bb432d |
+ [2] = "mirroring. Primary channel scrubbed successfully"
|
|
|
bb432d |
+};
|
|
|
bb432d |
+
|
|
|
bb432d |
+static int check_for_mirror(__u8 bank, __u64 status, __u64 misc)
|
|
|
bb432d |
+{
|
|
|
bb432d |
+ switch (cputype) {
|
|
|
bb432d |
+ case CPU_BROADWELL_EPEX:
|
|
|
bb432d |
+ return bdw_epex_ce_type(bank, status, misc);
|
|
|
bb432d |
+ case CPU_SKYLAKE_XEON:
|
|
|
bb432d |
+ return skylake_s_ce_type(bank, status, misc);
|
|
|
bb432d |
+ default:
|
|
|
bb432d |
+ return 0;
|
|
|
bb432d |
+ }
|
|
|
bb432d |
+}
|
|
|
bb432d |
+
|
|
|
bb432d |
static int decode_mci(__u64 status, __u64 misc, int cpu, unsigned mcgcap, int *ismemerr,
|
|
|
bb432d |
int socket, __u8 bank)
|
|
|
bb432d |
{
|
|
|
bb432d |
u64 track = 0;
|
|
|
bb432d |
+ int i;
|
|
|
bb432d |
|
|
|
bb432d |
Wprintf("MCi status:\n");
|
|
|
bb432d |
if (!(status & MCI_STATUS_VAL))
|
|
|
bb432d |
@@ -303,6 +323,8 @@ static int decode_mci(__u64 status, __u6
|
|
|
bb432d |
|
|
|
bb432d |
if (status & MCI_STATUS_UC)
|
|
|
bb432d |
Wprintf("Uncorrected error\n");
|
|
|
bb432d |
+ else if ((i = check_for_mirror(bank, status, misc)))
|
|
|
bb432d |
+ Wprintf("Corrected error by %s\n", ce_types[i]);
|
|
|
bb432d |
else
|
|
|
bb432d |
Wprintf("Corrected error\n");
|
|
|
bb432d |
|
|
|
bb432d |
@@ -428,6 +450,9 @@ void decode_intel_mc(struct mce *log, in
|
|
|
bb432d |
case CPU_SKYLAKE_XEON:
|
|
|
bb432d |
skylake_s_decode_model(cputype, log->bank, log->status, log->misc);
|
|
|
bb432d |
break;
|
|
|
bb432d |
+ case CPU_DENVERTON:
|
|
|
bb432d |
+ denverton_decode_model(cputype, log->bank, log->status, log->misc);
|
|
|
bb432d |
+ break;
|
|
|
bb432d |
}
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/README mcelog-d2e13bf0/README
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/README 2016-11-30 11:23:54.538909475 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/README 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,119 +0,0 @@
|
|
|
bb432d |
-mcelog is the user space backend for logging machine check errors
|
|
|
bb432d |
-reported by the hardware to the kernel. The kernel does the immediate
|
|
|
bb432d |
-actions (like killing processes etc.) and mcelog decodes the errors
|
|
|
bb432d |
-and manages various other advanced error responses like
|
|
|
bb432d |
-offlining memory, CPUs or triggering events. In addition
|
|
|
bb432d |
-mcelog also handles corrected errors, by logging and accounting them.
|
|
|
bb432d |
-
|
|
|
bb432d |
-It primarily handles machine checks and thermal events, which
|
|
|
bb432d |
-are reported for errors detected by the CPU.
|
|
|
bb432d |
-
|
|
|
bb432d |
-For more details on what mcelog can do and the underlying theory
|
|
|
bb432d |
-see http://www.mcelog.org
|
|
|
bb432d |
-
|
|
|
bb432d |
-It is recommended that mcelog runs on all x86 machines, both
|
|
|
bb432d |
-64bit (since early 2.6) and 32bit (since 2.6.32)
|
|
|
bb432d |
-
|
|
|
bb432d |
-mcelog can run in several modi: cronjob, trigger, daemon
|
|
|
bb432d |
-
|
|
|
bb432d |
-cronjob is the old method. mcelog runs every 5 minutes from cron and checks
|
|
|
bb432d |
-for errors. Disadvantage of this is that it can delay error reporting
|
|
|
bb432d |
-significantly (upto 10 minutes) and does not allow mcelog to keep extended state.
|
|
|
bb432d |
-
|
|
|
bb432d |
-trigger is a newer method where the kernel runs mcelog on a error.
|
|
|
bb432d |
-This is configured with
|
|
|
bb432d |
-echo /usr/sbin/mcelog > /sys/devices/system/machinecheck/machinecheck0/trigger
|
|
|
bb432d |
-This is faster, but still doesn't allow mcelog to keep state,
|
|
|
bb432d |
-and has relatively high overhead for each error because a program has
|
|
|
bb432d |
-to be initialized from scratch.
|
|
|
bb432d |
-
|
|
|
bb432d |
-In daemon mode mcelog runs continuously as a daemon in the background
|
|
|
bb432d |
-and wait for errors. It is enabled by running mcelog --daemon &
|
|
|
bb432d |
-from a init script. This is the fastest and most feature-ful.
|
|
|
bb432d |
-
|
|
|
bb432d |
-The recommended mode is daemon, because several new functions (like page error
|
|
|
bb432d |
-predictive failure analysis) require a continuously running daemon.
|
|
|
bb432d |
-
|
|
|
bb432d |
-Documentation:
|
|
|
bb432d |
-
|
|
|
bb432d |
-The primary reference documentation are the man pages.
|
|
|
bb432d |
-lk10-mcelog.pdf has a overview over the errors mcelog handles
|
|
|
bb432d |
-(originally from Linux Kongress 2010)
|
|
|
bb432d |
-mce.pdf is a very old paper describing the first releases of mcelog
|
|
|
bb432d |
-(some parts are obsolete)
|
|
|
bb432d |
-
|
|
|
bb432d |
-For distributors:
|
|
|
bb432d |
-
|
|
|
bb432d |
-You can run mcelog from systemd or similar daemons. An example
|
|
|
bb432d |
-systemd unit file is in mcelog.service.
|
|
|
bb432d |
-
|
|
|
bb432d |
-For older distributions using init scripts:
|
|
|
bb432d |
-
|
|
|
bb432d |
-Please install a init script by default that runs mcelog in daemon mode.
|
|
|
bb432d |
-The mcelog.init script is a good starting point.
|
|
|
bb432d |
-
|
|
|
bb432d |
-Also install a logrotated file (mcelog.logrotate) or equivalent
|
|
|
bb432d |
-when mcelog is running in daemon mode.
|
|
|
bb432d |
-
|
|
|
bb432d |
-These two are not in make install.
|
|
|
bb432d |
-
|
|
|
bb432d |
-The installation also requires a config file (/etc/mcelog.conf) and
|
|
|
bb432d |
-the default triggers. These are all installed by "make install"
|
|
|
bb432d |
-
|
|
|
bb432d |
-/dev/mcelog is needed for mcelog operation
|
|
|
bb432d |
-If it's not there it can be created with mknod /dev/mcelog c 10 227
|
|
|
bb432d |
-Normally it should be created automatically in udev.
|
|
|
bb432d |
-
|
|
|
bb432d |
-Security:
|
|
|
bb432d |
-
|
|
|
bb432d |
-mcelog needs to run as root because it might trigger actions like
|
|
|
bb432d |
-page-offlining, which require CAP_SYS_ADMIN. Also it opens /dev/mcelog
|
|
|
bb432d |
-and a unix socket for client support.
|
|
|
bb432d |
-
|
|
|
bb432d |
-It also opens /dev/mem to parse the BIOS DMI tables. It is careful
|
|
|
bb432d |
-to close the file descriptor and unmap any mappings after using them.
|
|
|
bb432d |
-
|
|
|
bb432d |
-There is support for changing the user in daemon mode after opening
|
|
|
bb432d |
-the device and the sockets, but that would stop triggers from
|
|
|
bb432d |
-doing corrective action that require root.
|
|
|
bb432d |
-
|
|
|
bb432d |
-In principle it would be possible to only keep CAP_SYS_ADMIN
|
|
|
bb432d |
-for page-offling, but that would prevent triggers from doing root
|
|
|
bb432d |
-only actions not covered by it (and CAP_SYS_ADMIN is not that different
|
|
|
bb432d |
-from full root)
|
|
|
bb432d |
-
|
|
|
bb432d |
-In daemon mode mcelog listens to a unix socket and processes
|
|
|
bb432d |
-requests from mcelog --client. This can be disabled in the configuration file.
|
|
|
bb432d |
-The uid/gid of the requestor is checked on access and is configurable
|
|
|
bb432d |
-(default 0/0 only). The command parsing code is very straight forward
|
|
|
bb432d |
-(server.c) The client parsing/reply is currently done with full privileges
|
|
|
bb432d |
-of the daemon.
|
|
|
bb432d |
-
|
|
|
bb432d |
-Testing:
|
|
|
bb432d |
-
|
|
|
bb432d |
-There is a simple test suite in tests/. The test suite requires root to
|
|
|
bb432d |
-run and access to mce-inject and a kernel with MCE injection support
|
|
|
bb432d |
-(CONFIG_X86_MCE_INJECT). It will kill any running mcelog daemon.
|
|
|
bb432d |
-
|
|
|
bb432d |
-Run it with "make test"
|
|
|
bb432d |
-
|
|
|
bb432d |
-The test suite requires the mce-inject tool, available from
|
|
|
bb432d |
-git://git.kernel.org/pub/utils/cpu/mce/mce-inject.git
|
|
|
bb432d |
-The mce-inject executable must be either in $PATH or in the
|
|
|
bb432d |
-../mce-inject directory.
|
|
|
bb432d |
-
|
|
|
bb432d |
-You can also test under valgrind with "make valgrind-test". For
|
|
|
bb432d |
-this valgrind needs to be installed of course. Advanced
|
|
|
bb432d |
-valgrind options can be specified with
|
|
|
bb432d |
-make VALGRIND="valgrind --option" valgrind-test
|
|
|
bb432d |
-
|
|
|
bb432d |
-Other checks:
|
|
|
bb432d |
-
|
|
|
bb432d |
-make iccverify and make clangverify run the static verifiers
|
|
|
bb432d |
-in clang and icc respectively.
|
|
|
bb432d |
-
|
|
|
bb432d |
-License:
|
|
|
bb432d |
-
|
|
|
bb432d |
-This program is licensed under the subject of the GNU Public General
|
|
|
bb432d |
-License, v.2
|
|
|
bb432d |
-
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/README.md mcelog-d2e13bf0/README.md
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/README.md 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/README.md 2016-11-30 11:24:12.202619289 -0500
|
|
|
bb432d |
@@ -0,0 +1,129 @@
|
|
|
bb432d |
+# mcelog
|
|
|
bb432d |
+
|
|
|
bb432d |
+mcelog is the user space backend for logging machine check errors reported
|
|
|
bb432d |
+by the hardware to the kernel. The kernel does the immediate actions
|
|
|
bb432d |
+(like killing processes etc.) and mcelog decodes the errors and manages
|
|
|
bb432d |
+various other advanced error responses like offlining memory, CPUs or triggering
|
|
|
bb432d |
+events. In addition mcelog also handles corrected errors, by logging and
|
|
|
bb432d |
+accounting them.
|
|
|
bb432d |
+It primarily handles machine checks and thermal events, which are reported
|
|
|
bb432d |
+for errors detected by the CPU.
|
|
|
bb432d |
+
|
|
|
bb432d |
+For more details on what mcelog can do and the underlying theory
|
|
|
bb432d |
+see [mcelog.org](http://www.mcelog.org).
|
|
|
bb432d |
+
|
|
|
bb432d |
+It is recommended that mcelog runs on all x86 machines, both 64bit
|
|
|
bb432d |
+(since early 2.6) and 32bit (since 2.6.32).
|
|
|
bb432d |
+
|
|
|
bb432d |
+mcelog can run in several modes:
|
|
|
bb432d |
+
|
|
|
bb432d |
+- cronjob
|
|
|
bb432d |
+- trigger
|
|
|
bb432d |
+- daemon
|
|
|
bb432d |
+
|
|
|
bb432d |
+**cronjob** is the old method. mcelog runs every 5 minutes from cron and checks
|
|
|
bb432d |
+for errors. Disadvantage of this is that it can delay error reporting
|
|
|
bb432d |
+significantly (upto 10 minutes) and does not allow mcelog to keep extended state.
|
|
|
bb432d |
+
|
|
|
bb432d |
+**trigger** is a newer method where the kernel runs mcelog on a error.
|
|
|
bb432d |
+
|
|
|
bb432d |
+This is configured with:
|
|
|
bb432d |
+```sh
|
|
|
bb432d |
+echo /usr/sbin/mcelog > /sys/devices/system/machinecheck/machinecheck0/trigger
|
|
|
bb432d |
+```
|
|
|
bb432d |
+This is faster, but still doesn't allow mcelog to keep state,
|
|
|
bb432d |
+and has relatively high overhead for each error because a program has
|
|
|
bb432d |
+to be initialized from scratch.
|
|
|
bb432d |
+
|
|
|
bb432d |
+In **daemon** mode mcelog runs continuously as a daemon in the background and
|
|
|
bb432d |
+wait for errors. It is enabled by running `mcelog --daemon &`
|
|
|
bb432d |
+from a init script. This is the fastest and most feature-ful.
|
|
|
bb432d |
+
|
|
|
bb432d |
+The recommended mode is **daemon**, because several new functions (like page
|
|
|
bb432d |
+error predictive failure analysis) require a continuously running daemon.
|
|
|
bb432d |
+
|
|
|
bb432d |
+## Documentation
|
|
|
bb432d |
+
|
|
|
bb432d |
+- The primary reference documentation are the man pages.
|
|
|
bb432d |
+- [lk10-mcelog.pdf](https://github.com/andikleen/mcelog/blob/master/lk10-mcelog.pdf)
|
|
|
bb432d |
+ has a overview over the errors mcelog handles (originally from Linux Kongress 2010).
|
|
|
bb432d |
+- [mce.pdf](https://github.com/mjtrangoni/mcelog/blob/README.md/mce.pdf)
|
|
|
bb432d |
+ is a very old paper describing the first releases of mcelog (some parts are obsolete).
|
|
|
bb432d |
+
|
|
|
bb432d |
+## For distributors
|
|
|
bb432d |
+
|
|
|
bb432d |
+You can run mcelog from systemd or similar daemons. An example systemd unit
|
|
|
bb432d |
+file is in `mcelog.service`.
|
|
|
bb432d |
+
|
|
|
bb432d |
+### For older distributions using init scripts
|
|
|
bb432d |
+
|
|
|
bb432d |
+Please install an init script by default that runs mcelog in daemon mode.
|
|
|
bb432d |
+The `mcelog.init` script is a good starting point. Also install a
|
|
|
bb432d |
+logrotated file (mcelog.logrotate) or equivalent when mcelog is running
|
|
|
bb432d |
+in daemon mode.
|
|
|
bb432d |
+These two are not in make install.
|
|
|
bb432d |
+
|
|
|
bb432d |
+The installation also requires a config file `/etc/mcelog.conf` and the default
|
|
|
bb432d |
+triggers. These are all installed by `make install`
|
|
|
bb432d |
+
|
|
|
bb432d |
+`/dev/mcelog` is needed for mcelog operation. If it's not there it can be
|
|
|
bb432d |
+created with:
|
|
|
bb432d |
+```sh
|
|
|
bb432d |
+mknod /dev/mcelog c 10 227
|
|
|
bb432d |
+```
|
|
|
bb432d |
+
|
|
|
bb432d |
+Normally it should be created automatically in udev.
|
|
|
bb432d |
+
|
|
|
bb432d |
+## Security
|
|
|
bb432d |
+
|
|
|
bb432d |
+mcelog needs to run as root because it might trigger actions like
|
|
|
bb432d |
+page-offlining, which require `CAP_SYS_ADMIN`. Also it opens `/dev/mcelog`
|
|
|
bb432d |
+and an UNIX socket for client support.
|
|
|
bb432d |
+
|
|
|
bb432d |
+It also opens `/dev/mem` to parse the BIOS DMI tables. It is careful to close
|
|
|
bb432d |
+the file descriptor and unmap any mappings after using them.
|
|
|
bb432d |
+
|
|
|
bb432d |
+There is support for changing the user in daemon mode after opening the device
|
|
|
bb432d |
+and the sockets, but that would stop triggers from doing corrective action
|
|
|
bb432d |
+that require `root`.
|
|
|
bb432d |
+
|
|
|
bb432d |
+In principle it would be possible to only keep `CAP_SYS_ADMIN` for page-offling,
|
|
|
bb432d |
+but that would prevent triggers from doing root-only actions not covered by
|
|
|
bb432d |
+it (and `CAP_SYS_ADMIN` is not that different from full root)
|
|
|
bb432d |
+
|
|
|
bb432d |
+In `daemon` mode mcelog listens to a UNIX socket and processes requests from
|
|
|
bb432d |
+`sh mcelog --client`. This can be disabled in the configuration file.
|
|
|
bb432d |
+The uid/gid of the requestor is checked on access and is configurable
|
|
|
bb432d |
+(default 0/0 only). The command parsing code is very straight forward
|
|
|
bb432d |
+(server.c). The client parsing/reply is currently done with full privileges
|
|
|
bb432d |
+of the `daemon`.
|
|
|
bb432d |
+
|
|
|
bb432d |
+## Testing
|
|
|
bb432d |
+
|
|
|
bb432d |
+There is a simple test suite in `sh tests/`. The test suite requires root to
|
|
|
bb432d |
+run and access to mce-inject and a kernel with MCE injection support
|
|
|
bb432d |
+`CONFIG_X86_MCE_INJECT`. It will kill any running mcelog daemon.
|
|
|
bb432d |
+
|
|
|
bb432d |
+Run it with `sh make test`.
|
|
|
bb432d |
+
|
|
|
bb432d |
+The test suite requires the
|
|
|
bb432d |
+[mce-inject](git://git.kernel.org/pub/utils/cpu/mce/mce-inject.git) tool.
|
|
|
bb432d |
+The `mce-inject` executable must be either in `$PATH` or in the
|
|
|
bb432d |
+`../mce-inject` directory.
|
|
|
bb432d |
+
|
|
|
bb432d |
+You can also test under **valgrind** with `sh make valgrind-test`. For this
|
|
|
bb432d |
+valgrind needs to be installed of course. Advanced valgrind options can be
|
|
|
bb432d |
+specified with:
|
|
|
bb432d |
+```sh
|
|
|
bb432d |
+make VALGRIND="valgrind --option" valgrind-test
|
|
|
bb432d |
+```
|
|
|
bb432d |
+
|
|
|
bb432d |
+### Other checks
|
|
|
bb432d |
+
|
|
|
bb432d |
+`make iccverify` and `make clangverify` run the static verifiers in *clang*
|
|
|
bb432d |
+and *icc* respectively.
|
|
|
bb432d |
+
|
|
|
bb432d |
+## License
|
|
|
bb432d |
+
|
|
|
bb432d |
+This program is licensed under the subject of the GNU Public General
|
|
|
bb432d |
+License, v.2
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/skylake_xeon.c mcelog-d2e13bf0/skylake_xeon.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/skylake_xeon.c 2016-11-30 11:23:54.538909475 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/skylake_xeon.c 2016-11-30 11:24:12.208619530 -0500
|
|
|
bb432d |
@@ -23,6 +23,11 @@
|
|
|
bb432d |
#include "skylake_xeon.h"
|
|
|
bb432d |
#include "memdb.h"
|
|
|
bb432d |
|
|
|
bb432d |
+/* Memory error was corrected by mirroring with channel failover */
|
|
|
bb432d |
+#define SKX_MCI_MISC_FO (1ULL<<63)
|
|
|
bb432d |
+/* Memory error was corrected by mirroring and primary channel scrubbed successfully */
|
|
|
bb432d |
+#define SKX_MCI_MISC_MC (1ULL<<62)
|
|
|
bb432d |
+
|
|
|
bb432d |
/* See IA32 SDM Vol3B Table 16-27 */
|
|
|
bb432d |
|
|
|
bb432d |
static char *pcu_1[] = {
|
|
|
bb432d |
@@ -208,3 +213,18 @@ void skylake_s_decode_model(int cputype,
|
|
|
bb432d |
break;
|
|
|
bb432d |
}
|
|
|
bb432d |
}
|
|
|
bb432d |
+
|
|
|
bb432d |
+int skylake_s_ce_type(int bank, u64 status, u64 misc)
|
|
|
bb432d |
+{
|
|
|
bb432d |
+ if (!(bank == 7 || bank == 8))
|
|
|
bb432d |
+ return 0;
|
|
|
bb432d |
+
|
|
|
bb432d |
+ if (status & MCI_STATUS_MISCV) {
|
|
|
bb432d |
+ if (misc & SKX_MCI_MISC_FO)
|
|
|
bb432d |
+ return 1;
|
|
|
bb432d |
+ if (misc & SKX_MCI_MISC_MC)
|
|
|
bb432d |
+ return 2;
|
|
|
bb432d |
+ }
|
|
|
bb432d |
+
|
|
|
bb432d |
+ return 0;
|
|
|
bb432d |
+}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/skylake_xeon.h mcelog-d2e13bf0/skylake_xeon.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/skylake_xeon.h 2016-11-30 11:23:54.539909515 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/skylake_xeon.h 2016-11-30 11:24:12.208619530 -0500
|
|
|
bb432d |
@@ -1 +1,2 @@
|
|
|
bb432d |
void skylake_s_decode_model(int cputype, int bank, u64 status, u64 misc);
|
|
|
bb432d |
+int skylake_s_ce_type(int bank, u64 status, u64 misc);
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/sysfs.c mcelog-d2e13bf0/sysfs.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/sysfs.c 2016-11-30 11:23:54.534909314 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/sysfs.c 2016-11-30 11:24:12.208619530 -0500
|
|
|
bb432d |
@@ -37,10 +37,10 @@ char *read_field(char *base, char *name)
|
|
|
bb432d |
|
|
|
bb432d |
asprintf(&fn, "%s/%s", base, name);
|
|
|
bb432d |
fd = open(fn, O_RDONLY);
|
|
|
bb432d |
+ free(fn);
|
|
|
bb432d |
if (fstat(fd, &st) < 0)
|
|
|
bb432d |
goto bad;
|
|
|
bb432d |
buf = xalloc(st.st_size);
|
|
|
bb432d |
- free(fn);
|
|
|
bb432d |
if (fd < 0)
|
|
|
bb432d |
goto bad;
|
|
|
bb432d |
n = read(fd, buf, st.st_size);
|
|
|
bb432d |
@@ -81,10 +81,12 @@ unsigned read_field_map(char *base, char
|
|
|
bb432d |
if (!strcmp(val, map->name))
|
|
|
bb432d |
break;
|
|
|
bb432d |
}
|
|
|
bb432d |
- free(val);
|
|
|
bb432d |
- if (map->name)
|
|
|
bb432d |
+ if (map->name) {
|
|
|
bb432d |
+ free(val);
|
|
|
bb432d |
return map->value;
|
|
|
bb432d |
+ }
|
|
|
bb432d |
Eprintf("sysfs field %s/%s has unknown string value `%s'\n", base, name, val);
|
|
|
bb432d |
+ free(val);
|
|
|
bb432d |
return -1;
|
|
|
bb432d |
}
|
|
|
bb432d |
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/TODO-diskdb mcelog-d2e13bf0/TODO-diskdb
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/TODO-diskdb 2016-11-30 11:23:54.530909154 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/TODO-diskdb 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,31 +0,0 @@
|
|
|
bb432d |
-
|
|
|
bb432d |
-diskdb was a experimental attempt to track errors per DIMM
|
|
|
bb432d |
-on disk. It ran into problems unfortunately.
|
|
|
bb432d |
-
|
|
|
bb432d |
-diskdb is not compiled by default now. It can be enabled with
|
|
|
bb432d |
-make CONFIG_DISKDB=1
|
|
|
bb432d |
-
|
|
|
bb432d |
-It is replaced with a new memory only database now that
|
|
|
bb432d |
-relies on daemon mode.
|
|
|
bb432d |
-
|
|
|
bb432d |
-Open fundamental issues:
|
|
|
bb432d |
-- DIMM tracking over boot doesn't work due to SMBIOS not reporting
|
|
|
bb432d |
-serial numbers
|
|
|
bb432d |
-
|
|
|
bb432d |
-Code problems:
|
|
|
bb432d |
-- Missing aging
|
|
|
bb432d |
-- For Intel Nehalem CE errors need reverse smbios translation
|
|
|
bb432d |
-- SMBIOS interleaving decoding missing
|
|
|
bb432d |
-- Some crash races in db.c (see comments there)
|
|
|
bb432d |
-- Need lock timeout
|
|
|
bb432d |
-- Default enable/disable heuristics (smbios check etc.)
|
|
|
bb432d |
-- write db test suite (with crash)
|
|
|
bb432d |
-
|
|
|
bb432d |
-General:
|
|
|
bb432d |
-- Missing CPU database
|
|
|
bb432d |
-
|
|
|
bb432d |
-Missing:
|
|
|
bb432d |
-- rename to different name without memory
|
|
|
bb432d |
-
|
|
|
bb432d |
-Old:
|
|
|
bb432d |
-- add ifdef for memory because it's broken
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/xeon75xx.c mcelog-d2e13bf0/xeon75xx.c
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/xeon75xx.c 2016-11-30 11:23:54.537909435 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/xeon75xx.c 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,39 +0,0 @@
|
|
|
bb432d |
-/* Copyright (C) 2009/2010 Intel Corporation
|
|
|
bb432d |
-
|
|
|
bb432d |
- Decode Intel Xeon75xx memory errors. Requires the mce-75xx.ko driver
|
|
|
bb432d |
- load. The core errors are the same as Nehalem.
|
|
|
bb432d |
-
|
|
|
bb432d |
- mcelog is free software; you can redistribute it and/or
|
|
|
bb432d |
- modify it under the terms of the GNU General Public
|
|
|
bb432d |
- License as published by the Free Software Foundation; version
|
|
|
bb432d |
- 2.
|
|
|
bb432d |
-
|
|
|
bb432d |
- mcelog is distributed in the hope that it will be useful,
|
|
|
bb432d |
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
bb432d |
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
bb432d |
- General Public License for more details.
|
|
|
bb432d |
-
|
|
|
bb432d |
- You should find a copy of v2 of the GNU General Public License somewhere
|
|
|
bb432d |
- on your Linux system; if not, write to the Free Software Foundation,
|
|
|
bb432d |
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
bb432d |
-
|
|
|
bb432d |
- Author: Andi Kleen
|
|
|
bb432d |
-*/
|
|
|
bb432d |
-
|
|
|
bb432d |
-#include <stdio.h>
|
|
|
bb432d |
-#include <stddef.h>
|
|
|
bb432d |
-#include "mcelog.h"
|
|
|
bb432d |
-#include "xeon75xx.h"
|
|
|
bb432d |
-
|
|
|
bb432d |
-/* This used to decode the old xeon 75xx memory error aux format. But that has never
|
|
|
bb432d |
- been merged into mainline kernels, so removed it again. */
|
|
|
bb432d |
-
|
|
|
bb432d |
-void
|
|
|
bb432d |
-xeon75xx_memory_error(struct mce *m, unsigned msize, int *channel, int *dimm)
|
|
|
bb432d |
-{
|
|
|
bb432d |
-}
|
|
|
bb432d |
-
|
|
|
bb432d |
-
|
|
|
bb432d |
-void xeon75xx_decode_dimm(struct mce *m, unsigned msize)
|
|
|
bb432d |
-{
|
|
|
bb432d |
-}
|
|
|
bb432d |
diff -urNp mcelog-d2e13bf0.orig/xeon75xx.h mcelog-d2e13bf0/xeon75xx.h
|
|
|
bb432d |
--- mcelog-d2e13bf0.orig/xeon75xx.h 2016-11-30 11:23:54.537909435 -0500
|
|
|
bb432d |
+++ mcelog-d2e13bf0/xeon75xx.h 1969-12-31 19:00:00.000000000 -0500
|
|
|
bb432d |
@@ -1,2 +0,0 @@
|
|
|
bb432d |
-void xeon75xx_memory_error(struct mce *m, unsigned msize, int *channel, int *dimm);
|
|
|
bb432d |
-void xeon75xx_decode_dimm(struct mce *m, unsigned msize);
|