From patchwork Mon Feb 3 18:18:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean Pihet X-Patchwork-Id: 24061 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f72.google.com (mail-oa0-f72.google.com [209.85.219.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 21056202B2 for ; Mon, 3 Feb 2014 18:18:49 +0000 (UTC) Received: by mail-oa0-f72.google.com with SMTP id i4sf32120617oah.11 for ; Mon, 03 Feb 2014 10:18:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=lJb5jQX/g8u65cHRtQUh6mzFTIKYW14X3Dm8annCSQ8=; b=lP7gFtUNUGcO1Dm4GpPXLAtlaOYTA2W+j9pbzNCsfPy12prLaBiqSJKuVKThRHjI7D Q0MLBLEG6rjv3rUdYhBbWzEB05DknREtlVyMps9gSRKKBB9FUHkejCbUCk+cloc8Mdr1 /LlosWd+mCmdYiz7jSL0S7pZcN4DH1NIKGv7SejKhlxbT8G6hCVyHKOQaOAkXXt5zQ6K eXhN4Dpdm2nYWnEYDkNEYNbfIag40DF6MEzIyBEXbAtmf9CofZgZQjWBqTG4Tso1Qbg3 gzp4b7rLZqeLBqDPNeOLwE/8lLFSg3+U1XUEjs5cTw+kYdoHnTQe7llP0yjLWhPg+B1u OekA== X-Gm-Message-State: ALoCoQnFbxhsd1qVs8zwqNW7JzkrxRrkKr/2ksAu8nitSsceExEATzeGuhU5g1bkPPIHXq+98AS6 X-Received: by 10.182.126.137 with SMTP id my9mr14688457obb.13.1391451528023; Mon, 03 Feb 2014 10:18:48 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.46.98 with SMTP id j89ls1943660qga.73.gmail; Mon, 03 Feb 2014 10:18:47 -0800 (PST) X-Received: by 10.58.146.5 with SMTP id sy5mr192730veb.43.1391451527836; Mon, 03 Feb 2014 10:18:47 -0800 (PST) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by mx.google.com with ESMTPS id xn9si7076747vcb.41.2014.02.03.10.18.47 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 03 Feb 2014 10:18:47 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.169; Received: by mail-vc0-f169.google.com with SMTP id hq11so5141738vcb.0 for ; Mon, 03 Feb 2014 10:18:47 -0800 (PST) X-Received: by 10.52.247.168 with SMTP id yf8mr147835vdc.65.1391451527545; Mon, 03 Feb 2014 10:18:47 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp174316vcz; Mon, 3 Feb 2014 10:18:46 -0800 (PST) X-Received: by 10.14.221.129 with SMTP id r1mr82321eep.113.1391451526227; Mon, 03 Feb 2014 10:18:46 -0800 (PST) Received: from mail-ea0-f169.google.com (mail-ea0-f169.google.com [209.85.215.169]) by mx.google.com with ESMTPS id x43si37131001eey.187.2014.02.03.10.18.45 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 03 Feb 2014 10:18:46 -0800 (PST) Received-SPF: neutral (google.com: 209.85.215.169 is neither permitted nor denied by best guess record for domain of jean.pihet@linaro.org) client-ip=209.85.215.169; Received: by mail-ea0-f169.google.com with SMTP id h10so3954338eak.0 for ; Mon, 03 Feb 2014 10:18:45 -0800 (PST) X-Received: by 10.14.241.142 with SMTP id g14mr45468023eer.40.1391451525747; Mon, 03 Feb 2014 10:18:45 -0800 (PST) Received: from localhost.localdomain (193.52-245-81.adsl-dyn.isp.belgacom.be. [81.245.52.193]) by mx.google.com with ESMTPSA id k41sm67692577een.19.2014.02.03.10.18.43 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 03 Feb 2014 10:18:45 -0800 (PST) From: Jean Pihet To: linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org, linux-arm-kernel@lists.infradead.org, Will Deacon Cc: Arnaldo , Ingo Molnar , Jiri Olsa , patches@linaro.org, Jean Pihet Subject: [PATCH 2/3] ARM64: perf: add support for frame pointer unwinding in compat mode Date: Mon, 3 Feb 2014 19:18:28 +0100 Message-Id: <1391451509-31265-3-git-send-email-jean.pihet@linaro.org> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1391451509-31265-1-git-send-email-jean.pihet@linaro.org> References: <1391451509-31265-1-git-send-email-jean.pihet@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: jean.pihet@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When profiling a 32-bit application, user space callchain unwinding using the frame pointer is performed in compat mode. The code is taken over from the AARCH32 code and adapted to work on AARCH64. Signed-off-by: Jean Pihet Acked-by: Will Deacon --- arch/arm64/kernel/perf_event.c | 75 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 5b1cd79..e868c72 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1348,8 +1348,8 @@ early_initcall(init_hw_perf_events); * Callchain handling code. */ struct frame_tail { - struct frame_tail __user *fp; - unsigned long lr; + struct frame_tail __user *fp; + unsigned long lr; } __attribute__((packed)); /* @@ -1386,22 +1386,80 @@ user_backtrace(struct frame_tail __user *tail, return buftail.fp; } +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct compat_frame_tail *)(xxx->fp)-1 + * + * This code has been adapted from the ARM OProfile support. + */ +struct compat_frame_tail { + compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */ + u32 sp; + u32 lr; +} __attribute__((packed)); + +static struct compat_frame_tail __user * +compat_user_backtrace(struct compat_frame_tail __user *tail, + struct perf_callchain_entry *entry) +{ + struct compat_frame_tail buftail; + unsigned long err; + + /* Also check accessibility of one struct frame_tail beyond */ + if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) + return NULL; + + pagefault_disable(); + err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail)); + pagefault_enable(); + + if (err) + return NULL; + + perf_callchain_store(entry, buftail.lr); + + /* + * Frame pointers should strictly progress back up the stack + * (towards higher addresses). + */ + if (tail + 1 >= (struct compat_frame_tail __user *) + compat_ptr(buftail.fp)) + return NULL; + + return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1; +} + void perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) { - struct frame_tail __user *tail; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } perf_callchain_store(entry, regs->pc); - tail = (struct frame_tail __user *)regs->regs[29]; - while (entry->nr < PERF_MAX_STACK_DEPTH && - tail && !((unsigned long)tail & 0xf)) - tail = user_backtrace(tail, entry); + if (!compat_user_mode(regs)) { + /* AARCH64 mode */ + struct frame_tail __user *tail; + + tail = (struct frame_tail __user *)regs->regs[29]; + + while (entry->nr < PERF_MAX_STACK_DEPTH && + tail && !((unsigned long)tail & 0xf)) + tail = user_backtrace(tail, entry); + } else { + /* AARCH32 compat mode */ + struct compat_frame_tail __user *tail; + + tail = (struct compat_frame_tail __user *)regs->compat_fp - 1; + + while ((entry->nr < PERF_MAX_STACK_DEPTH) && + tail && !((unsigned long)tail & 0x3)) + tail = compat_user_backtrace(tail, entry); + } } /* @@ -1429,6 +1487,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, frame.fp = regs->regs[29]; frame.sp = regs->sp; frame.pc = regs->pc; + walk_stackframe(&frame, callchain_trace, entry); }