linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: "Guilherme G. Piccoli" <gpiccoli@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: benh@kernel.crashing.org, paulus@samba.org, mpe@ellerman.id.au,
	npiggin@gmail.com, xinhui.pan@linux.vnet.ibm.com,
	gpiccoli@linux.vnet.ibm.com
Subject: [PATCH] powerpc/xmon: add debugfs entry for xmon
Date: Mon, 13 Feb 2017 19:00:42 -0200	[thread overview]
Message-ID: <1487019642-11411-1-git-send-email-gpiccoli@linux.vnet.ibm.com> (raw)

Currently the xmon debugger is set only via kernel boot command-line.
It's disabled by default, and can be enabled with "xmon=on" on the
command-line. Also, xmon may be accessed via sysrq mechanism, but once
we enter xmon via sysrq,  it's  kept enabled until system is rebooted,
even if we exit the debugger. A kernel crash will then lead to xmon
instance, instead of triggering a kdump procedure (if configured), for
example.

This patch introduces a debugfs entry for xmon, allowing user to query
its current state and change it if desired. Basically, the "xmon" file
to read from/write to is under the debugfs mount point, on powerpc
directory. Reading this file will provide the current state of the
debugger, one of the following: "on", "off", "early" or "nobt". Writing
one of these states to the file will take immediate effect on the debugger.

Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
---
* I had this patch partially done for some time, and after a discussion
at the kernel slack channel latest week, I decided to rebase and fix
some remaining bugs. I'd change 'x' option to always disable the debugger,
since with this patch we can always re-enable xmon, but today I noticed
Pan's patch on the mailing list, so perhaps his approach of adding a flag
to 'x' option is preferable. I can change this in a V2, if requested.
Thanks in advance!

 arch/powerpc/xmon/xmon.c | 124 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 105 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 9c0e17c..5fb39db 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -29,6 +29,12 @@
 #include <linux/nmi.h>
 #include <linux/ctype.h>
 
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#endif
+
 #include <asm/ptrace.h>
 #include <asm/string.h>
 #include <asm/prom.h>
@@ -184,7 +190,12 @@ static void dump_tlb_44x(void);
 static void dump_tlb_book3e(void);
 #endif
 
-static int xmon_no_auto_backtrace;
+/* xmon_state values */
+#define XMON_OFF	0
+#define XMON_ON	1
+#define XMON_EARLY	2
+#define XMON_NOBT	3
+static int xmon_state;
 
 #ifdef CONFIG_PPC64
 #define REG		"%.16lx"
@@ -880,8 +891,8 @@ cmds(struct pt_regs *excp)
 	last_cmd = NULL;
 	xmon_regs = excp;
 
-	if (!xmon_no_auto_backtrace) {
-		xmon_no_auto_backtrace = 1;
+	if (xmon_state != XMON_NOBT) {
+		xmon_state = XMON_NOBT;
 		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
 	}
 
@@ -3244,6 +3255,26 @@ static void xmon_init(int enable)
 	}
 }
 
