From patchwork Wed Dec 23 04:16:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Gardner X-Patchwork-Id: 560347 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id EC34D140B99 for ; Wed, 23 Dec 2015 15:16:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755549AbbLWEQc (ORCPT ); Tue, 22 Dec 2015 23:16:32 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:51201 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755034AbbLWEQc (ORCPT ); Tue, 22 Dec 2015 23:16:32 -0500 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tBN4GVH3012285 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Wed, 23 Dec 2015 04:16:31 GMT Received: from localhost.localdomain (dhcp-amer-vpn-rmdc-anyconnect-10-159-114-231.vpn.oracle.com [10.159.114.231]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tBN4GHqk028581; Wed, 23 Dec 2015 04:16:31 GMT From: Rob Gardner To: sparclinux@vger.kernel.org Cc: Rob Gardner , Dave Aldridge Subject: [PATCH 2/2] sparc64: Perf should save/restore fault info Date: Tue, 22 Dec 2015 21:16:07 -0700 Message-Id: <1450844167-7327-2-git-send-email-rob.gardner@oracle.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1450844167-7327-1-git-send-email-rob.gardner@oracle.com> References: <1450844167-7327-1-git-send-email-rob.gardner@oracle.com> X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org There have been several reports of random processes being killed with a bus error or segfault during userspace stack walking in perf. One of the root causes of this problem is an asynchronous modification to thread_info fault_address and fault_code, which stems from a perf counter interrupt arriving during kernel processing of a "benign" fault, such as a TSB miss. Since perf_callchain_user() invokes copy_from_user() to read user stacks, a fault is not only possible, but probable. Validity checks on the stack address merely cover up the problem and reduce its frequency. The solution here is to save and restore fault_address and fault_code in perf_callchain_user() so that the benign fault handler is not disturbed by a perf interrupt. Signed-off-by: Rob Gardner Signed-off-by: Dave Aldridge --- arch/sparc/kernel/perf_event.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 55a6caa..cb20d34 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1810,6 +1810,8 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) { + u64 saved_fault_address = current_thread_info()->fault_address; + u8 saved_fault_code = get_thread_fault_code(); u8 saved_asi; perf_callchain_store(entry, regs->tpc); @@ -1837,4 +1839,6 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) if (saved_asi != ASI_AIUS) __asm__ __volatile__ ( "wr %%g0, %0, %%asi\n" : : "r" (saved_asi)); + set_thread_fault_code(saved_fault_code); + current_thread_info()->fault_address = saved_fault_address; }