Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752752AbbBXDa4 (ORCPT ); Mon, 23 Feb 2015 22:30:56 -0500 Received: from ozlabs.org ([103.22.144.67]:44728 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752552AbbBXDay (ORCPT ); Mon, 23 Feb 2015 22:30:54 -0500 From: Anton Blanchard To: Andrew Morton , Steven Rostedt , Michael Ellerman , Paul Mackerras , Benjamin Herrenschmidt , sam.bobroff@au1.ibm.com, Thomas Gleixner , Ingo Molnar , hpa@zytor.com, Russell King , peterz@infradead.org, Don Zickus Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, x86@kernel.org Subject: [PATCH 7/7] powerpc: Serialise BUG and WARNs with die_spin_lock_{irqsave,irqrestore} Date: Tue, 24 Feb 2015 14:30:34 +1100 Message-Id: <1424748634-9153-8-git-send-email-anton@samba.org> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1424748634-9153-1-git-send-email-anton@samba.org> References: <1424748634-9153-1-git-send-email-anton@samba.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2567 Lines: 88 A simple kernel module was used to create concurrent WARNs and BUGs: http://ozlabs.org/~anton/junkcode/warnstorm.tar.gz Signed-off-by: Anton Blanchard --- arch/powerpc/kernel/traps.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 4cc1e72..f779557 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1114,6 +1114,39 @@ static int emulate_math(struct pt_regs *regs) static inline int emulate_math(struct pt_regs *regs) { return -1; } #endif +static bool __report_bug(unsigned long bugaddr, struct pt_regs *regs) +{ + const struct bug_entry *bug; + unsigned long flags; + int err; + + if (!is_valid_bugaddr(bugaddr)) + return false; + + bug = find_bug(bugaddr); + if (!bug) + return false; + + if (is_warning_bug(bug)) { + die_spin_lock_irqsave(flags); + report_bug(bugaddr, regs); + die_spin_unlock_irqrestore(flags); + + regs->nip += 4; + + return true; + } + + flags = oops_begin(regs); + report_bug(bugaddr, regs); + err = SIGTRAP; + if (__die("Exception in kernel mode", regs, err)) + err = 0; + oops_end(flags, regs, err); + + return true; +} + void __kprobes program_check_exception(struct pt_regs *regs) { enum ctx_state prev_state = exception_enter(); @@ -1138,11 +1171,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) == NOTIFY_STOP) goto bail; - if (!(regs->msr & MSR_PR) && /* not user-mode */ - report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { - regs->nip += 4; + if (!user_mode(regs) && __report_bug(regs->nip, regs)) goto bail; - } + _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); goto bail; } @@ -1157,11 +1188,8 @@ void __kprobes program_check_exception(struct pt_regs *regs) * - A tend is illegally attempted. * - writing a TM SPR when transactional. */ - if (!user_mode(regs) && - report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { - regs->nip += 4; + if (!user_mode(regs) && __report_bug(regs->nip, regs)) goto bail; - } /* If usermode caused this, it's done something illegal and * gets a SIGILL slap on the wrist. We call it an illegal * operand to distinguish from the instruction just being bad -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/