+static int parse_xmon(char *p)
+{
+	if (!p || strncmp(p, "early", 5) == 0) {
+		/* just "xmon" is equivalent to "xmon=early" */
+		xmon_init(1);
+		xmon_state = XMON_EARLY;
+	} else if (strncmp(p, "on", 2) == 0) {
+		xmon_init(1);
+		xmon_state = XMON_ON;
+	} else if (strncmp(p, "off", 3) == 0) {
+		xmon_init(0);
+		xmon_state = XMON_OFF;
+	} else if (strncmp(p, "nobt", 4) == 0)
+		xmon_state = XMON_NOBT;
+	else
+		return 1;
+
+	return 0;
+}
+
 #ifdef CONFIG_MAGIC_SYSRQ
 static void sysrq_handle_xmon(int key)
 {
@@ -3266,34 +3297,89 @@ static int __init setup_xmon_sysrq(void)
 __initcall(setup_xmon_sysrq);
 #endif /* CONFIG_MAGIC_SYSRQ */
 
-static int __initdata xmon_early, xmon_off;
+#ifdef CONFIG_DEBUG_FS
+static ssize_t xmon_dbgfs_read(struct file *file, char __user *ubuffer,
+				size_t len, loff_t *offset)
+{
+	int buf_len = 0;
+	char buf[6] = { 0 };
 
-static int __init early_parse_xmon(char *p)
+	switch (xmon_state) {
+	case XMON_OFF:
+		buf_len = sprintf(buf, "off");
+		break;
+	case XMON_ON:
+		buf_len = sprintf(buf, "on");
+		break;
+	case XMON_EARLY:
+		buf_len = sprintf(buf, "early");
+		break;
+	case XMON_NOBT:
+		buf_len = sprintf(buf, "nobt");
+		break;
+	}
+
+	return simple_read_from_buffer(ubuffer, len, offset, buf, buf_len);
+}
+
+static ssize_t xmon_dbgfs_write(struct file *file, const char __user *ubuffer,
+				size_t len, loff_t *offset)
 {
-	if (!p || strncmp(p, "early", 5) == 0) {
-		/* just "xmon" is equivalent to "xmon=early" */
-		xmon_init(1);
-		xmon_early = 1;
-	} else if (strncmp(p, "on", 2) == 0)
-		xmon_init(1);
-	else if (strncmp(p, "off", 3) == 0)
-		xmon_off = 1;
-	else if (strncmp(p, "nobt", 4) == 0)
-		xmon_no_auto_backtrace = 1;
-	else
-		return 1;
+	int ret, not_copied;
+	char *buf;
+
+	/* Valid states are on, off, early and nobt. */
+	if ((*offset != 0) || (len <= 0) || (len > 6))
+                return -EINVAL;
+
+	buf = kzalloc(len + 1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	not_copied = copy_from_user(buf, ubuffer, len);
+	if (not_copied) {
+		kfree(buf);
+		return -EFAULT;
+        }
 
+	ret = parse_xmon(buf);
+	kfree(buf);
+
+	/* parse_xmon returns 0 on success. */
+	if (ret)
+		return -EINVAL;
+	return len;
+}
+
+static const struct file_operations xmon_dbgfs_ops = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.read = xmon_dbgfs_read,
+	.write = xmon_dbgfs_write,
+};
+
+static int __init setup_xmon_dbgfs(void)
+{
+	debugfs_create_file("xmon", 0600, powerpc_debugfs_root, NULL,
+			    &xmon_dbgfs_ops);
 	return 0;
 }
+__initcall(setup_xmon_dbgfs);
+#endif /*CONFIG_DEBUG_FS*/
+
+static int __init early_parse_xmon(char *p)
+{
+	return parse_xmon(p);
+}
 early_param("xmon", early_parse_xmon);
 
 void __init xmon_setup(void)
 {
 #ifdef CONFIG_XMON_DEFAULT
-	if (!xmon_off)
+	if (xmon_state) /* XMON_OFF */
 		xmon_init(1);
 #endif
-	if (xmon_early)
+	if (xmon_state == XMON_EARLY)
 		debugger(NULL);
 }
 
-- 
2.7.4

             reply	other threads:[~2017-02-13 21:00 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-13 21:00 Guilherme G. Piccoli [this message]
2017-02-14  2:35 ` [PATCH] powerpc/xmon: add debugfs entry for xmon Nicholas Piggin
2017-02-14  3:58   ` Pan Xinhui
2017-02-14 11:41     ` Michael Ellerman
2017-02-14 17:35     ` Guilherme G. Piccoli
2017-02-14 23:50       ` Michael Ellerman
2017-02-15  3:52       ` panxinhui
2017-02-14 11:37 ` Michael Ellerman
2017-02-14 17:39   ` Guilherme G. Piccoli

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=1487019642-11411-1-git-send-email-gpiccoli@linux.vnet.ibm.com \
    --to=gpiccoli@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=paulus@samba.org \
    --cc=xinhui.pan@linux.vnet.ibm.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;
as well as URLs for NNTP newsgroup(s).