[Midnightbsd-cvs] mports [22975] trunk/sysutils: add mcelog
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Nov 25 10:55:36 EST 2017
Revision: 22975
http://svnweb.midnightbsd.org/mports/?rev=22975
Author: laffer1
Date: 2017-11-25 10:55:35 -0500 (Sat, 25 Nov 2017)
Log Message:
-----------
add mcelog
Modified Paths:
--------------
trunk/sysutils/Makefile
Added Paths:
-----------
trunk/sysutils/mcelog/
trunk/sysutils/mcelog/Makefile
trunk/sysutils/mcelog/distinfo
trunk/sysutils/mcelog/files/
trunk/sysutils/mcelog/files/memstream.c
trunk/sysutils/mcelog/files/patch-Makefile
trunk/sysutils/mcelog/files/patch-cache.c
trunk/sysutils/mcelog/files/patch-client.c
trunk/sysutils/mcelog/files/patch-config.c
trunk/sysutils/mcelog/files/patch-eventloop.c
trunk/sysutils/mcelog/files/patch-intel.c
trunk/sysutils/mcelog/files/patch-mcelog.c
trunk/sysutils/mcelog/files/patch-mcelog.h
trunk/sysutils/mcelog/files/patch-memdb.c
trunk/sysutils/mcelog/files/patch-p4.c
trunk/sysutils/mcelog/files/patch-server.c
trunk/sysutils/mcelog/files/patch-tsc.c
trunk/sysutils/mcelog/pkg-descr
trunk/sysutils/mcelog/pkg-message
Modified: trunk/sysutils/Makefile
===================================================================
--- trunk/sysutils/Makefile 2017-11-25 15:26:56 UTC (rev 22974)
+++ trunk/sysutils/Makefile 2017-11-25 15:55:35 UTC (rev 22975)
@@ -70,6 +70,7 @@
SUBDIR += lscpu
SUBDIR += lsof
SUBDIR += mbmon
+SUBDIR += mcelog
SUBDIR += mdf2iso
SUBDIR += memtest
SUBDIR += memtest86
Added: trunk/sysutils/mcelog/Makefile
===================================================================
--- trunk/sysutils/mcelog/Makefile (rev 0)
+++ trunk/sysutils/mcelog/Makefile 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,42 @@
+# Created by: Jeremy Chadwick <freebsd at jdc.parodius.com>
+# $FreeBSD: head/sysutils/mcelog/Makefile 444980 2017-07-03 19:06:08Z ultima $
+# $MidnightBSD$
+
+PORTNAME= mcelog
+PORTVERSION= 153
+DISTVERSIONPREFIX= v
+CATEGORIES= sysutils
+
+MAINTAINER= ports at MidnightBSD.org
+COMMENT= Collects and decodes Machine Check Exception data
+
+LICENSE= gpl2
+
+TEST_DEPENDS= bash:shells/bash
+
+USE_GITHUB= yes
+GH_ACCOUNT= andikleen
+
+USES= alias gmake shebangfix
+
+SHEBANG_FILES= tests/cache/inject tests/memdb/inject tests/page/inject \
+ tests/pfa/inject tests/server/inject tests/socket/inject \
+ tests/trigger tests/unknown/inject
+
+MAKE_ENV+= FREEBSD=1
+MAKE_ARGS+= CFLAGS="${CFLAGS}" prefix="${PREFIX}"
+LDFLAGS+= -lkvm
+
+PLIST_FILES= bin/mcelog man/man8/mcelog.8.gz
+
+post-patch:
+ @${ECHO} "${DISTVERSIONPREFIX}${PORTVERSION}" >${WRKSRC}/.os_version
+ @${CP} ${FILESDIR}/memstream.c ${WRKSRC}/memstream.c
+ @${REINPLACE_CMD} 's/\"unknown\"/\"${PORTVERSION}\"/' \
+ ${WRKSRC}/Makefile
+
+do-install:
+ ${INSTALL_PROGRAM} ${WRKSRC}/mcelog ${STAGEDIR}${PREFIX}/bin
+ ${INSTALL_MAN} ${WRKSRC}/mcelog.8 ${STAGEDIR}${MANPREFIX}/man/man8
+
+.include <bsd.port.mk>
Property changes on: trunk/sysutils/mcelog/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/distinfo
===================================================================
--- trunk/sysutils/mcelog/distinfo (rev 0)
+++ trunk/sysutils/mcelog/distinfo 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,3 @@
+TIMESTAMP = 1511625305
+SHA256 (mcelog-v153_GH0.tar.gz) = 9b827f708855804b6952de6f6cbf2f6523fa1203c621e6050064388f459646f1
+SIZE (mcelog-v153_GH0.tar.gz) = 297099
Property changes on: trunk/sysutils/mcelog/distinfo
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/memstream.c
===================================================================
--- trunk/sysutils/mcelog/files/memstream.c (rev 0)
+++ trunk/sysutils/mcelog/files/memstream.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,133 @@
+/* Use funopen(3) to provide open_memstream(3) like functionality. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+struct memstream {
+ char **cp;
+ size_t *lenp;
+ size_t offset;
+};
+
+FILE *
+open_memstream(char **cp, size_t *lenp);
+
+static void
+memstream_grow(struct memstream *ms, size_t newsize)
+{
+ char *buf;
+
+ if (newsize > *ms->lenp) {
+ buf = realloc(*ms->cp, newsize + 1);
+ if (buf != NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "MS: %p growing from %zd to %zd\n",
+ ms, *ms->lenp, newsize);
+#endif
+ memset(buf + *ms->lenp + 1, 0, newsize - *ms->lenp);
+ *ms->cp = buf;
+ *ms->lenp = newsize;
+ }
+ }
+}
+
+static int
+memstream_read(void *cookie, char *buf, int len)
+{
+ struct memstream *ms;
+ int tocopy;
+
+ ms = cookie;
+ memstream_grow(ms, ms->offset + len);
+ tocopy = *ms->lenp - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(buf, *ms->cp + ms->offset, tocopy);
+ ms->offset += tocopy;
+#ifdef DEBUG
+ fprintf(stderr, "MS: read(%p, %d) = %d\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static int
+memstream_write(void *cookie, const char *buf, int len)
+{
+ struct memstream *ms;
+ int tocopy;
+
+ ms = cookie;
+ memstream_grow(ms, ms->offset + len);
+ tocopy = *ms->lenp - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(*ms->cp + ms->offset, buf, tocopy);
+ ms->offset += tocopy;
+#ifdef DEBUG
+ fprintf(stderr, "MS: write(%p, %d) = %d\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static fpos_t
+memstream_seek(void *cookie, fpos_t pos, int whence)
+{
+ struct memstream *ms;
+#ifdef DEBUG
+ size_t old;
+#endif
+
+ ms = cookie;
+#ifdef DEBUG
+ old = ms->offset;
+#endif
+ switch (whence) {
+ case SEEK_SET:
+ ms->offset = pos;
+ break;
+ case SEEK_CUR:
+ ms->offset += pos;
+ break;
+ case SEEK_END:
+ ms->offset = *ms->lenp + pos;
+ break;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "MS: seek(%p, %zd, %d) %zd -> %zd\n", ms, pos, whence,
+ old, ms->offset);
+#endif
+ return (ms->offset);
+}
+
+static int
+memstream_close(void *cookie)
+{
+
+ free(cookie);
+ return (0);
+}
+
+FILE *
+open_memstream(char **cp, size_t *lenp)
+{
+ struct memstream *ms;
+ int save_errno;
+ FILE *fp;
+
+ *cp = NULL;
+ *lenp = 0;
+ ms = malloc(sizeof(*ms));
+ ms->cp = cp;
+ ms->lenp = lenp;
+ ms->offset = 0;
+ fp = funopen(ms, memstream_read, memstream_write, memstream_seek,
+ memstream_close);
+ if (fp == NULL) {
+ save_errno = errno;
+ free(ms);
+ errno = save_errno;
+ }
+ return (fp);
+}
Property changes on: trunk/sysutils/mcelog/files/memstream.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-Makefile
===================================================================
--- trunk/sysutils/mcelog/files/patch-Makefile (rev 0)
+++ trunk/sysutils/mcelog/files/patch-Makefile 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,45 @@
+--- Makefile.orig 2017-05-22 16:38:47 UTC
++++ Makefile
+@@ -27,14 +27,21 @@ all: mcelog
+
+ .PHONY: install clean depend FORCE
+
++LIBS :=
+ OBJ := p4.o k8.o mcelog.o dmi.o tsc.o core2.o bitfield.o intel.o \
+ nehalem.o dunnington.o tulsa.o config.o memutil.o msg.o \
+- eventloop.o leaky-bucket.o memdb.o server.o trigger.o \
+- client.o cache.o sysfs.o yellow.o page.o rbtree.o \
++ eventloop.o leaky-bucket.o memdb.o server.o \
++ client.o cache.o rbtree.o \
+ sandy-bridge.o ivy-bridge.o haswell.o \
+ broadwell_de.o broadwell_epex.o skylake_xeon.o \
+ denverton.o \
+- msr.o bus.o unknown.o
++ msr.o
++ifndef FREEBSD
++OBJ += page.o trigger.o sysfs.o yellow.o bus.o unknown.o
++endif
++ifdef FREEBSD
++OBJ += memstream.o
++endif
+ CLEAN := mcelog dmi tsc dbquery .depend .depend.X dbquery.o \
+ version.o version.c version.tmp
+ DOC := mce.pdf
+@@ -43,7 +50,7 @@ ADD_DEFINES :=
+
+ SRC := $(OBJ:.o=.c)
+
+-mcelog: ${OBJ} version.o
++mcelog: ${OBJ} ${LIBS} version.o
+
+ # dbquery intentionally not installed by default
+ install: mcelog mcelog.conf mcelog.conf.5 mcelog.triggers.5
+@@ -101,8 +108,6 @@ version.c: version.tmp
+
+ .depend: ${SRC}
+ ${CC} -MM -I. ${SRC} > .depend.X && mv .depend.X .depend
+-
+-include .depend
+
+ Makefile: .depend
+
Property changes on: trunk/sysutils/mcelog/files/patch-Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-cache.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-cache.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-cache.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,26 @@
+--- cache.c.orig 2016-02-10 18:38:43 UTC
++++ cache.c
+@@ -27,6 +27,7 @@
+ #include "sysfs.h"
+ #include "cache.h"
+
++#ifdef __Linux__
+ struct cache {
+ unsigned level;
+ /* Numerical values must match MCACOD */
+@@ -173,6 +174,15 @@ int cache_to_cpus(int cpu, unsigned leve
+ Wprintf("Cannot find sysfs cache for CPU %d", cpu);
+ return -1;
+ }
++#endif
++
++#ifdef __FreeBSD__
++int cache_to_cpus(int cpu, unsigned level, unsigned type,
++ int *cpulen, unsigned **cpumap)
++{
++ return -1;
++}
++#endif
+
+ #ifdef TEST
+ main()
Property changes on: trunk/sysutils/mcelog/files/patch-cache.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-client.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-client.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-client.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,20 @@
+--- client.c.orig 2016-02-10 18:38:43 UTC
++++ client.c
+@@ -18,6 +18,7 @@
+ #include <stdio.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
++#include <string.h>
+ #include <unistd.h>
+ #include "mcelog.h"
+ #include "client.h"
+@@ -48,6 +49,9 @@ void ask_server(char *command)
+ sizeof(struct sockaddr_un)) < 0)
+ SYSERRprintf("client connect");
+
++#ifdef __FreeBSD__
++ /* XXX: Need to use sendmsg() to send a SCM_CREDS control message. */
++#endif
+ n = strlen(command);
+ if (write(fd, command, n) != n)
+ SYSERRprintf("client command write");
Property changes on: trunk/sysutils/mcelog/files/patch-client.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-config.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-config.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-config.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,25 @@
+--- config.c.orig 2010-01-21 02:36:52 UTC
++++ config.c
+@@ -18,6 +18,9 @@
+ Author: Andi Kleen
+ */
+ #define _GNU_SOURCE 1
++#ifdef __FreeBSD__
++#include <sys/param.h>
++#endif
+ #include <stdio.h>
+ #include <string.h>
+ #include <ctype.h>
+@@ -304,7 +307,12 @@ int config_trigger(const char *header, c
+ s = config_string(header, name);
+ if (s) {
+ /* no $PATH */
++#ifdef __Linux_
+ if (trigger_check(s) != 0) {
++#endif
++#ifdef __FreeBSD__
++ if (access(s, R_OK|X_OK) != 0) {
++#endif
+ SYSERRprintf("Trigger `%s' not executable\n", s);
+ exit(1);
+ }
Property changes on: trunk/sysutils/mcelog/files/patch-config.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-eventloop.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-eventloop.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-eventloop.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,46 @@
+--- eventloop.c.orig 2016-02-10 18:38:43 UTC
++++ eventloop.c
+@@ -38,7 +38,9 @@ struct pollcb {
+ static struct pollfd pollfds[MAX_POLLFD];
+ static struct pollcb pollcbs[MAX_POLLFD];
+
++#ifdef __Linux__
+ static sigset_t event_sigs;
++#endif
+
+ static int closeonexec(int fd)
+ {
+@@ -97,6 +99,7 @@ static void poll_callbacks(int n)
+ }
+
+ /* Run signal handler only directly after event loop */
++#ifdef __Linux__
+ int event_signal(int sig)
+ {
+ static int first = 1;
+@@ -126,17 +129,25 @@ static int ppoll_fallback(struct pollfd
+
+ static int (*ppoll_vec)(struct pollfd *, nfds_t, const struct timespec
+ *, const sigset_t *);
++#endif
+
+ void eventloop(void)
+ {
++#ifdef __Linux__
+ #if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 5 || __GLIBC__ > 2
+ ppoll_vec = ppoll;
+ #endif
+ if (!ppoll_vec)
+ ppoll_vec = ppoll_fallback;
++#endif
+
+ for (;;) {
++#ifdef __Linux__
+ int n = ppoll_vec(pollfds, max_pollfd, NULL, &event_sigs);
++#endif
++#ifdef __FreeBSD__
++ int n = poll(pollfds, max_pollfd, -1);
++#endif
+ if (n <= 0) {
+ if (n < 0 && errno != EINTR)
+ SYSERRprintf("poll error");
Property changes on: trunk/sysutils/mcelog/files/patch-eventloop.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-intel.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-intel.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-intel.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,21 @@
+--- intel.c.orig 2016-02-10 18:38:43 UTC
++++ intel.c
+@@ -141,14 +141,18 @@ static int intel_memory_error(struct mce
+ if (recordlen > offsetof(struct mce, mcgcap) && m->mcgcap & MCG_CMCI_P)
+ corr_err_cnt = EXTRACT(m->status, 38, 52);
+ memory_error(m, channel[0], dimm[0], corr_err_cnt, recordlen);
++#ifdef __Linux__
+ account_page_error(m, channel[0], dimm[0]);
++#endif
+
+ /*
+ * When both DIMMs have a error account the error twice to the page.
+ */
+ if (channel[1] != -1) {
+ memory_error(m, channel[1], dimm[1], corr_err_cnt, recordlen);
++#ifdef __Linux__
+ account_page_error(m, channel[1], dimm[1]);
++#endif
+ }
+
+ return 1;
Property changes on: trunk/sysutils/mcelog/files/patch-intel.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-mcelog.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-mcelog.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-mcelog.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,818 @@
+--- mcelog.c.orig 2016-10-10 22:08:11 UTC
++++ mcelog.c
+@@ -20,9 +20,22 @@
+ #define _GNU_SOURCE 1
+ #include <sys/fcntl.h>
+ #include <sys/ioctl.h>
++#ifdef __Linux__
+ #include <asm/types.h>
+ #include <asm/ioctls.h>
+ #include <linux/limits.h>
++#endif
++#ifdef __FreeBSD__
++#include <sys/types.h>
++#include <sys/sysctl.h>
++#include <machine/cpufunc.h>
++#include <machine/cputypes.h>
++#include <machine/specialreg.h>
++#include <err.h>
++#include <kvm.h>
++#include <limits.h>
++#endif
++#undef CPU_P4
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -60,9 +73,25 @@
+ #include "bus.h"
+ #include "unknown.h"
+
++struct mca_record {
++ uint64_t mr_status;
++ uint64_t mr_addr;
++ uint64_t mr_misc;
++ uint64_t mr_tsc;
++ int mr_apic_id;
++ int mr_bank;
++ uint64_t mr_mcg_cap;
++ uint64_t mr_mcg_status;
++ int mr_cpu_id;
++ int mr_cpu_vendor_id;
++ int mr_cpu;
++};
++
+ enum cputype cputype = CPU_GENERIC;
+
++#ifdef __Linux__
+ char *logfn = LOG_DEV_FILENAME;
++#endif
+
+ int ignore_nodev;
+ int filter_bogus = 1;
+@@ -73,7 +102,9 @@ int ascii_mode;
+ int dump_raw_ascii;
+ int daemon_mode;
+ static char *inputfile;
++#ifdef __Linux__
+ char *processor_flags;
++#endif
+ static int foreground;
+ int filter_memory_errors;
+ static struct config_cred runcred = { .uid = -1U, .gid = -1U };
+@@ -82,6 +113,10 @@ static char pidfile_default[] = PID_FILE
+ static char logfile_default[] = LOG_FILE;
+ static char *pidfile = pidfile_default;
+ static char *logfile;
++#ifdef __FreeBSD__
++static char *execfile;
++static char *corefile;
++#endif
+ static int debug_numerrors;
+ int imc_log = -1;
+ static int check_only = 0;
+@@ -196,6 +231,7 @@ static void parse_cpuid(u32 cpuid, u32 *
+ *model += c.c.ext_model << 4;
+ }
+
++#ifdef __Linux__
+ static u32 unparse_cpuid(unsigned family, unsigned model)
+ {
+ union {
+@@ -213,6 +249,7 @@ static u32 unparse_cpuid(unsigned family
+ c.c.ext_model = model >> 4;
+ return c.v;
+ }
++#endif
+
+ static char *cputype_name[] = {
+ [CPU_GENERIC] = "generic CPU",
+@@ -325,6 +362,7 @@ static char *vendor[] = {
+ [8] = "NSC"
+ };
+
++#ifdef __Linux__
+ static unsigned cpuvendor_to_num(char *name)
+ {
+ unsigned i;
+@@ -339,6 +377,7 @@ static unsigned cpuvendor_to_num(char *n
+ return i;
+ return 0;
+ }
++#endif
+
+ static char *cpuvendor_name(u32 cpuvendor)
+ {
+@@ -483,6 +522,7 @@ static void dump_mce_raw_ascii(struct mc
+ Wprintf("\n");
+ }
+
++#ifdef __Linux__
+ int is_cpu_supported(void)
+ {
+ enum {
+@@ -553,14 +593,61 @@ int is_cpu_supported(void)
+
+ return 1;
+ }
++#endif
++
++#ifdef __FreeBSD__
++int is_cpu_supported(void)
++{
++ char vendor[20];
++ u_int regs[4];
++ u_int cpu_id;
++ int family, model;
++ static int checked;
++
++ if (checked)
++ return 1;
++
++ checked = 1;
++
++ do_cpuid(0, regs);
++ ((u_int *)vendor)[0] = regs[1];
++ ((u_int *)vendor)[1] = regs[3];
++ ((u_int *)vendor)[2] = regs[2];
++ vendor[12] = 0;
++
++ do_cpuid(1, regs);
++ cpu_id = regs[0];
++ family = CPUID_TO_FAMILY(cpu_id);
++ model = CPUID_TO_MODEL(cpu_id);
++
++ if (cpu_forced)
++ ;
++ else if (!strcmp(vendor,"AuthenticAMD")) {
++ if (family == 15) {
++ cputype = CPU_K8;
++ } else if (family >= 16) {
++ SYSERRprintf("ERROR: AMD Processor family %d: mcelog does not support this processor. Please use the edac_mce_amd module instead.\n", family);
++ return 0;
++ }
++ } else if (!strcmp(vendor,"GenuineIntel"))
++ cputype = select_intel_cputype(family, model);
++ /* Add checks for other CPUs here */
++ else
++ return 1;
++ return 0;
++}
++#endif
+
++#ifdef __Linux__
+ static char *skipspace(char *s)
+ {
+ while (isspace(*s))
+ ++s;
+ return s;
+ }
++#endif
+
++#ifdef __Linux__
+ static char *skip_syslog(char *s)
+ {
+ char *p;
+@@ -571,7 +658,9 @@ static char *skip_syslog(char *s)
+ return p + sizeof("mcelog: ") - 1;
+ return s;
+ }
++#endif
+
++#ifdef __Linux__
+ static char *skipgunk(char *s)
+ {
+ s = skip_syslog(s);
+@@ -596,12 +685,16 @@ static char *skipgunk(char *s)
+
+ return skipspace(s);
+ }
++#endif
+
++#ifdef __Linux__
+ static inline int urange(unsigned val, unsigned lo, unsigned hi)
+ {
+ return val >= lo && val <= hi;
+ }
++#endif
+
++#ifdef __Linux__
+ static int is_short(char *name)
+ {
+ return strlen(name) == 3 &&
+@@ -609,7 +702,9 @@ static int is_short(char *name)
+ islower(name[1]) &&
+ islower(name[2]);
+ }
++#endif
+
++#ifdef __Linux__
+ static unsigned skip_date(char *s)
+ {
+ unsigned day, hour, min, year, sec;
+@@ -626,6 +721,7 @@ static unsigned skip_date(char *s)
+ return 0;
+ return next;
+ }
++#endif
+
+ static void dump_mce_final(struct mce *m, char *symbol, int missing, int recordlen,
+ int dseen)
+@@ -646,6 +742,7 @@ static void dump_mce_final(struct mce *m
+ flushlog();
+ }
+
++#ifdef __Linux__
+ static char *skip_patterns[] = {
+ "MCA:*",
+ "MCi_MISC register valid*",
+@@ -654,7 +751,9 @@ static char *skip_patterns[] = {
+ "Kernel does not support page offline interface",
+ NULL
+ };
++#endif
+
++#ifdef __Linux__
+ static int match_patterns(char *s, char **pat)
+ {
+ for (; *pat; pat++)
+@@ -662,12 +761,14 @@ static int match_patterns(char *s, char
+ return 0;
+ return 1;
+ }
++#endif
+
+ #define FIELD(f) \
+ if (recordlen < endof_field(struct mce, f)) \
+ recordlen = endof_field(struct mce, f)
+
+ /* Decode ASCII input for fatal messages */
++#ifdef __Linux__
+ static void decodefatal(FILE *inf)
+ {
+ struct mce m;
+@@ -878,6 +979,227 @@ restart:
+ if (data)
+ dump_mce_final(&m, symbol, missing, recordlen, disclaimer_seen);
+ }
++#endif
++
++#ifdef __FreeBSD__
++/*
++ * Table used to map cpuid vendor strings and FreeBSD CPU vendor IDs
++ * to Linux cpuvendor values.
++ */
++static struct {
++ char *name;
++ int vendor_id;
++ u_char cpuvendor;
++} vendor_ids[] = {
++ { "GenuineIntel", CPU_VENDOR_INTEL, 0 },
++ { "AuthenticAMD", CPU_VENDOR_AMD, 2 },
++ { "CentaurHauls", CPU_VENDOR_CENTAUR, 5 },
++#ifdef __i386__
++ { "CyrixInstead", CPU_VENDOR_CYRIX, 1 },
++ { "UMC UMC UMC ", CPU_VENDOR_UMC, 3 },
++ { "GenuineTMx86", CPU_VENDOR_TRANSMETA, 7 },
++ { "Geode by NSC", CPU_VENDOR_NSC, 8 },
++#endif
++};
++
++static int find_cpu_vendor(const char *vendor)
++{
++ u_int i;
++
++ for (i = 0; i < sizeof(vendor_ids) / sizeof(vendor_ids[0]); i++)
++ if (strcmp(vendor, vendor_ids[i].name) == 0)
++ return (vendor_ids[i].cpuvendor);
++ return (0xff);
++}
++
++static int find_cpu_vendor_id(const char *vendor)
++{
++ u_int i;
++
++ for (i = 0; i < sizeof(vendor_ids) / sizeof(vendor_ids[0]); i++)
++ if (strcmp(vendor, vendor_ids[i].name) == 0)
++ return (vendor_ids[i].vendor_id);
++ return (0);
++}
++
++static int map_cpu_vendor(int vendor_id)
++{
++ u_int i;
++
++ for (i = 0; i < sizeof(vendor_ids) / sizeof(vendor_ids[0]); i++)
++ if (vendor_ids[i].vendor_id == vendor_id)
++ return (vendor_ids[i].cpuvendor);
++ return (0xff);
++}
++
++/* Convert FreeBSD's struct mca_record into a struct mce. */
++static void convert_mca(struct mca_record *mr, struct mce *mce, int live,
++ size_t len)
++{
++ memset(mce, 0, sizeof(*mce));
++ mce->status = mr->mr_status;
++ mce->misc = mr->mr_misc;
++ mce->addr = mr->mr_addr;
++ mce->mcgstatus = mr->mr_mcg_status;
++ mce->tsc = mr->mr_tsc;
++ mce->cpuvendor = map_cpu_vendor(mr->mr_cpu_vendor_id);
++ mce->cpuid = mr->mr_cpu_id;
++ mce->bank = mr->mr_bank;
++ mce->finished = 1;
++ mce->extcpu = mr->mr_cpu;
++ mce->apicid = mr->mr_apic_id;
++ mce->mcgcap = mr->mr_mcg_cap;
++
++ /*
++ * For older live records (from sysctl), fill in some fields
++ * using registers from the current CPU.
++ */
++ if (len < offsetof(struct mca_record, mr_cpu_id) && live) {
++ char vendor[20];
++ u_int regs[4];
++
++ do_cpuid(0, regs);
++ ((u_int *)vendor)[0] = regs[1];
++ ((u_int *)vendor)[1] = regs[3];
++ ((u_int *)vendor)[2] = regs[2];
++ vendor[12] = 0;
++ mce->cpuvendor = find_cpu_vendor(vendor);
++
++ do_cpuid(1, regs);
++ mce->cpuid = regs[0];
++ }
++}
++
++/* Decode ASCII input for fatal messages */
++static void decodefatal(FILE *inf)
++{
++ struct mca_record mr;
++ struct mce m;
++ long long val, val2;
++ char *cp, line[100], *s, symbol[1];
++ const char *fmt;
++ int cpu, data, old, missing;
++ enum rows {
++ BANK = 0x1,
++ MCG = 0x2,
++ VENDOR = 0x4,
++ CPU = 0x8,
++ ADDR = 0x10,
++ MISC = 0x20,
++ };
++
++ symbol[0] = '\0';
++ data = 0;
++ missing = 0;
++ old = 0;
++ memset(&mr, 0, sizeof(mr));
++ while ((s = fgets(line, sizeof(line), inf)) != NULL) {
++ s = strstr(s, "MCA: ");
++ if (s == NULL)
++ continue;
++ s += strlen("MCA: ");
++
++ if (strncmp(s, "bank", 4) == 0 || strncmp(s, "Bank", 4) == 0) {
++ /* Start of a new record, dump the previous one. */
++ if (data != 0) {
++ /* Require some minimum data. */
++ if (data & BANK) {
++ if (mr.mr_status & MC_STATUS_ADDRV &&
++ !(data & ADDR))
++ missing = 1;
++ if (mr.mr_status & MC_STATUS_MISCV &&
++ !(data & MISC))
++ missing = 1;
++ convert_mca(&mr, &m, 0, sizeof(mr));
++ mce_cpuid(&m);
++ dump_mce_final(&m, symbol, missing,
++ sizeof(struct mce), 0);
++ }
++ data = 0;
++ missing = 0;
++ memset(&mr, 0, sizeof(mr));
++ }
++
++ if (s[0] == 'b') {
++ old = 1;
++ fmt = "bank %d, status 0x%llx";
++ } else {
++ old = 0;
++ fmt = "Bank %d, Status 0x%llx";
++ }
++ if (sscanf(s, fmt, &mr.mr_bank, &val) != 2)
++ missing = 1;
++ else {
++ data |= BANK;
++ mr.mr_status = val;
++ }
++ }
++ if (strncmp(s, "Global", 6) == 0) {
++ if (sscanf(s, "Global Cap 0x%llx, Status 0x%llx", &val,
++ &val2) != 2)
++ missing = 1;
++ else {
++ data |= MCG;
++ mr.mr_mcg_cap = val;
++ mr.mr_mcg_status = val2;
++ }
++ }
++ if (strncmp(s, "Vendor \"", 8) == 0) {
++ s += 8;
++ cp = index(s, '"');
++ if (cp != NULL) {
++ *cp = '\0';
++ mr.mr_cpu_vendor_id = find_cpu_vendor_id(s);
++ s = cp + 1;
++ if (sscanf(s, ", ID 0x%x, APIC ID %d",
++ &mr.mr_cpu_id, &mr.mr_apic_id) != 2)
++ missing = 1;
++ else
++ data |= VENDOR;
++ } else
++ missing = 1;
++ }
++ if (strncmp(s, "CPU", 3) == 0) {
++ if (sscanf(s, "CPU %d ", &cpu) != 1)
++ missing = 1;
++ else {
++ data |= CPU;
++ if (old)
++ mr.mr_apic_id = cpu;
++ else
++ mr.mr_cpu = cpu;
++ }
++ }
++ if (strncmp(s, "Address", 7) == 0) {
++ if (sscanf(s, "Address 0x%llx", &val) != 1)
++ missing = 1;
++ else {
++ data |= ADDR;
++ mr.mr_addr = val;
++ }
++ }
++ if (strncmp(s, "Misc", 4) == 0) {
++ if (sscanf(s, "Misc 0x%llx", &val) != 1)
++ missing = 1;
++ else {
++ data |= MISC;
++ mr.mr_misc = val;
++ }
++ }
++ }
++
++ /* Dump the last record. */
++ if (data & BANK) {
++ if (mr.mr_status & MC_STATUS_ADDRV && !(data & ADDR))
++ missing = 1;
++ if (mr.mr_status & MC_STATUS_MISCV && !(data & MISC))
++ missing = 1;
++ convert_mca(&mr, &m, 0, sizeof(mr));
++ mce_cpuid(&m);
++ dump_mce_final(&m, symbol, missing, sizeof(struct mce), 0);
++ }
++}
++#endif
+
+ static void remove_pidfile(void)
+ {
+@@ -943,6 +1265,10 @@ void usage(void)
+ " mcelog [options] --ascii < log\n"
+ " mcelog [options] --ascii --file log\n"
+ "Decode machine check ASCII output from kernel logs\n"
++#ifdef __FreeBSD_
++" mcelog [options] -M vmcore -N kernel\n"
++"Decode machine check error records from kernel crashdump.\n"
++#endif
+ "\n"
+ "Options:\n"
+ "--version Show the version of mcelog and exit\n"
+@@ -1147,6 +1473,14 @@ static int modifier(int opt)
+ case O_IS_CPU_SUPPORTED:
+ check_only = 1;
+ break;
++#ifdef __FreeBSD__
++ case 'M':
++ corefile = strdup(optarg);
++ break;
++ case 'N':
++ execfile = strdup(optarg);
++ break;
++#endif
+ case 0:
+ break;
+ default:
+@@ -1195,10 +1529,12 @@ static int combined_modifier(int opt)
+
+ static void general_setup(void)
+ {
++#ifdef __Linux__
+ trigger_setup();
+ yellow_setup();
+ bus_setup();
+ unknown_setup();
++#endif
+ config_cred("global", "run-credentials", &runcred);
+ if (config_bool("global", "filter-memory-errors") == 1)
+ filter_memory_errors = 1;
+@@ -1221,6 +1557,7 @@ static void drop_cred(void)
+ }
+ }
+
++#ifdef __Linux__
+ static void process(int fd, unsigned recordlen, unsigned loglen, char *buf)
+ {
+ int i;
+@@ -1273,6 +1610,173 @@ static void process(int fd, unsigned rec
+ if (finish)
+ exit(0);
+ }
++#endif
++
++#ifdef __FreeBSD__
++#ifdef LOCAL_HACK
++struct mca_record_old {
++ uint64_t mr_status;
++ uint64_t mr_addr;
++ uint64_t mr_misc;
++ uint64_t mr_tsc;
++ int mr_apic_id;
++ int mr_bank;
++};
++#endif
++
++struct mca_record_internal {
++ struct mca_record rec;
++ int logged;
++ STAILQ_ENTRY(mca_internal) link;
++};
++
++#ifdef LOCAL_HACK
++struct mca_record_internal_old {
++ struct mca_record_old rec;
++ int logged;
++ STAILQ_ENTRY(mca_internal) link;
++};
++#endif
++
++static struct nlist nl[] = {
++#define X_MCA_RECORDS 0
++ { .n_name = "_mca_records" },
++#ifdef LOCAL_HACK
++#define X_SNAPDATE 1
++ { .n_name = "_snapdate" },
++#endif
++ { .n_name = NULL },
++};
++
++static int
++kread(kvm_t *kvm, void *kvm_pointer, void *buf, size_t size, size_t offset)
++{
++ ssize_t ret;
++
++ ret = kvm_read(kvm, (unsigned long)kvm_pointer + offset, buf, size);
++ if (ret < 0 || (size_t)ret != size)
++ return (-1);
++ return (0);
++}
++
++static int
++kread_symbol(kvm_t *kvm, int index, void *buf, size_t size)
++{
++ ssize_t ret;
++
++ ret = kvm_read(kvm, nl[index].n_value, buf, size);
++ if (ret < 0 || (size_t)ret != size)
++ return (-1);
++ return (0);
++}
++
++static void process_kvm(const char *execfile, const char *corefile)
++{
++ struct mca_record mr, *mrp;
++ struct mce mce;
++ char errbuf[_POSIX2_LINE_MAX];
++ kvm_t *kvm;
++ size_t record_size, link_offset;
++ int i;
++#ifdef LOCAL_HACK
++ int snapdate;
++#endif
++
++ kvm = kvm_openfiles(execfile, corefile, NULL, O_RDONLY, errbuf);
++ if (kvm == NULL)
++ errx(1, "kvm_openfiles: %s", errbuf);
++ if (kvm_nlist(kvm, nl) != 0)
++ errx(1, "kvm_nlist: %s", kvm_geterr(kvm));
++
++#ifdef LOCAL_HACK
++ if (kread_symbol(kvm, X_SNAPDATE, &snapdate, sizeof(snapdate)) < 0)
++ errx(1, "kvm_read(snapdate) failed");
++#endif
++ /* stqh_first is the first pointer at this address. */
++ if (kread_symbol(kvm, X_MCA_RECORDS, &mrp, sizeof(mrp)) < 0)
++ errx(1, "kvm_read(mca_records) failed");
++#ifdef LOCAL_HACK
++ if (snapdate >= 20100329) {
++#endif
++ record_size = sizeof(struct mca_record);
++ link_offset = __offsetof(struct mca_record_internal,
++ link.stqe_next);
++#ifdef LOCAL_HACK
++ } else {
++ record_size = sizeof(struct mca_record_old);
++ link_offset = __offsetof(struct mca_record_internal_old,
++ link.stqe_next);
++ }
++#endif
++
++ for (i = 0; mrp != NULL; i++) {
++ memset(&mr, 0, sizeof(mr));
++ if (kread(kvm, mrp, &mr, record_size, 0) < 0)
++ break;
++ if (kread(kvm, mrp, &mrp, sizeof(mrp), link_offset) < 0)
++ mrp = NULL;
++
++ convert_mca(&mr, &mce, 1, record_size);
++ mce_prepare(&mce);
++ if (!mce_filter(&mce, sizeof(struct mce)))
++ continue;
++ if (!dump_raw_ascii) {
++ disclaimer();
++ Wprintf("MCE %d\n", i);
++ dump_mce(&mce, sizeof(struct mce));
++ } else
++ dump_mce_raw_ascii(&mce, sizeof(struct mce));
++ flushlog();
++ }
++
++ exit(0);
++}
++
++static void process_live(void)
++{
++ struct mca_record mr;
++ struct mce mce;
++ int mib[4];
++ size_t len;
++ int count, finish, i;
++
++ len = sizeof(count);
++ if (sysctlbyname("hw.mca.count", &count, &len, NULL, 0) < 0)
++ return;
++
++ len = 4;
++ if (sysctlnametomib("hw.mca.records", mib, &len) < 0)
++ return;
++
++ finish = 0;
++ for (i = 0; i < count; i++) {
++ mib[3] = i;
++ len = sizeof(mr);
++ memset(&mr, 0, sizeof(mr));
++ if (sysctl(mib, 4, &mr, &len, NULL, 0) < 0) {
++ warn("sysctl(hw.mca.records.%d)", i);
++ continue;
++ }
++
++ convert_mca(&mr, &mce, 1, len);
++ mce_prepare(&mce);
++ if (numerrors > 0 && --numerrors == 0)
++ finish = 1;
++ if (!mce_filter(&mce, sizeof(struct mce)))
++ continue;
++ if (!dump_raw_ascii) {
++ disclaimer();
++ Wprintf("MCE %d\n", i);
++ dump_mce(&mce, sizeof(struct mce));
++ } else
++ dump_mce_raw_ascii(&mce, sizeof(struct mce));
++ flushlog();
++ }
++
++ if (finish)
++ exit(0);
++}
++#endif
+
+ static void noargs(int ac, char **av)
+ {
+@@ -1331,12 +1835,14 @@ struct mcefd_data {
+ char *buf;
+ };
+
++#ifdef __Linux__
+ static void process_mcefd(struct pollfd *pfd, void *data)
+ {
+ struct mcefd_data *d = (struct mcefd_data *)data;
+ assert((pfd->revents & POLLIN) != 0);
+ process(pfd->fd, d->recordlen, d->loglen, d->buf);
+ }
++#endif
+
+ static void handle_sigusr1(int sig)
+ {
+@@ -1345,13 +1851,18 @@ static void handle_sigusr1(int sig)
+
+ int main(int ac, char **av)
+ {
++#ifdef __Linux__
+ struct mcefd_data d = {};
+- int opt;
+ int fd;
+-
++#endif
++ int opt;
+ parse_config(av);
+
++#ifdef __FreeBSD
++ while ((opt = getopt_long(ac, av, "M:N:", options, NULL)) != -1) {
++#else
+ while ((opt = getopt_long(ac, av, "", options, NULL)) != -1) {
++#endif
+ if (opt == '?') {
+ usage();
+ } else if (combined_modifier(opt) > 0) {
+@@ -1371,11 +1882,13 @@ int main(int ac, char **av)
+ }
+
+ /* before doing anything else let's see if the CPUs are supported */
++#ifdef __Linux__
+ if (!cpu_forced && !is_cpu_supported()) {
+ if (!check_only)
+ fprintf(stderr, "CPU is unsupported\n");
+ exit(1);
+ }
++#endif
+ if (check_only)
+ exit(0);
+
+@@ -1394,13 +1907,21 @@ int main(int ac, char **av)
+ }
+
+ modifier_finish();
++#ifdef __Linux__
+ if (av[optind])
+ logfn = av[optind++];
++#endif
+ if (av[optind])
+ usage();
++#ifdef __FreeBSD__
++ if ((corefile != NULL) ^ (execfile != NULL) ||
++ (corefile != NULL && daemon_mode))
++ usage();
++#endif
+ checkdmi();
+ general_setup();
+
++#ifdef __Linux__
+ fd = open(logfn, O_RDONLY);
+ if (fd < 0) {
+ if (ignore_nodev)
+@@ -1415,27 +1936,44 @@ int main(int ac, char **av)
+ err("MCE_GET_LOG_LEN");
+
+ d.buf = xalloc(d.recordlen * d.loglen);
++#endif
+ if (daemon_mode) {
+ prefill_memdb(do_dmi);
+ if (!do_dmi)
+ closedmi();
+ server_setup();
++#ifdef __Linux__
+ page_setup();
++#endif
+ if (imc_log)
+ set_imc_log(cputype);
+ drop_cred();
++#ifdef __Linux__
+ register_pollcb(fd, POLLIN, process_mcefd, &d);
++#endif
+ if (!foreground && daemon(0, need_stdout()) < 0)
+ err("daemon");
+ if (pidfile)
+ write_pidfile();
+ signal(SIGUSR1, handle_sigusr1);
++#ifdef __Linux__
+ event_signal(SIGUSR1);
++#endif
+ eventloop();
+ } else {
++#ifdef __Linux__
+ process(fd, d.recordlen, d.loglen, d.buf);
++#endif
++#ifdef __FreeBSD__
++ if (corefile != NULL)
++ process_kvm(execfile, corefile);
++ else
++ process_live();
++#endif
+ }
++#ifdef __Linux__
+ trigger_wait();
++#endif
+
+ exit(0);
+ }
Property changes on: trunk/sysutils/mcelog/files/patch-mcelog.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-mcelog.h
===================================================================
--- trunk/sysutils/mcelog/files/patch-mcelog.h (rev 0)
+++ trunk/sysutils/mcelog/files/patch-mcelog.h 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,26 @@
+--- mcelog.h.orig 2016-02-10 18:38:43 UTC
++++ mcelog.h
+@@ -67,10 +67,12 @@ struct mce {
+ #define MCI_STATUS_AR (1ULL<<55) /* action-required */
+ #define MCI_STATUS_FWST (1ULL<<37) /* Firmware updated status indicator */
+
++#ifndef MCG_STATUS_RIPV
+ #define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */
+ #define MCG_STATUS_EIPV (1ULL<<1) /* eip points to correct instruction */
+ #define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */
+ #define MCG_STATUS_LMCES (1ULL<<3) /* local machine check signaled */
++#endif
+
+ #define MCG_CMCI_P (1ULL<<10) /* CMCI supported */
+ #define MCG_TES_P (1ULL<<11) /* Yellow bit cache threshold supported */
+@@ -97,6 +99,10 @@ struct mce {
+ #define noreturn
+ #endif
+
++#if defined(__FreeBSD__) && defined(_STDIO_H_)
++FILE *open_memstream(char **cp, size_t *lenp);
++#endif
++
+ int Wprintf(char *fmt, ...) PRINTFLIKE;
+ void Eprintf(char *fmt, ...) PRINTFLIKE;
+ void SYSERRprintf(char *fmt, ...) PRINTFLIKE;
Property changes on: trunk/sysutils/mcelog/files/patch-mcelog.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-memdb.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-memdb.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-memdb.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,12 @@
+--- memdb.c.orig 2016-02-10 18:38:43 UTC
++++ memdb.c
+@@ -172,7 +172,9 @@ void memdb_trigger(char *msg, struct mem
+ asprintf(&env[ei++], "THRESHOLD_COUNT=%d", bucket->count);
+ env[ei] = NULL;
+ assert(ei < MAX_ENV);
++#ifdef __Linux__
+ run_trigger(bc->trigger, NULL, env);
++#endif
+ for (i = 0; i < ei; i++)
+ free(env[i]);
+ out:
Property changes on: trunk/sysutils/mcelog/files/patch-memdb.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-p4.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-p4.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-p4.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,81 @@
+--- p4.c.orig 2016-10-10 22:08:11 UTC
++++ p4.c
+@@ -176,8 +176,10 @@ static int decode_mca(u64 status, u64 mi
+ levelnum = mca & 3;
+ level = get_LL_str(levelnum);
+ Wprintf("%s Generic cache hierarchy error\n", level);
++#ifdef __Linux__
+ if (track == 2)
+ run_yellow_trigger(cpu, -1, levelnum, "unknown", level, socket);
++#endif
+ } else if (test_prefix(4, mca)) {
+ unsigned levelnum, typenum;
+ char *level, *type;
+@@ -186,8 +188,10 @@ static int decode_mca(u64 status, u64 mi
+ levelnum = (mca & TLB_LL_MASK) >> TLB_LL_SHIFT;
+ level = get_LL_str(levelnum);
+ Wprintf("%s TLB %s Error\n", type, level);
++#ifdef __Linux__
+ if (track == 2)
+ run_yellow_trigger(cpu, typenum, levelnum, type, level, socket);
++#endif
+ } else if (test_prefix(8, mca)) {
+ unsigned typenum = (mca & CACHE_TT_MASK) >> CACHE_TT_SHIFT;
+ unsigned levelnum = (mca & CACHE_LL_MASK) >> CACHE_LL_SHIFT;
+@@ -196,8 +200,10 @@ static int decode_mca(u64 status, u64 mi
+ Wprintf("%s CACHE %s %s Error\n", type, level,
+ get_RRRR_str((mca & CACHE_RRRR_MASK) >>
+ CACHE_RRRR_SHIFT));
++#ifdef __Linux__
+ if (track == 2)
+ run_yellow_trigger(cpu, typenum, levelnum, type, level,socket);
++#endif
+ } else if (test_prefix(10, mca)) {
+ if (mca == 0x400)
+ Wprintf("Internal Timer error\n");
+@@ -216,7 +222,9 @@ static int decode_mca(u64 status, u64 mi
+
+ Wprintf("BUS error: %d %d %s %s %s %s %s\n", socket, cpu,
+ level, pp, rrrr, ii, timeout);
++#ifdef __Linux__
+ run_bus_trigger(socket, cpu, level, pp, rrrr, ii, timeout);
++#endif
+ /* IO MCA - reported as bus/interconnect with specific PP,T,RRRR,II,LL values
+ * and MISCV set. MISC register points to root port that reported the error
+ * need to cross check with AER logs for more details.
+@@ -232,7 +240,9 @@ static int decode_mca(u64 status, u64 mi
+ fn = EXTRACT(misc, 16, 18);
+ Wprintf("IO MCA reported by root port %x:%02x:%02x.%x\n",
+ seg, bus, dev, fn);
++#ifdef __Linux__
+ run_iomca_trigger(socket, cpu, seg, bus, dev, fn);
++#endif
+ }
+ } else if (test_prefix(7, mca)) {
+ decode_memory_controller(mca, bank);
+@@ -382,19 +392,25 @@ static void decode_thermal(struct mce *l
+
+ void decode_intel_mc(struct mce *log, int cputype, int *ismemerr, unsigned size)
+ {
++#ifdef __Linux__
+ int socket = size > offsetof(struct mce, socketid) ? (int)log->socketid : -1;
++#endif
+ int cpu = log->extcpu ? log->extcpu : log->cpu;
+
+ if (log->bank == MCE_THERMAL_BANK) {
+ decode_thermal(log, cpu);
++#ifdef __Linux__
+ run_unknown_trigger(socket, cpu, log);
++#endif
+ return;
+ }
+
+ decode_mcg(log->mcgstatus);
++#ifdef __Linux__
+ if (decode_mci(log->status, log->misc, cpu, log->mcgcap, ismemerr,
+ socket, log->bank))
+ run_unknown_trigger(socket, cpu, log);
++#endif
+
+ if (test_prefix(11, (log->status & 0xffffL))) {
+ switch (cputype) {
Property changes on: trunk/sysutils/mcelog/files/patch-p4.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-server.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-server.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-server.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,123 @@
+--- server.c.orig 2017-06-11 18:52:26 UTC
++++ server.c
+@@ -101,7 +101,9 @@ static void dispatch_dump(FILE *fh, char *s)
+
+ static void dispatch_pages(FILE *fh)
+ {
++#ifdef __Linux__
+ dump_page_errors(fh);
++#endif
+ fprintf(fh, "done\n");
+ }
+
+@@ -137,6 +139,7 @@ static void process_cmd(struct clientcon *cc)
+ Enomem();
+ }
+
++#ifdef __Linux__
+ /* check if client is allowed to access */
+ static int access_check(int fd, struct msghdr *msg)
+ {
+@@ -162,11 +165,44 @@ static int access_check(int fd, struct msghdr *msg)
+ sendstring(fd, "permission denied\n");
+ return -1;
+ }
++#endif
+
++#ifdef __FreeBSD__
++/* check if client is allowed to access */
++static int access_check(int fd, struct msghdr *msg)
++{
++ struct cmsghdr *cmsg;
++ struct cmsgcred *cr;
++
++ /* check credentials */
++ cmsg = CMSG_FIRSTHDR(msg);
++ if (cmsg == NULL ||
++ cmsg->cmsg_level != SOL_SOCKET ||
++ cmsg->cmsg_type != SCM_CREDS) {
++ Eprintf("Did not receive credentials over client unix socket %p\n",
++ cmsg);
++ return -1;
++ }
++ cr = (struct cmsgcred *)CMSG_DATA(cmsg);
++ if (cr->cmcred_uid == 0 ||
++ (acc.uid != -1U && cr->cmcred_uid == acc.uid) ||
++ (acc.gid != -1U && cr->cmcred_gid == acc.gid))
++ return 0;
++ Eprintf("rejected client access from pid:%u uid:%u gid:%u\n",
++ cr->cmcred_pid, cr->cmcred_uid, cr->cmcred_gid);
++ sendstring(fd, "permission denied\n");
++ return -1;
++}
++#endif
++
+ /* retrieve commands from client */
+ static int client_input(int fd, struct clientcon *cc)
+ {
++#ifdef __Linux__
+ char ctlbuf[CMSG_SPACE(sizeof(struct ucred))];
++#else
++ char ctlbuf[CMSG_SPACE(sizeof(struct cmsgcred))];
++#endif
+ struct iovec miov;
+ struct msghdr msg = {
+ .msg_iov = &miov,
+@@ -242,18 +278,22 @@ static void client_accept(struct pollfd *pfd, void *da
+ {
+ struct clientcon *cc = NULL;
+ int nfd = accept(pfd->fd, NULL, 0);
++#ifdef __Linux__
+ int on;
++#endif
+
+ if (nfd < 0) {
+ SYSERRprintf("accept failed on client socket");
+ return;
+ }
+
++#ifdef __Linux__
+ on = 1;
+ if (setsockopt(nfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
+ SYSERRprintf("Cannot enable credentials passing on client socket");
+ goto cleanup;
+ }
++#endif
+
+ cc = xalloc(sizeof(struct clientcon));
+ if (register_pollcb(nfd, POLLIN, client_event, cc) < 0) {
+@@ -301,7 +341,12 @@ static int server_ping(struct sockaddr_un *un)
+ if (sigsetjmp(ping_timeout_ctx, 1) == 0) {
+ ret = -1;
+ alarm(initial_ping_timeout);
++#ifdef __Linux__
+ if (connect(fd, un, sizeof(struct sockaddr_un)) < 0)
++#endif
++#ifdef __FreeBSD__
++ if (connect(fd, (struct sockaddr *) un, sizeof(struct sockaddr_un)) < 0)
++#endif
+ goto cleanup;
+ if (write(fd, PAIR("ping\n")) < 0)
+ goto cleanup;
+@@ -322,7 +367,9 @@ void server_setup(void)
+ {
+ int fd;
+ struct sockaddr_un adr;
++#ifdef __Linux__
+ int on;
++#endif
+
+ server_config();
+
+@@ -363,9 +410,11 @@ void server_setup(void)
+ listen(fd, 10);
+ /* Set SO_PASSCRED to avoid race with client connecting too fast */
+ /* Ignore error for old kernels */
++#ifdef __Linux__
+ on = 1;
+ setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+
++#endif
+ register_pollcb(fd, POLLIN, client_accept, NULL);
+ return;
+
Property changes on: trunk/sysutils/mcelog/files/patch-server.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/files/patch-tsc.c
===================================================================
--- trunk/sysutils/mcelog/files/patch-tsc.c (rev 0)
+++ trunk/sysutils/mcelog/files/patch-tsc.c 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,95 @@
+--- tsc.c.orig 2016-02-10 18:38:43 UTC
++++ tsc.c
+@@ -15,6 +15,12 @@
+ on your Linux system; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ #define _GNU_SOURCE 1
++#ifdef __FreeBSD__
++#include <sys/types.h>
++#include <sys/sysctl.h>
++#include <machine/cpufunc.h>
++#include <machine/specialreg.h>
++#endif
+ #include <string.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -46,6 +52,7 @@ static int fmt_tsc(char **buf, u64 tsc,
+ return 0;
+ }
+
++#ifdef __Linux__
+ static double cpufreq_mhz(int cpu, double infomhz)
+ {
+ double mhz;
+@@ -68,12 +75,29 @@ static double cpufreq_mhz(int cpu, doubl
+ fclose(f);
+ return mhz;
+ }
++#endif
++
++#ifdef __FreeBSD__
++static double cpufreq_mhz(int cpu, double infomhz)
++{
++ double mhz;
++ uint64_t freq;
++ size_t len;
++
++ len = sizeof(freq);
++ if (sysctlbyname("machdep.tsc_freq", &freq, &len, NULL, 0) < 0)
++ return infomhz;
++ mhz = freq / 1000000.0;
++ return mhz;
++}
++#endif
+
+ int decode_tsc_forced(char **buf, double mhz, u64 tsc)
+ {
+ return fmt_tsc(buf, tsc, mhz);
+ }
+
++#ifdef __Linux__
+ static int deep_sleep_states(int cpu)
+ {
+ int ret;
+@@ -132,6 +156,41 @@ static int tsc_reliable(int cputype, int
+ return 0;
+ return 1;
+ }
++#endif
++
++#ifdef __FreeBSD__
++/* Try to figure out if this CPU has a somewhat reliable TSC clock */
++static int tsc_reliable(int cputype, int cpunum)
++{
++ u_int regs[4];
++ u_int cpu_id, amd_pminfo;
++
++ if (cputype != CPU_K8 && !is_intel_cpu(cputype))
++ return 0;
++
++ do_cpuid(0, regs);
++ cpu_id = regs[1];
++ do_cpuid(0x80000000, regs);
++ if (regs[0] >= 0x80000007) {
++ do_cpuid(0x80000007, regs);
++ amd_pminfo = regs[3];
++ } else
++ amd_pminfo = 0;
++
++ if (amd_pminfo & AMDPM_TSC_INVARIANT)
++ return 1;
++ if (is_intel_cpu(cputype)) {
++ if (CPUID_TO_FAMILY(cpu_id) >= 0x10 ||
++ cpu_id == 0x60fb2)
++ return 1;
++ } else if ((CPUID_TO_FAMILY(cpu_id) == 0x6 &&
++ CPUID_TO_MODEL(cpu_id) >= 0xe) ||
++ (CPUID_TO_FAMILY(cpu_id) == 0xf && CPUID_TO_MODEL(cpu_id) >= 0x3))
++ return 1;
++
++ return 0;
++}
++#endif
+
+ int decode_tsc_current(char **buf, int cpunum, enum cputype cputype, double mhz,
+ unsigned long long tsc)
Property changes on: trunk/sysutils/mcelog/files/patch-tsc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/pkg-descr
===================================================================
--- trunk/sysutils/mcelog/pkg-descr (rev 0)
+++ trunk/sysutils/mcelog/pkg-descr 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,18 @@
+mcelog processes machine checks (in particular memory and CPU
+hardware errors) on modern x86-based Unix systems and
+produces human-readable output.
+
+This software is heavily patched to work on FreeBSD systems,
+and thus provides an extremely limited subset of features as
+of this writing (for example, daemon mode is not currently
+supported).
+
+The primary purpose is to provide a way to decode MCE output
+from the FreeBSD kernel into something more human-readable
+using the command 'mcelog --no-dmi --ascii'.
+
+FreeBSD conversion patches were originally written by John
+Baldwin <jhb at freebsd.org> and later incorporated into this
+port.
+
+WWW: http://mcelog.org/
Property changes on: trunk/sysutils/mcelog/pkg-descr
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sysutils/mcelog/pkg-message
===================================================================
--- trunk/sysutils/mcelog/pkg-message (rev 0)
+++ trunk/sysutils/mcelog/pkg-message 2017-11-25 15:55:35 UTC (rev 22975)
@@ -0,0 +1,12 @@
+======================================================
+You can decode MCE output from the FreeBSD kernel by
+using the following command:
+
+ mcelog --no-dmi --ascii --file /path/to/log
+
+Or if you wish to paste the MCE via stdin:
+
+ mcelog --no-dmi --ascii
+ {...paste MCE and send EOF/press Ctrl-D...}
+
+======================================================
Property changes on: trunk/sysutils/mcelog/pkg-message
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
More information about the Midnightbsd-cvs
mailing list