From patchwork Thu Mar 31 02:27:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 8706921 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id DF8139F3D1 for ; Thu, 31 Mar 2016 02:30:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D909C202A1 for ; Thu, 31 Mar 2016 02:30:09 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD758201CE for ; Thu, 31 Mar 2016 02:30:08 +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 1alSKu-0008FY-GQ; Thu, 31 Mar 2016 02:27:52 +0000 Received: from mail-bn1on0085.outbound.protection.outlook.com ([157.56.110.85] helo=na01-bn1-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1alSKq-0008Dj-4m for linux-arm-kernel@lists.infradead.org; Thu, 31 Mar 2016 02:27:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-caviumnetworks-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=WCJcwc8NX7HqRjTTlImeDT30Kd7iebhn3cLr3N6A5hA=; b=L2ARKpY50ZkKjYY+m5qmKDhK5L/fdkWtIN9QvQ3aqkXlJPt3tsUECse2vmUwuJjuqV3B9Ej+Wk7likrs+587/ME/8kjhlJHrFY4BYAeMyQtmTBdy5HY2I3BLmHjH9IS96YtIVo5BpRjpJ4tMDDZf3jfdPzgDgDvo7HwRcUcBU04= Authentication-Results: lists.infradead.org; dkim=none (message not signed) header.d=none; lists.infradead.org; dmarc=none action=none header.from=caviumnetworks.com; Received: from localhost (95.143.213.121) by BLUPR07MB611.namprd07.prod.outlook.com (10.141.207.16) with Microsoft SMTP Server (TLS) id 15.1.434.16; Thu, 31 Mar 2016 02:27:23 +0000 From: Yury Norov To: , , Subject: [RFC] [PATCH] arm64: survive after access to unimplemented register Date: Thu, 31 Mar 2016 05:27:03 +0300 Message-ID: <1459391223-3826-1-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.5.0 MIME-Version: 1.0 X-Originating-IP: [95.143.213.121] X-ClientProxiedBy: VI1PR07CA0123.eurprd07.prod.outlook.com (25.165.229.177) To BLUPR07MB611.namprd07.prod.outlook.com (10.141.207.16) X-MS-Office365-Filtering-Correlation-Id: 87e75d2e-c4bc-4ed3-a606-08d3590bfe94 X-Microsoft-Exchange-Diagnostics: 1; BLUPR07MB611; 2:uBVyhZEonIUDr++o/uC8hX1Kx8W5TjAQIiJ/vBKkLV99R1n/3ZwaoXuT8X0wyGsWQuGBgGc6XhTCFFxwp/ZDLmyK+NzjaANGLPer+W+N/BS18m/IKSCL5Wvj4tCR8Hqz6wpWbjlbjOpsMXtywRCkzK/7rrhmOYTbaF+Dez5J6wT3lGCoNGUyy15dtbBZEbPo; 3:iC5/M0QnBQwLd8Fkls6w+sTUuIAtnrFnEPA26dG3fAy2dCWbNyWDBYgAgmmCkew81Bf+Yjr4cziqxUUMnAPtdTOeMXzA1a/C9Zt0P9UMre+1JAlLk5cFNk1OGNUeC9VK X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR07MB611; X-Microsoft-Exchange-Diagnostics: 1; BLUPR07MB611; 25:F9K5t79m+sC/8EBYYnMmViSoGTP++s3MP8JtVLhJvLo6k94ZEGGijBPtCaqMr7/q+XDy5pndJFiW7WitlvGiIhynMGKaea9SlNu9HoH/eKtG2K/2RkfuzeTyHdHb4o72+8rS4COSwMdFGsJL6PBujChYUyqiRC9CsQ0an6d9SihGOI1zUOeVqBDUXr3zgxRjNBz0Lx0WMOD+E2xK7h3M0n+r4p+oMfxBacNHf38bfxWTuHPX048OKXtimp4z/HNMJxar2/nviZUN5OqALxkMk4UTwZW+fhRaLg+HxNhIx5/dhI8Ejvsl1TkaaTDzDvC7YsixybhXzdLmaWRiRgloJralCkeyF3gYzEzLzC6ws6dhTV+h1zHGqo3DvzXL9QzDfQUW20j4YYks8Avo7znI1EhHwV4lUY7hLUHoqkxFiOhx7KVTxnlph4oiRs6/Pj/lkQQ/POuOpJ38XSQ4r+Oibkqmn4D34L2RbaMpdp/mCPqOYZsKE4G9vLbUDUZ+Kjn6w30XLQ8BuoSaQokSH3psYa3eEjJ1b9HxH+cWcseWRiDiQsfn5F/i4QFUQWFpzfRdyoRHlqa3KWz5bHNSTDljCHxXpjIRsVk9IZwqOgzyHVtZSkjRBre7iFELYiPWP14FB0A1rWPJeaA0nBv93zTaPWPZ2WsuhdMPgLmkHISNT1TMbsOYxK8w6fRg7L/f97q4Hfd8Togl5JInP4M/sOYZdCAPYRYwpz1UzYAHXP10ByM= X-Microsoft-Exchange-Diagnostics: 1; BLUPR07MB611; 20:dYYVF8oqe7jF04782CtOfMfNoMGqCPClNZGQcUiMLqZdMaGws8qL5qkXRd+IQJ/u03Hdz6KjyYUCjPshiSh9PvbeZTzgTj9P7A1a45SB9SUWaTXL1o/pUEmeFI7hJOG6QFNASQvXSmC/gizvh+0Pbs6IodZmnADpNErSrHdlWdqZVxoWADo47Ae6LyEN7Hb1n96/0ncfGdxxrDoJG0vk+yr1WFvG1cJFxbjtsoAFay3K0eHupCxBs2op0UJG70E4/Y1RNFqfBKcHNHJ9xYPzhjOuGYXvpQvqJB0Ukev/lT6vDdEp14KXEu4aJk06EIsSBfArdGthj/6TAb1ZBHeRGeNUzepAmICPS0JQox+VNpbzm9jOcpmx3qjQtamFBiDTVllQsYtzqsAHfWOydMjKPIWZWo2S9J0bmUeGAoHS7W++5xAj5n6pwCRHdUqWLQ/KuTOvkVmouSb1vJji2rfdBoSV3Inmh+CBesfvPvo7wjEqFAuZjGoeNybNVP+XO2wRx9W63Y35puihuLH3bJ3gOBGLp8uNPRejzYfsp6QHenI3jnUgPWMJzgoyV+uFJdHQJwqW3ol0216Tlj7EucArXLVW5POOJPRXdscnzJXqzLM= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046); SRVR:BLUPR07MB611; BCL:0; PCL:0; RULEID:; SRVR:BLUPR07MB611; X-Microsoft-Exchange-Diagnostics: 1; BLUPR07MB611; 4:9RjDlX1E0a9sRGqvwQbM3qpZhXtCYlr3ucr9Wlm0tVq26IT3By+hBQgQnsRsV9+0Euk+Oz+jAebSUm08nOeMVHjZvptypChxxoGmsD5s+7IjMn6IHEfpj8d1UxJ3EaYoKMUJ9tYB05TDhSV/WSTjW4QSBmoyfAjW6RGGJ0w1zLHfawlzPtJqzW9mUJ2hzVLIJ+/JIa5lJthvVry9xdB1vfi57BwT+HhkcuLETzDL//x6q/JDBB9BkW4oefaBvLd/KB/8CIl4P3EYu3hW/dzGZ/8zRH9fzfCA+yM7NvpyWVnRmKGwUUantGGORKaBO+pSHR8odaUHB6IRJpRoLnaM1O7HijJ8+UZNEGYxMNOoIwoN5J6/HqgdGpXcemV4tZAR X-Forefront-PRVS: 0898A6E028 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(6069001)(107886002)(575784001)(47776003)(229853001)(50466002)(4001430100002)(5008740100001)(19580395003)(2201001)(15975445007)(189998001)(19580405001)(36756003)(50226001)(5001770100001)(50986999)(66066001)(5003940100001)(76506005)(5004730100002)(48376002)(81166005)(42186005)(77096005)(68736007)(92566002)(2906002)(3846002)(1096002)(586003)(33646002)(6116002)(4326007)(21314002)(2101003); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR07MB611; H:localhost; FPR:; SPF:None; MLV:nov; PTR:InfoNoRecords; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR07MB611; 23:PmvskUdChiI3Zd85MlNW/aNajqYcbRSThHeGOq2hGJ?= =?us-ascii?Q?j/o9wf4gL7ENNdWVNuO9OhkSOWkKFL7bcIqRR4P1C+J2AtvHEOWeNMITcgaS?= =?us-ascii?Q?dVLhSNVzFyh8syh1IQ79bD7o9p8X5KjZlEpm0TzzYgOZSoIw3Z3izc5KCQPR?= =?us-ascii?Q?qDaaH+Pj1J35ahUCesBVo/KweC7Czw2zHTjIEoXWB0AyJdnqo4B/9kmnJaGi?= =?us-ascii?Q?gwDnjjU2EaKWiYSelTcb4hpdv9Svt8q/QcYEJRS9S9Ax3jq6XDaVBbHkf/Mw?= =?us-ascii?Q?j+ggnL7KGgatHHcIb7oIjUnUCFNb6WUI87gyBadnQn8+Ud/3eu2Xr3kZRtgp?= =?us-ascii?Q?JdFK9i1Eu+L0UxUK2DOVIyqjTpaktHXndkcPtGpfL3ERVv5NOWhm0DCvdf5K?= =?us-ascii?Q?UC9Cusrs0aHyI4eWnf3heNqqUNPkI/oEFCcj+Bdkcue7yDZUYYbSv9NRfeyi?= =?us-ascii?Q?vE6oP+uBSvZiu1zCoMrtupiONr1WRQAL7G22IPL/xzIO4aiDekmD2lY/O6pi?= =?us-ascii?Q?hkmO8ezF/oD6LlZb8fDTho2QGhwlSz59Rx59kPIiGhKH8mkYPZos38oQzKKE?= =?us-ascii?Q?PyedyO9hminGZbmk+YKWYl6nLuqwJXEd6/4JYsR+QiGvsC7WZiNayrl2EX4W?= =?us-ascii?Q?Uh4a/pfnIWCIt/LcD+mmrOPSOoupPp+keSnPZrMEsLX8v4EtNXQ6pHgMNu+H?= =?us-ascii?Q?vMR+pIlPZq7wOWdPU9BrBtNJWqzPArIr054bptOsA7M6sVSc/XCCLZpacPhI?= =?us-ascii?Q?7waWhHyzMmee3b54M8U85G9ZkpItLRmiEX73PT7pXac7iVQx+F5ZMAOEL844?= =?us-ascii?Q?Oilu9cfOq3vqbWW+mUaKd0F0sw5A1Fszrv6GKCkj+z2S6tvG2Ju5teiONNVK?= =?us-ascii?Q?jMkVxUDxlTc8nbjVh/29SSOHR7g+lU6S3X+fQ/fgCyXUfoCgzAYg/4/7QvkP?= =?us-ascii?Q?GKzJKJyFceKvOhRGxl+uvDhMyM1jZkpv3NqQkAqNoyEegGOKJvjimV3ZKFbN?= =?us-ascii?Q?ULnNjlo4VVZzlDNioOLHq8Ss3tkfjJz+gdnmaw8Dxjsw=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR07MB611; 5:tGNtKM6m0YtLNF2elvI6YTCLtzd/dR7xKyBJZbvQzv4sxJN+Yvx/qJAmtL18dh9KPwBI6wQTaLqfGdQXopHB5K2w6/8Y7msUpMZcOEO0HuQRyLWYRJsHu/PXhndeT7/RaW15LBMB6slTx3Ed5bnPMg==; 24:4mk1V88z6Yb43+SZiQNH93IhLz3rSVGzw9U1SGfQwF/hhQzj6MipVvAqMZ4l8XR4hNkUHXOC6EKrcviJnzb0RgTvJDlXf7wUr7Liq4N2/jI= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Mar 2016 02:27:23.6445 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR07MB611 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160330_192748_522078_9D6BA7C7 X-CRM114-Status: GOOD ( 12.61 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: wangkefeng.wang@huawei.com, Yury Norov , alexey.klimov@linaro.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.1 required=5.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID, 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 Not all vendors implement all the system registers ARM specifies. So access them causes undefined instruction abort and then kernel panic. There are 3 ways to handle it we can figure out: - use conditional compilation and erratas; - use kernel patching; - inline fixups resolving the abort. Last option is more robust as it does not require additional efforts to support targers. It is looking reasonable because in many cases optional registers should be RAZ if not implemented. Special cases may be handled by underlying __read_cpuid() when needed. Tested on QEMU emulator version 2.3.0 (Debian 1:2.3+dfsg-5ubuntu9.2) that does not implement SYS_ID_AA64MMFR2_EL1 register. (Fixed in new releases), Discussion: https://lkml.org/lkml/2016/3/29/931 Signed-off-by: Yury Norov --- arch/arm64/include/asm/cputype.h | 17 +++++++++++++++-- arch/arm64/include/asm/exttable.h | 21 +++++++++++++++++++++ arch/arm64/include/asm/uaccess.h | 15 --------------- arch/arm64/kernel/entry.S | 3 ++- arch/arm64/kernel/traps.c | 6 ++++++ arch/arm64/mm/extable.c | 2 +- 6 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 arch/arm64/include/asm/exttable.h diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 87e1985..9660130 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -90,13 +90,26 @@ #ifndef __ASSEMBLY__ #include +#include -#define read_cpuid(reg) ({ \ +#define __read_cpuid(reg, err) ({ \ u64 __val; \ - asm("mrs_s %0, " __stringify(SYS_ ## reg) : "=r" (__val)); \ + asm ( \ + "1:mrs_s %0, " reg "\n" \ + "2:\n" \ + " .section .fixup, \"ax\"\n" \ + " .align 2\n" \ + "3: mov %w0, %1\n" \ + " b 2b\n" \ + " .previous\n" \ + _ASM_EXTABLE(1b, 3b) \ + : "=r" (__val) \ + : "i" (err)); \ __val; \ }) +#define read_cpuid(reg) __read_cpuid(__stringify(SYS_ ## reg), 0) + /* * The CPU ID never changes at run time, so we might as well tell the * compiler that it's constant. Use this function to read the CPU ID diff --git a/arch/arm64/include/asm/exttable.h b/arch/arm64/include/asm/exttable.h new file mode 100644 index 0000000..c0a66c8 --- /dev/null +++ b/arch/arm64/include/asm/exttable.h @@ -0,0 +1,21 @@ +#ifndef __ASM_EXTTABLE_H +#define __ASM_EXTTABLE_H + +#include + +#define ARCH_HAS_RELATIVE_EXTABLE + +#define _ASM_EXTABLE(from, to) \ + " .pushsection __ex_table, \"a\"\n" \ + " .align 3\n" \ + " .long (" #from " - .), (" #to " - .)\n" \ + " .popsection\n" + +struct exception_table_entry +{ + int insn, fixup; +}; + +extern int fixup_exception(struct pt_regs *regs); + +#endif /* __ASM_EXTTABLE_H */ diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 0685d74..19cfdc5 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -48,15 +48,6 @@ * on our cache or tlb entries. */ -struct exception_table_entry -{ - int insn, fixup; -}; - -#define ARCH_HAS_RELATIVE_EXTABLE - -extern int fixup_exception(struct pt_regs *regs); - #define KERNEL_DS (-1UL) #define get_ds() (KERNEL_DS) @@ -117,12 +108,6 @@ static inline void set_fs(mm_segment_t fs) #define access_ok(type, addr, size) __range_ok(addr, size) #define user_addr_max get_fs -#define _ASM_EXTABLE(from, to) \ - " .pushsection __ex_table, \"a\"\n" \ - " .align 3\n" \ - " .long (" #from " - .), (" #to " - .)\n" \ - " .popsection\n" - /* * The "__xxx" versions of the user access functions do not verify the address * space - it must have been done previously with a separate "access_ok()" diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 1f7a145..6b88096 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -377,7 +377,8 @@ el1_undef: */ enable_dbg mov x0, sp - b do_undefinstr + bl do_undefinstr + kernel_exit 1 el1_dbg: /* * Debug exception handling diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index cacd30a..515444a 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -386,6 +386,12 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if (call_undef_hook(regs) == 0) return; + /* + * Are we prepared to handle this kernel fault? + */ + if (fixup_exception(regs)) + return; + if (unhandled_signal(current, SIGILL) && show_unhandled_signals_ratelimited()) { pr_info("%s[%d]: undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c index 81acd47..c140688 100644 --- a/arch/arm64/mm/extable.c +++ b/arch/arm64/mm/extable.c @@ -3,7 +3,7 @@ */ #include -#include +#include int fixup_exception(struct pt_regs *regs) {