All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>,
	linux-kernel@vger.kernel.org, torvalds@linux-foundation.org,
	arjan@linux.intel.com, bp@alien8.de, jpoimboe@redhat.com,
	richard.weinberger@gmail.com
Subject: Re: [RFC][PATCH] bug: Add _ONCE logic to report_bug()
Date: Sat, 25 Feb 2017 10:44:26 +0100	[thread overview]
Message-ID: <20170225094426.GT6500@twins.programming.kicks-ass.net> (raw)
In-Reply-To: <20170225091823.GB24922@gmail.com>

On Sat, Feb 25, 2017 at 10:18:23AM +0100, Ingo Molnar wrote:

> > Sadly this only works for WARN_ON_ONCE(), since the others have
> > printk() statements prior to triggering the trap.
> 
> Which one is problematic to convert, WARN_ONCE()?

Yes, WARN_ONCE(), all the ones that have printf fmt crud in.

If we want report_bug() to do the _ONCE thing, we also need that to do
the printk().

I tried the below hackery (beware eye and brain damage ahead) which
actually compiles, but generates horrific junk -- far larger than
without.

The __builtin_va_*() crud was really not meant for things like this.

---
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -66,6 +66,11 @@ do {								\
 
 #define __WARN_FLAGS(flags)	_BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags))
 
+#define __WARN_ARGS_FLAGS(args, flags) do {		\
+	asm volatile ("" : : "a" (args));		\
+	_BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags));	\
+} while (0)
+
 #include <asm-generic/bug.h>
 
 #endif /* _ASM_X86_BUG_H */
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -7,6 +7,7 @@
 #define BUGFLAG_WARNING		(1 << 0)
 #define BUGFLAG_ONCE		(1 << 1)
 #define BUGFLAG_DONE		(1 << 2)
+#define BUGFLAG_ARGS		(1 << 3)
 #define BUGFLAG_TAINT(taint)	(BUGFLAG_WARNING | ((taint) << 8))
 #define BUG_GET_TAINT(bug)	((bug)->flags >> 8)
 #endif
@@ -67,8 +68,28 @@ struct bug_entry {
 		__WARN_ONCE_TAINT(TAINT_WARN);			\
 	unlikely(__ret_warn_on);				\
 })
+
+#ifdef __WARN_ARGS_FLAGS
+static inline void __va_hack(va_list *ap, ...)
+{
+	va_start(*ap, ap);
+}
+
+#define __WARN_printf(arg...) do {					\
+	va_list __ap;							\
+	__va_hack(&__ap, arg);						\
+	__WARN_ARGS_FLAGS(&__ap, BUGFLAG_ARGS|BUGFLAG_TAINT(TAINT_WARN));	\
+} while (0)
+
+#define __WARN_printf_taint(taint, arg...) do {				\
+	va_list __ap;							\
+	__va_hack(&__ap, arg);						\
+	__WARN_ARGS_FLAGS(&__ap, BUGFLAG_ARGS|BUGFLAG_TAINT(taint));	\
+} while (0)
 #endif
 
+#endif /* __WARN_FLAGS */
+
 /*
  * WARN(), WARN_ON(), WARN_ON_ONCE, and so on can be used to report
  * significant issues that need prompt attention if they should ever
@@ -90,10 +111,12 @@ extern void warn_slowpath_null(const cha
 	warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg)
 #else
 #define __WARN()		__WARN_TAINT(TAINT_WARN)
+#ifndef __WARN_ARGS_FLAGS
 #define __WARN_printf(arg...)	do { printk(arg); __WARN(); } while (0)
 #define __WARN_printf_taint(taint, arg...)				\
 	do { printk(arg); __WARN_TAINT(taint); } while (0)
 #endif
+#endif
 
 /* used internally by panic.c */
 struct warn_args;
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -143,7 +143,8 @@ enum bug_trap_type report_bug(unsigned l
 {
 	struct bug_entry *bug;
 	const char *file;
-	unsigned line, warning, once, done;
+	unsigned line, warning, once, done, args;
+	va_list *ap;
 
 	if (!is_valid_bugaddr(bugaddr))
 		return BUG_TRAP_TYPE_NONE;
@@ -166,6 +167,7 @@ enum bug_trap_type report_bug(unsigned l
 		warning = (bug->flags & BUGFLAG_WARNING) != 0;
 		once = (bug->flags & BUGFLAG_ONCE) != 0;
 		done = (bug->flags & BUGFLAG_DONE) != 0;
+		args = (bug->flags & BUGFLAG_ARGS) != 0;
 
 		if (warning && once) {
 			if (done)
@@ -176,9 +178,16 @@ enum bug_trap_type report_bug(unsigned l
 			 */
 			bug->flags |= BUGFLAG_DONE;
 		}
+
+		if (args)
+			ap = (va_list *)regs->ax;
 	}
 
 	if (warning) {
+		if (args) {
+			const char *fmt = va_arg(*ap, const char *);
+			vprintk(fmt, *ap);
+		}
 		/* this is a WARN_ON rather than BUG/BUG_ON */
 		__warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
 		       NULL);

      reply	other threads:[~2017-02-25 10:44 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-23 13:28 [PATCH] x86: Implement __WARN using UD0 Peter Zijlstra
2017-02-23 14:09 ` Peter Zijlstra
2017-02-23 14:59   ` Peter Zijlstra
2017-02-23 15:09   ` hpa
2017-02-23 15:23     ` Peter Zijlstra
2017-02-23 15:32       ` hpa
2017-02-23 16:03         ` Borislav Petkov
2017-02-23 14:12 ` Josh Poimboeuf
2017-02-23 14:17   ` Borislav Petkov
2017-02-23 14:36   ` Peter Zijlstra
2017-02-23 14:14 ` Arjan van de Ven
2017-02-23 14:57   ` Peter Zijlstra
2017-02-24  7:43     ` Ingo Molnar
2017-02-24  8:31       ` Peter Zijlstra
2017-02-24  9:06         ` hpa
2017-02-24  9:11         ` hpa
2017-02-24  9:15           ` Ingo Molnar
2017-02-24  9:46             ` Borislav Petkov
2017-02-24  9:52               ` H. Peter Anvin
     [not found]             ` <21ac6e53-2fcd-52e9-e72d-9faf7da14d1e@zytor.com>
2017-02-24 10:41               ` Peter Zijlstra
2017-02-25 10:38                 ` Borislav Petkov
2017-02-25 17:55                   ` hpa
2017-02-25 19:38                     ` Borislav Petkov
2017-02-25 20:04                       ` hpa
2017-02-25 20:29                         ` Borislav Petkov
2017-02-24 11:16 ` [PATCH -v2] " Peter Zijlstra
2017-02-25  8:19   ` [RFC][PATCH] bug: Add _ONCE logic to report_bug() Peter Zijlstra
2017-02-25  9:18     ` Ingo Molnar
2017-02-25  9:44       ` Peter Zijlstra [this message]

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=20170225094426.GT6500@twins.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=arjan@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=hpa@zytor.com \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=richard.weinberger@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.