From patchwork Wed Dec 23 04:16:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Gardner X-Patchwork-Id: 560346 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 2CEF3140B99 for ; Wed, 23 Dec 2015 15:16:20 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755062AbbLWEQT (ORCPT ); Tue, 22 Dec 2015 23:16:19 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:51153 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752970AbbLWEQS (ORCPT ); Tue, 22 Dec 2015 23:16:18 -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 tBN4GHXR012189 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Wed, 23 Dec 2015 04:16:18 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 tBN4GHqj028581; Wed, 23 Dec 2015 04:16:17 GMT From: Rob Gardner To: sparclinux@vger.kernel.org Cc: Rob Gardner , Dave Aldridge Subject: [PATCH 1/2] sparc64: Ensure perf can access user stacks Date: Tue, 22 Dec 2015 21:16:06 -0700 Message-Id: <1450844167-7327-1-git-send-email-rob.gardner@oracle.com> X-Mailer: git-send-email 1.7.9.5 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 When an interrupt (such as a perf counter interrupt) is delivered while executing in user space, the trap entry code puts ASI_AIUS in %asi so that copy_from_user() and copy_to_user() will access the correct memory. But if a perf counter interrupt is delivered while the cpu is already executing in kernel space, then the trap entry code will put ASI_P in %asi, and this will prevent copy_from_user() from reading any useful stack data in either of the perf_callchain_user_X functions, and thus no user callgraph data will be collected for this sample period. An additional problem is that a fault is guaranteed to occur, and though it will be silently covered up, it wastes time and could perturb state. In perf_callchain_user(), we ensure that %asi contains ASI_AIUS because we know for a fact that the subsequent calls to copy_from_user() are intended to read the user's stack. Signed-off-by: Rob Gardner Signed-off-by: Dave Aldridge --- arch/sparc/kernel/perf_event.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 689db65..55a6caa 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1810,11 +1810,19 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) { + u8 saved_asi; + perf_callchain_store(entry, regs->tpc); if (!current->mm) return; + /* ensure we get user memory when trying to read stacks */ + __asm__ __volatile__ ("rd %%asi, %0\n" : "=r" (saved_asi)); + if (saved_asi != ASI_AIUS) + __asm__ __volatile__ ( + "wr %%g0, %0, %%asi\n" : : "i" (ASI_AIUS)); + flushw_user(); pagefault_disable(); @@ -1825,4 +1833,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) perf_callchain_user_64(entry, regs); pagefault_enable(); + + if (saved_asi != ASI_AIUS) + __asm__ __volatile__ ( + "wr %%g0, %0, %%asi\n" : : "r" (saved_asi)); }