From: Borislav Petkov <bp@amd64.org>
To: Tony Luck <tony.luck@intel.com>, Ingo Molnar <mingo@elte.hu>
Cc: EDAC devel <linux-edac@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
Borislav Petkov <borislav.petkov@amd.com>
Subject: [PATCH 2/3] x86, RAS: Add a decoded msg buffer
Date: Tue, 28 Feb 2012 17:11:26 +0100 [thread overview]
Message-ID: <1330445487-15020-3-git-send-email-bp@amd64.org> (raw)
In-Reply-To: <1330445487-15020-1-git-send-email-bp@amd64.org>
From: Borislav Petkov <borislav.petkov@amd.com>
Echoing 1 into /sys/devices/system/ras/agent causes the ras_printk()
function to buffer a string describing a hardware error. This is meant
for userspace daemons which are running on the system and are going to
consume decoded information through the MCE tracepoint.
Also, upon first use, the buffer enlarges itself from its initial size
so that it can accomodate longer messages.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
arch/x86/Kconfig | 9 +++
arch/x86/Makefile | 3 +
arch/x86/include/asm/ras.h | 13 ++++
arch/x86/ras/Makefile | 1 +
arch/x86/ras/ras.c | 162 ++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 188 insertions(+), 0 deletions(-)
create mode 100644 arch/x86/include/asm/ras.h
create mode 100644 arch/x86/ras/Makefile
create mode 100644 arch/x86/ras/ras.c
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5bed94e189fa..bda1480241b2 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -657,6 +657,15 @@ config X86_CYCLONE_TIMER
def_bool y
depends on X86_SUMMIT
+config X86_RAS
+ def_bool y
+ prompt "X86 RAS features"
+ ---help---
+ A collection of Reliability, Availability and Serviceability
+ software features which aim to enable hardware error logging
+ and reporting. Leave it at 'y' unless you really know what
+ you're doing
+
source "arch/x86/Kconfig.cpu"
config HPET_TIMER
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 209ba1294592..a6b6bb1f308b 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -146,6 +146,9 @@ drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
# suspend and hibernation support
drivers-$(CONFIG_PM) += arch/x86/power/
+# RAS support
+core-y += arch/x86/ras/
+
drivers-$(CONFIG_FB) += arch/x86/video/
####
diff --git a/arch/x86/include/asm/ras.h b/arch/x86/include/asm/ras.h
new file mode 100644
index 000000000000..17aa2679032b
--- /dev/null
+++ b/arch/x86/include/asm/ras.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_X86_RAS_H
+#define _ASM_X86_RAS_H
+
+extern bool ras_agent;
+
+#define PR_EMERG BIT(0)
+#define PR_WARNING BIT(1)
+#define PR_CONT BIT(2)
+
+extern const char *ras_get_decoded_err(void);
+extern void ras_printk(unsigned long flags, const char *fmt, ...);
+
+#endif /* _ASM_X86_RAS_H */
diff --git a/arch/x86/ras/Makefile b/arch/x86/ras/Makefile
new file mode 100644
index 000000000000..7a70bb5cd057
--- /dev/null
+++ b/arch/x86/ras/Makefile
@@ -0,0 +1 @@
+obj-y := ras.o
diff --git a/arch/x86/ras/ras.c b/arch/x86/ras/ras.c
new file mode 100644
index 000000000000..38e24908e682
--- /dev/null
+++ b/arch/x86/ras/ras.c
@@ -0,0 +1,162 @@
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/ras.h>
+
+static size_t err_str_sz, dec_len;
+static char *err_str;
+
+/*
+ * If true, userspace has an agent running and eating all the
+ * tracing data we're sending out so there's no dmesg output
+ */
+bool ras_agent;
+EXPORT_SYMBOL_GPL(ras_agent);
+
+/* getting the string implies the current buffer is emptied */
+const char *ras_get_decoded_err(void)
+{
+ dec_len = 0;
+ return err_str;
+}
+
+void ras_printk(unsigned long flags, const char *fmt, ...)
+{
+ va_list args;
+ char *buf;
+ size_t left;
+ int i;
+
+ /* add a HW_ERR prefix to a newly started line */
+ if (!(flags & PR_CONT)) {
+ strcpy(err_str + dec_len, HW_ERR);
+ dec_len += strlen(HW_ERR);
+ }
+
+ left = err_str_sz - dec_len - 1;
+
+ if (left <= 50) {
+ /* enlarge arbitrarily by 50 chars */
+ err_str_sz += 50;
+ left += 50;
+
+ err_str = krealloc(err_str, err_str_sz, GFP_KERNEL);
+ if (!err_str) {
+ pr_err("Error enlarging decode buffer.\n");
+ return;
+ }
+ }
+
+ /* use err_str _after_ the realloc because it can change */
+ buf = err_str + dec_len;
+
+ va_start(args, fmt);
+ i = vsnprintf(buf, left, fmt, args);
+ va_end(args);
+
+ if (i >= left) {
+ pr_err("Error decode buffer truncated.\n");
+ dec_len = err_str_sz-1;
+ err_str[dec_len] = '\n';
+ } else
+ dec_len += i;
+
+ if (!ras_agent) {
+ if (flags & PR_EMERG)
+ pr_emerg("%s", buf);
+ if (flags & PR_WARNING)
+ pr_warning("%s", buf);
+ else if (flags & PR_CONT)
+ pr_cont("%s", buf);
+
+ dec_len = 0;
+ }
+}
+EXPORT_SYMBOL_GPL(ras_printk);
+
+struct bus_type ras_subsys = {
+ .name = "ras",
+ .dev_name = "ras",
+};
+
+struct ras_attr {
+ struct attribute attr;
+ ssize_t (*show) (struct kobject *kobj, struct ras_attr *attr, char *bf);
+ ssize_t (*store)(struct kobject *kobj, struct ras_attr *attr,
+ const char *buf, size_t count);
+};
+
+#define RAS_ATTR(_name, _mode, _show, _store) \
+static struct ras_attr ras_attr_##_name = __ATTR(_name, _mode, _show, _store)
+
+static ssize_t ras_agent_show(struct kobject *kobj,
+ struct ras_attr *attr,
+ char *buf)
+{
+ return sprintf(buf, "%.1d\n", ras_agent);
+}
+
+static ssize_t ras_agent_store(struct kobject *kobj,
+ struct ras_attr *attr,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ unsigned long value;
+
+ ret = kstrtoul(buf, 10, &value);
+ if (ret < 0) {
+ printk(KERN_ERR "Wrong value for ras_agent field.\n");
+ return ret;
+ }
+
+ ras_agent = !!value;
+
+ return count;
+}
+
+RAS_ATTR(agent, 0644, ras_agent_show, ras_agent_store);
+
+static struct attribute *ras_root_attrs[] = {
+ &ras_attr_agent.attr,
+ NULL
+};
+
+static const struct attribute_group ras_root_attr_group = {
+ .attrs = ras_root_attrs,
+};
+
+static const struct attribute_group *ras_root_attr_groups[] = {
+ &ras_root_attr_group,
+ NULL,
+};
+
+static int __init ras_init(void)
+{
+ int err = 0;
+
+ err = subsys_system_register(&ras_subsys, ras_root_attr_groups);
+ if (err) {
+ printk(KERN_ERR "Error registering toplevel RAS sysfs node.\n");
+ return err;
+ }
+
+ /* initial string size, will be potentially enlarged if needed */
+ err_str_sz = 200;
+
+ /* no freeing of this since it ras.c is compiled-on only */
+ err_str = kzalloc(err_str_sz, GFP_KERNEL);
+ if (!err_str) {
+ err = -ENOMEM;
+ goto err_alloc;
+ }
+
+ return 0;
+
+err_alloc:
+ bus_unregister(&ras_subsys);
+
+ return err;
+}
+subsys_initcall(ras_init);
--
1.7.8.rc0
next prev parent reply other threads:[~2012-02-28 16:11 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-28 16:11 [RFC PATCH 0/3] RAS: Use MCE tracepoint for decoded MCEs Borislav Petkov
2012-02-28 16:11 ` [PATCH 1/3] mce: Add a msg string to the MCE tracepoint Borislav Petkov
2012-02-29 1:14 ` Hidetoshi Seto
2012-02-29 10:10 ` Borislav Petkov
2012-02-29 12:04 ` Mauro Carvalho Chehab
2012-02-29 12:19 ` Borislav Petkov
2012-02-29 13:05 ` Mauro Carvalho Chehab
2012-02-29 13:37 ` Borislav Petkov
2012-02-29 17:11 ` Luck, Tony
2012-02-29 17:19 ` Borislav Petkov
2012-03-01 2:23 ` Hidetoshi Seto
2012-03-01 11:40 ` Borislav Petkov
2012-03-01 18:28 ` Luck, Tony
2012-03-02 4:02 ` Hidetoshi Seto
2012-03-02 13:17 ` Mauro Carvalho Chehab
2012-03-02 20:05 ` Luck, Tony
2012-02-29 17:20 ` Luck, Tony
2012-02-29 18:00 ` Mauro Carvalho Chehab
2012-02-29 18:11 ` Luck, Tony
2012-02-29 12:52 ` Mauro Carvalho Chehab
2012-02-29 13:45 ` Borislav Petkov
2012-02-29 14:04 ` Mauro Carvalho Chehab
2012-02-29 14:40 ` Borislav Petkov
2012-02-29 16:58 ` Luck, Tony
2012-02-29 17:16 ` Borislav Petkov
2012-02-29 17:33 ` Luck, Tony
2012-03-01 11:29 ` Borislav Petkov
2012-03-01 13:19 ` Mauro Carvalho Chehab
2012-03-01 18:15 ` Luck, Tony
2012-03-01 18:45 ` Borislav Petkov
2012-03-01 18:58 ` Luck, Tony
2012-03-01 19:54 ` Mauro Carvalho Chehab
2012-02-29 17:45 ` Mauro Carvalho Chehab
2012-02-29 17:17 ` Mauro Carvalho Chehab
2012-02-28 16:11 ` Borislav Petkov [this message]
2012-02-28 22:43 ` [PATCH 2/3] x86, RAS: Add a decoded msg buffer Luck, Tony
2012-02-29 10:11 ` Borislav Petkov
2012-03-02 9:55 ` Borislav Petkov
2012-02-28 16:11 ` [PATCH 3/3] EDAC: Convert AMD EDAC pieces to use RAS printk buffer Borislav Petkov
2012-03-06 13:31 [RFC -v3 PATCH 0/3] RAS: Use MCE tracepoint for decoded MCEs Borislav Petkov
2012-03-06 13:31 ` [PATCH 2/3] x86, RAS: Add a decoded msg buffer Borislav Petkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1330445487-15020-3-git-send-email-bp@amd64.org \
--to=bp@amd64.org \
--cc=borislav.petkov@amd.com \
--cc=linux-edac@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome