From patchwork Sat Apr 18 00:14:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Hutchings X-Patchwork-Id: 6236071 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A4A02BF4A6 for ; Sat, 18 Apr 2015 00:18:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A5B1F201BC for ; Sat, 18 Apr 2015 00:18:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7839820166 for ; Sat, 18 Apr 2015 00:17:59 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YjGPo-0003Vd-Oj; Sat, 18 Apr 2015 00:15:20 +0000 Received: from ducie-dc1.codethink.co.uk ([185.25.241.215]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YjGPl-0002Kk-At for linux-arm-kernel@lists.infradead.org; Sat, 18 Apr 2015 00:15:18 +0000 Received: from localhost (localhost [127.0.0.1]) by ducie-dc1.codethink.co.uk (Postfix) with ESMTP id 28BD8460BDC; Sat, 18 Apr 2015 01:14:47 +0100 (BST) X-Virus-Scanned: Debian amavisd-new at ducie-dc1.codethink.co.uk Received: from ducie-dc1.codethink.co.uk ([127.0.0.1]) by localhost (ducie-dc1.codethink.co.uk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wQilKzVygmSp; Sat, 18 Apr 2015 01:14:44 +0100 (BST) Received: from [192.168.25.61] (unknown [192.168.25.61]) by ducie-dc1.codethink.co.uk (Postfix) with ESMTPSA id 8543246073D; Sat, 18 Apr 2015 01:14:44 +0100 (BST) Message-ID: <1429316083.8341.76.camel@xylophone.i.decadent.org.uk> Subject: [PATCH] ARM: mm: add imprecise abort non-deadly handler From: Ben Hutchings To: linux-arm-kernel@lists.infradead.org Date: Sat, 18 Apr 2015 01:14:43 +0100 Organization: Codethink Ltd. X-Mailer: Evolution 3.4.4-3 Mime-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150417_171517_698419_9587C425 X-CRM114-Status: GOOD ( 18.23 ) X-Spam-Score: -0.0 (/) Cc: CT kernel , Ben Dooks X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ben Dooks Given that imprecise aborts may be delivered after the action that caused them (or even for non-cpu related activities such as bridge faults from a bus-master) it is possible that the wrong process is terminated as a result. Add a handler to take and print imprecise aborts and allow the process to continue. This should ensure that the abort is shown but not kill the process that was running on the cpu core at the time. Signed-off-by: Ben Dooks [bwh: Change the log level and format to match other exceptions; set the now-unused sig and code fields for these exceptions to 0] Signed-off-by: Ben Hutchings --- arch/arm/mm/fault.c | 20 ++++++++++++++++++++ arch/arm/mm/fsr-2level.c | 32 ++++++++++++++++---------------- arch/arm/mm/fsr-3level.c | 2 +- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 6333d9c17875..da00fd68fdf4 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -518,6 +518,26 @@ struct fsr_info { const char *name; }; +static struct fsr_info fsr_info[]; + +/* + * On an imprecise external abort it is possible that the currently running + * process did not cause it (it could be from an external bus bridge or + * another device causing a fault on the bus). + * + * Always return handled as we do not know how to do it and killing the + * current process may not prevent future faults. + */ +static int +do_bad_imprecise(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + const struct fsr_info *inf = fsr_info + fsr_fs(fsr); + + pr_alert("Imprecise abort: %s (0x%03x) at %08lx\n", + inf->name, fsr, addr); + return 0; +} + /* FSR definition */ #ifdef CONFIG_ARM_LPAE #include "fsr-3level.c" diff --git a/arch/arm/mm/fsr-2level.c b/arch/arm/mm/fsr-2level.c index 18ca74c0f341..84f2d77ac150 100644 --- a/arch/arm/mm/fsr-2level.c +++ b/arch/arm/mm/fsr-2level.c @@ -24,22 +24,22 @@ static struct fsr_info fsr_info[] = { * 10 of the FSR, and may not be recoverable. These are only * supported if the CPU abort handler supports bit 10. */ - { do_bad, SIGBUS, 0, "unknown 16" }, - { do_bad, SIGBUS, 0, "unknown 17" }, - { do_bad, SIGBUS, 0, "unknown 18" }, - { do_bad, SIGBUS, 0, "unknown 19" }, - { do_bad, SIGBUS, 0, "lock abort" }, /* xscale */ - { do_bad, SIGBUS, 0, "unknown 21" }, - { do_bad, SIGBUS, BUS_OBJERR, "imprecise external abort" }, /* xscale */ - { do_bad, SIGBUS, 0, "unknown 23" }, - { do_bad, SIGBUS, 0, "dcache parity error" }, /* xscale */ - { do_bad, SIGBUS, 0, "unknown 25" }, - { do_bad, SIGBUS, 0, "unknown 26" }, - { do_bad, SIGBUS, 0, "unknown 27" }, - { do_bad, SIGBUS, 0, "unknown 28" }, - { do_bad, SIGBUS, 0, "unknown 29" }, - { do_bad, SIGBUS, 0, "unknown 30" }, - { do_bad, SIGBUS, 0, "unknown 31" }, + { do_bad_imprecise, 0, 0, "unknown 16" }, + { do_bad_imprecise, 0, 0, "unknown 17" }, + { do_bad_imprecise, 0, 0, "unknown 18" }, + { do_bad_imprecise, 0, 0, "unknown 19" }, + { do_bad_imprecise, 0, 0, "lock abort" }, /* xscale */ + { do_bad_imprecise, 0, 0, "unknown 21" }, + { do_bad_imprecise, 0, 0, "imprecise external abort" }, /* xscale */ + { do_bad_imprecise, 0, 0, "unknown 23" }, + { do_bad_imprecise, 0, 0, "dcache parity error" }, /* xscale */ + { do_bad_imprecise, 0, 0, "unknown 25" }, + { do_bad_imprecise, 0, 0, "unknown 26" }, + { do_bad_imprecise, 0, 0, "unknown 27" }, + { do_bad_imprecise, 0, 0, "unknown 28" }, + { do_bad_imprecise, 0, 0, "unknown 29" }, + { do_bad_imprecise, 0, 0, "unknown 30" }, + { do_bad_imprecise, 0, 0, "unknown 31" }, }; static struct fsr_info ifsr_info[] = { diff --git a/arch/arm/mm/fsr-3level.c b/arch/arm/mm/fsr-3level.c index ab4409a2307e..6eaae6ec6d71 100644 --- a/arch/arm/mm/fsr-3level.c +++ b/arch/arm/mm/fsr-3level.c @@ -16,7 +16,7 @@ static struct fsr_info fsr_info[] = { { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" }, { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" }, { do_bad, SIGBUS, 0, "synchronous external abort" }, - { do_bad, SIGBUS, 0, "asynchronous external abort" }, + { do_bad_imprecise, 0, 0, "asynchronous external abort" }, { do_bad, SIGBUS, 0, "unknown 18" }, { do_bad, SIGBUS, 0, "unknown 19" }, { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },