Received: by 10.223.176.5 with SMTP id f5csp2518913wra; Mon, 5 Feb 2018 05:32:07 -0800 (PST) X-Google-Smtp-Source: AH8x2277XI2jn/r0W72YvLNTljbfY2dy0oV/M+ASs2VLIImOKaDoTU55IUboJba1Y3LMhlD8ArWw X-Received: by 2002:a17:902:bd84:: with SMTP id q4-v6mr34504684pls.247.1517837527389; Mon, 05 Feb 2018 05:32:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517837527; cv=none; d=google.com; s=arc-20160816; b=UnGz56hQ9IiZ9TGGTPD70BjxId3+76VfAQwkozAjW70J03ATXBG3cB7X37d0QsDZEe oNf5qjNNzxMi37Lhhg2B52Bh83Ilqrfc5Dz8gbEGum769IEsS6fWQ6KMaL56qVXtUOeP 3vFnpKSwThPRHpHDgOJl12b5jbdciAP9JA6KHGCJJOQWLuit+52IA7Zwjk9hm7hLYl+r ZR96LbvKRTag+ygxovnxe3BEJ06KHeP+v54j51M24vDZ9EZlbo+SaDF/aHwAJwgAis0W rt9lSoctEXZVAUSGaDrgdM3PZGwKX0WioD530xm7vly3Cw6cM5CmLPOG7hHhlgixB7JX AgJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=PKd6XTBCgk5YA53rCZ88Y/DDz62x/WWsWPlPnwb2YII=; b=WaVNhQI4Dfa/ejOhubCwWxFuuqvr/rYiEIUnhvLUIZrkNbY6A4byNbU1LqxS0IJ85G PSiIQVLr+/yfS+D8BU8vPnL/NYDuAFxAB94Db+5IEsSNBTifuHRKl9FirBxJlYdZgaPF CVJ/q59Aon+TIg742tB8voc3mgbWhZ4VI60cy46wiSznULtVXTmkuhdQVdm1MzPcN3y5 +e+MifvNgDkyc1uF9QtFia1XtyedoK2UDyw/wHOURIBNEDZn0gnfZHIarc7CPai8F5Bi iRHJzwDKQ0nJqIY5dB1B2rFfwkngoFtLXhiIJ/F6a5nSjlcTTXILtU4NmdZQgZjWsHQZ lNRg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d4si5405489pgf.231.2018.02.05.05.31.40; Mon, 05 Feb 2018 05:32:07 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752848AbeBEN2M (ORCPT + 99 others); Mon, 5 Feb 2018 08:28:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38030 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752316AbeBEN2F (ORCPT ); Mon, 5 Feb 2018 08:28:05 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D3D9B28217; Mon, 5 Feb 2018 13:28:04 +0000 (UTC) Received: from localhost.localdomain (unknown [10.43.17.250]) by smtp.corp.redhat.com (Postfix) with SMTP id 84F1419F08; Mon, 5 Feb 2018 13:28:02 +0000 (UTC) Received: by localhost.localdomain (sSMTP sendmail emulation); Mon, 05 Feb 2018 14:28:01 +0100 From: "Jerome Marchand" To: linux-arm-kernel@lists.infradead.org Cc: Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org, Pratyush Anand , Jerome Marchand Subject: [PATCH v4] arm64: fix unwind_frame() for filtered out fn for function graph tracing Date: Mon, 5 Feb 2018 14:28:01 +0100 Message-Id: <20180205132801.7442-1-jmarchan@redhat.com> In-Reply-To: <20180112104832.9417-1-jmarchan@redhat.com> References: <20180112104832.9417-1-jmarchan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 05 Feb 2018 13:28:04 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Pratyush Anand Change since v3: - Exit unwind_frame() if frame->graph != -1 Change since v2: - Set frame.graph = current->curr_ret_stack in profile_pc - Check that frame->graph != -1 in unwind_frame do_task_stat() calls get_wchan(), which further does unwind_frame(). unwind_frame() restores frame->pc to original value in case function graph tracer has modified a return address (LR) in a stack frame to hook a function return. However, if function graph tracer has hit a filtered function, then we can't unwind it as ftrace_push_return_trace() has biased the index(frame->graph) with a 'huge negative' offset(-FTRACE_NOTRACE_DEPTH). Moreover, arm64 stack walker defines index(frame->graph) as unsigned int, which can not compare a -ve number. Similar problem we can have with calling of walk_stackframe() from save_stack_trace_tsk() or dump_backtrace(). This patch fixes unwind_frame() to test the index for -ve value and restore index accordingly before we can restore frame->pc. Reproducer: cd /sys/kernel/debug/tracing/ echo schedule > set_graph_notrace echo 1 > options/display-graph echo wakeup > current_tracer ps -ef | grep -i agent Above commands result in: Unable to handle kernel paging request at virtual address ffff801bd3d1e000 pgd = ffff8003cbe97c00 [ffff801bd3d1e000] *pgd=0000000000000000, *pud=0000000000000000 Internal error: Oops: 96000006 [#1] SMP [...] CPU: 5 PID: 11696 Comm: ps Not tainted 4.11.0+ #33 [...] task: ffff8003c21ba000 task.stack: ffff8003cc6c0000 PC is at unwind_frame+0x12c/0x180 LR is at get_wchan+0xd4/0x134 pc : [] lr : [] pstate: 60000145 sp : ffff8003cc6c3ab0 x29: ffff8003cc6c3ab0 x28: 0000000000000001 x27: 0000000000000026 x26: 0000000000000026 x25: 00000000000012d8 x24: 0000000000000000 x23: ffff8003c1c04000 x22: ffff000008c83000 x21: ffff8003c1c00000 x20: 000000000000000f x19: ffff8003c1bc0000 x18: 0000fffffc593690 x17: 0000000000000000 x16: 0000000000000001 x15: 0000b855670e2b60 x14: 0003e97f22cf1d0f x13: 0000000000000001 x12: 0000000000000000 x11: 00000000e8f4883e x10: 0000000154f47ec8 x9 : 0000000070f367c0 x8 : 0000000000000000 x7 : 00008003f7290000 x6 : 0000000000000018 x5 : 0000000000000000 x4 : ffff8003c1c03cb0 x3 : ffff8003c1c03ca0 x2 : 00000017ffe80000 x1 : ffff8003cc6c3af8 x0 : ffff8003d3e9e000 Process ps (pid: 11696, stack limit = 0xffff8003cc6c0000) Stack: (0xffff8003cc6c3ab0 to 0xffff8003cc6c4000) [...] [] unwind_frame+0x12c/0x180 [] do_task_stat+0x864/0x870 [] proc_tgid_stat+0x3c/0x48 [] proc_single_show+0x5c/0xb8 [] seq_read+0x160/0x414 [] __vfs_read+0x58/0x164 [] vfs_read+0x88/0x144 [] SyS_read+0x60/0xc0 [] __sys_trace_return+0x0/0x4 fixes: 20380bb390a4 (arm64: ftrace: fix a stack tracer's output under function graph tracer) Signed-off-by: Pratyush Anand Signed-off-by: Jerome Marchand --- arch/arm64/include/asm/stacktrace.h | 2 +- arch/arm64/kernel/stacktrace.c | 7 +++++++ arch/arm64/kernel/time.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 6ad30776e984..99390755c0c4 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -27,7 +27,7 @@ struct stackframe { unsigned long fp; unsigned long pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER - unsigned int graph; + int graph; #endif }; diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 76809ccd309c..2c74ff76b0cd 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -59,6 +59,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) #ifdef CONFIG_FUNCTION_GRAPH_TRACER if (tsk->ret_stack && (frame->pc == (unsigned long)return_to_handler)) { + if (frame->graph == -1) { + WARN_ON(1); + return -EINVAL; + } + if (frame->graph < -1) + frame->graph += FTRACE_NOTRACE_DEPTH; + /* * This is a case where function graph tracer has * modified a return address (LR) in a stack frame diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c index a4391280fba9..f258636273c9 100644 --- a/arch/arm64/kernel/time.c +++ b/arch/arm64/kernel/time.c @@ -52,7 +52,7 @@ unsigned long profile_pc(struct pt_regs *regs) frame.fp = regs->regs[29]; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER - frame.graph = -1; /* no task info */ + frame.graph = current->curr_ret_stack; #endif do { int ret = unwind_frame(NULL, &frame); -- 2.13.6