lkml.org 
[lkml]   [2019]   [Aug]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 7/7] bug: Move WARN_ON() "cut here" into exception handler
    Date
    The original clean up of "cut here" missed the WARN_ON() case (that
    does not have a printk message), which was fixed recently by adding
    an explicit printk of "cut here". This had the downside of adding a
    printk() to every WARN_ON() caller, which reduces the utility of using
    an instruction exception to streamline the resulting code. By making
    this a new BUGFLAG, all of these can be removed and "cut here" can be
    handled by the exception handler.

    This was very pronounced on PowerPC, but the effect can be seen on
    x86 as well. The resulting text size of a defconfig build shows some
    small savings from this patch:

    text data bss dec hex filename
    19691167 5134320 1646664 26472151 193eed7 vmlinux.before
    19676362 5134260 1663048 26473670 193f4c6 vmlinux.after

    This change also opens the door for creating something like BUG_MSG(),
    where a custom printk() before issuing BUG(), without confusing the "cut
    here" line.

    Reported-by: Christophe Leroy <christophe.leroy@c-s.fr>
    Fixes: Fixes: 6b15f678fb7d ("include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT architectures")
    Signed-off-by: Kees Cook <keescook@chromium.org>
    ---
    include/asm-generic/bug.h | 8 +++-----
    lib/bug.c | 11 +++++++++--
    2 files changed, 12 insertions(+), 7 deletions(-)

    diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
    index 588dd59a5b72..da471fcc5487 100644
    --- a/include/asm-generic/bug.h
    +++ b/include/asm-generic/bug.h
    @@ -10,6 +10,7 @@
    #define BUGFLAG_WARNING (1 << 0)
    #define BUGFLAG_ONCE (1 << 1)
    #define BUGFLAG_DONE (1 << 2)
    +#define BUGFLAG_PRINTK (1 << 3)
    #define BUGFLAG_TAINT(taint) ((taint) << 8)
    #define BUG_GET_TAINT(bug) ((bug)->flags >> 8)
    #endif
    @@ -86,13 +87,10 @@ void warn_slowpath_fmt(const char *file, const int line, unsigned taint,
    warn_slowpath_fmt(__FILE__, __LINE__, taint, arg)
    #else
    extern __printf(1, 2) void __warn_printk(const char *fmt, ...);
    -#define __WARN() do { \
    - printk(KERN_WARNING CUT_HERE); \
    - __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN)); \
    - } while (0)
    +#define __WARN() __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN))
    #define __WARN_printf(taint, arg...) do { \
    __warn_printk(arg); \
    - __WARN_FLAGS(BUGFLAG_TAINT(taint)); \
    + __WARN_FLAGS(BUGFLAG_PRINTK | BUGFLAG_TAINT(taint)); \
    } while (0)
    #define WARN_ON_ONCE(condition) ({ \
    int __ret_warn_on = !!(condition); \
    diff --git a/lib/bug.c b/lib/bug.c
    index 1077366f496b..6c22e8a6f9de 100644
    --- a/lib/bug.c
    +++ b/lib/bug.c
    @@ -181,6 +181,15 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
    }
    }

    + /*
    + * BUG() and WARN_ON() families don't print a custom debug message
    + * before triggering the exception handler, so we must add the
    + * "cut here" line now. WARN() issues its own "cut here" before the
    + * extra debugging message it writes before triggering the handler.
    + */
    + if ((bug->flags & BUGFLAG_PRINTK) == 0)
    + printk(KERN_DEFAULT CUT_HERE);
    +
    if (warning) {
    /* this is a WARN_ON rather than BUG/BUG_ON */
    __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
    @@ -188,8 +197,6 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
    return BUG_TRAP_TYPE_WARN;
    }

    - printk(KERN_DEFAULT CUT_HERE);
    -
    if (file)
    pr_crit("kernel BUG at %s:%u!\n", file, line);
    else
    --
    2.17.1
    \
     
     \ /
      Last update: 2019-08-20 01:44    [W:2.785 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site