From patchwork Tue Jun 6 01:45:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Yan X-Patchwork-Id: 13268147 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 72F50C7EE24 for ; Tue, 6 Jun 2023 01:47:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=RIVyfTS6/ZIlP2kNJKKyabqkS0ogKqM2QzQRXL+fWQ8=; b=G0tR9WEwGYL8fa mm59qF4F3vCO06U9jWkpVA6wJGLc3Rukig+kYgBbDbXGwBsSs61vXxaUrLDORJ4sfSzLdESrCcPLY wiRGfN4iPfDpytaINNlmYsymkOlvcM8SxEpiLdXt9hiEJwgGGIpnukPs7kxaghtx85p4ZCaDlS5s3 OJS+jQnbFAYWUZnJh14UYPmRqgTWZAVWGroUUH3aKRnS7PgtquxCt6JYeSX2A523JMNTomdFHjtD/ xCXN+DbpG13rzgQE6K8cU5lGdwdpl2buYZ6WBYz2AXYHoeRC/rzIh3ZYNKxFGdMFfd8SdmRF/k/hj CbC7Ncvm68FczLLvxIZA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q6Lma-00HMWM-0g; Tue, 06 Jun 2023 01:46:48 +0000 Received: from mail-yw1-x1132.google.com ([2607:f8b0:4864:20::1132]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q6LmW-00HMTL-39 for linux-arm-kernel@lists.infradead.org; Tue, 06 Jun 2023 01:46:47 +0000 Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-568a1011488so60744087b3.0 for ; Mon, 05 Jun 2023 18:46:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1686016003; x=1688608003; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hEUFNMzfqFzxFoJd7U1v/KQDElpKa5YtXy/vXslzPbA=; b=LA9N6eC3cyCwTKRQ4W5MpfBUJWmmUbHbV+FJ03f8x/kD7xCpL9FrNObUCWAOHz0bIP hg3+oDXGhm2PSAdyTZLnE4OalEdP94UHCw3+9v/6mI5ZJd6gCIFbuju0hUisUKKQGIZp Pfm/MYWXvbmNQVEb+6yj9DBAKzpaNzrIul++AW9r3l60OYl80UttFvJrHTLz2n2RHnZj a8DruiAPI5/ehkUzO1EDjl8DMkSVtJFUrOMRPsSXcCNymW6i1HWYV3cG8L8N22mmp92m t/VbIvBeyojx5/Q7/IWIBvCu2XXGo7cmldR/YSFUNoFxfQ7528CYGxoWHXN1Feh6vylu 4FiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686016003; x=1688608003; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hEUFNMzfqFzxFoJd7U1v/KQDElpKa5YtXy/vXslzPbA=; b=PLaVpjtMPAFd/CzUeet8UCdQNKF70/NB/NczWITq26TbDWVN7uX6/Ub2D9JjvFR+iD TYuFTdThNJbFTmWbHH/4ko01d78qR/0RjzcV02h/f6XGbEKw2KNLO/tEmiEDwK+bvTjn qAHA2UwOvyVy3kAaBU/LYYQ7pBwTdm4CcMMtd/nKnjo73m9wbWmFGFIB+kww7e/IYavE V5dt6mHURpxEufanNtGdfexAO4pU95caSsOOBOguB80JefaKkgq/VlIJ+kHNW+6g0gIU CCd5I1ISiGvxJoLxyRc+Mpfq5JmlYoW84riF52kKCLbTjg3XKTBQQtZYHItTrgxqEoLJ KLwQ== X-Gm-Message-State: AC+VfDwOXBFGBCukbDDx71GxUTRLTTfWGLM2ye1lOpgVoyIu4INlCsow Yfswjq1VqtKDvy5SdbNPsNTqJQ== X-Google-Smtp-Source: ACHHUZ7maH3siosah4nPbJbjCHedUNuOhM+xAOF1/WJ25pQnl9KDQ8bh56nVXlW/wMvVZL77G0B1fQ== X-Received: by 2002:a81:4e58:0:b0:568:fdc2:5af7 with SMTP id c85-20020a814e58000000b00568fdc25af7mr288740ywb.50.1686016002707; Mon, 05 Jun 2023 18:46:42 -0700 (PDT) Received: from leoy-huanghe.lan ([240e:389:8603:ad00:6600:a29f:6ab:1788]) by smtp.gmail.com with ESMTPSA id s10-20020a170902a50a00b001a64851087bsm7197805plq.272.2023.06.05.18.46.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Jun 2023 18:46:42 -0700 (PDT) From: Leo Yan To: Arnaldo Carvalho de Melo , John Garry , Will Deacon , James Clark , Mike Leach , Peter Zijlstra , Ingo Molnar , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Guo Ren , Paul Walmsley , Palmer Dabbelt , Albert Ou , Huacai Chen , Ming Wang , Eric Lin , Kan Liang , Sandipan Das , Ivan Babrou , Fangrui Song , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-csky@vger.kernel.org, linux-riscv@lists.infradead.org Cc: Leo Yan Subject: [PATCH v2 2/6] perf parse-regs: Introduce functions perf_arch_reg_{ip|sp}() Date: Tue, 6 Jun 2023 09:45:55 +0800 Message-Id: <20230606014559.21783-3-leo.yan@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230606014559.21783-1-leo.yan@linaro.org> References: <20230606014559.21783-1-leo.yan@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230605_184645_025403_CCCC261B X-CRM114-Status: GOOD ( 19.82 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The current code uses macros PERF_REG_IP and PERF_REG_SP for parsing registers and we build perf with these macros statically, which means it only can correctly analyze CPU registers for the native architecture and fails to support cross analysis (e.g. we build perf on x86 and cannot analyze Arm64's registers). We need to generalize util/perf_regs.c for support multi architectures, as a first step, this commit introduces new functions perf_arch_reg_ip() and perf_arch_reg_sp(), these two functions dynamically return IP and SP register index respectively according to the parameter "arch". Every architecture has its own functions (like __perf_reg_ip_arm64 and __perf_reg_sp_arm64), these architecture specific functions are defined in each arch source file under folder util/perf-regs-arch; at the end all of them are built into the tool for cross analysis. Signed-off-by: Leo Yan --- tools/perf/util/evsel.c | 6 ++- .../util/perf-regs-arch/perf_regs_aarch64.c | 10 ++++ .../perf/util/perf-regs-arch/perf_regs_arm.c | 10 ++++ .../perf/util/perf-regs-arch/perf_regs_csky.c | 10 ++++ .../util/perf-regs-arch/perf_regs_loongarch.c | 10 ++++ .../perf/util/perf-regs-arch/perf_regs_mips.c | 10 ++++ .../util/perf-regs-arch/perf_regs_powerpc.c | 10 ++++ .../util/perf-regs-arch/perf_regs_riscv.c | 10 ++++ .../perf/util/perf-regs-arch/perf_regs_s390.c | 10 ++++ .../perf/util/perf-regs-arch/perf_regs_x86.c | 10 ++++ tools/perf/util/perf_regs.c | 52 +++++++++++++++++++ tools/perf/util/perf_regs.h | 36 ++++++++++++- 12 files changed, 180 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 46da3f0bb47e..dfba2bc79cfc 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -844,6 +844,7 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o { bool function = evsel__is_function_event(evsel); struct perf_event_attr *attr = &evsel->core.attr; + const char *arch = perf_env__arch(evsel__env(evsel)); evsel__set_sample_bit(evsel, CALLCHAIN); @@ -876,8 +877,9 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o if (!function) { evsel__set_sample_bit(evsel, REGS_USER); evsel__set_sample_bit(evsel, STACK_USER); - if (opts->sample_user_regs && DWARF_MINIMAL_REGS != PERF_REGS_MASK) { - attr->sample_regs_user |= DWARF_MINIMAL_REGS; + if (opts->sample_user_regs && + DWARF_MINIMAL_REGS(arch) != PERF_REGS_MASK) { + attr->sample_regs_user |= DWARF_MINIMAL_REGS(arch); pr_warning("WARNING: The use of --call-graph=dwarf may require all the user registers, " "specifying a subset with --user-regs may render DWARF unwinding unreliable, " "so the minimal registers set (IP, SP) is explicitly forced.\n"); diff --git a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c index c02c045af46e..696566c54768 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c @@ -83,4 +83,14 @@ const char *__perf_reg_name_arm64(int id) return NULL; } +uint64_t __perf_reg_ip_arm64(void) +{ + return PERF_REG_ARM64_PC; +} + +uint64_t __perf_reg_sp_arm64(void) +{ + return PERF_REG_ARM64_SP; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_arm.c b/tools/perf/util/perf-regs-arch/perf_regs_arm.c index e8b0fcd72f34..700fd07cd2aa 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_arm.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_arm.c @@ -47,4 +47,14 @@ const char *__perf_reg_name_arm(int id) return NULL; } +uint64_t __perf_reg_ip_arm(void) +{ + return PERF_REG_ARM_PC; +} + +uint64_t __perf_reg_sp_arm(void) +{ + return PERF_REG_ARM_SP; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_csky.c b/tools/perf/util/perf-regs-arch/perf_regs_csky.c index e343b1cef7ba..a2841094e096 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_csky.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_csky.c @@ -87,4 +87,14 @@ const char *__perf_reg_name_csky(int id) return NULL; } +uint64_t __perf_reg_ip_csky(void) +{ + return PERF_REG_CSKY_PC; +} + +uint64_t __perf_reg_sp_csky(void) +{ + return PERF_REG_CSKY_SP; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c index 6f937464067b..a9ba0f934123 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c @@ -78,4 +78,14 @@ const char *__perf_reg_name_loongarch(int id) return NULL; } +uint64_t __perf_reg_ip_loongarch(void) +{ + return PERF_REG_LOONGARCH_PC; +} + +uint64_t __perf_reg_sp_loongarch(void) +{ + return PERF_REG_LOONGARCH_R3; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_mips.c b/tools/perf/util/perf-regs-arch/perf_regs_mips.c index f48fbca2f947..5a45830cfbf5 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_mips.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_mips.c @@ -74,4 +74,14 @@ const char *__perf_reg_name_mips(int id) return NULL; } +uint64_t __perf_reg_ip_mips(void) +{ + return PERF_REG_MIPS_PC; +} + +uint64_t __perf_reg_sp_mips(void) +{ + return PERF_REG_MIPS_R29; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c index dda1b4b169fc..1f0d682db74a 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c @@ -132,4 +132,14 @@ const char *__perf_reg_name_powerpc(int id) return NULL; } +uint64_t __perf_reg_ip_powerpc(void) +{ + return PERF_REG_POWERPC_NIP; +} + +uint64_t __perf_reg_sp_powerpc(void) +{ + return PERF_REG_POWERPC_R1; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c index c504b047cac2..e432630be4c5 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c @@ -79,4 +79,14 @@ const char *__perf_reg_name_riscv(int id) return NULL; } +uint64_t __perf_reg_ip_riscv(void) +{ + return PERF_REG_RISCV_PC; +} + +uint64_t __perf_reg_sp_riscv(void) +{ + return PERF_REG_RISCV_SP; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_s390.c b/tools/perf/util/perf-regs-arch/perf_regs_s390.c index e71e2302394c..1c7a46db778c 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_s390.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_s390.c @@ -83,4 +83,14 @@ const char *__perf_reg_name_s390(int id) return NULL; } +uint64_t __perf_reg_ip_s390(void) +{ + return PERF_REG_S390_PC; +} + +uint64_t __perf_reg_sp_s390(void) +{ + return PERF_REG_S390_R15; +} + #endif diff --git a/tools/perf/util/perf-regs-arch/perf_regs_x86.c b/tools/perf/util/perf-regs-arch/perf_regs_x86.c index eb5d249afa70..873c620f0634 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_x86.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_x86.c @@ -85,4 +85,14 @@ const char *__perf_reg_name_x86(int id) return NULL; } +uint64_t __perf_reg_ip_x86(void) +{ + return PERF_REG_X86_IP; +} + +uint64_t __perf_reg_sp_x86(void) +{ + return PERF_REG_X86_SP; +} + #endif diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index 5af1b95c3d01..23584efd4886 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -3,6 +3,7 @@ #include #include "perf_regs.h" #include "util/sample.h" +#include "debug.h" int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, char **new_op __maybe_unused) @@ -74,4 +75,55 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) *valp = regs->cache_regs[id]; return 0; } + +uint64_t perf_arch_reg_ip(const char *arch) +{ + if (!strcmp(arch, "arm")) + return __perf_reg_ip_arm(); + else if (!strcmp(arch, "arm64")) + return __perf_reg_ip_arm64(); + else if (!strcmp(arch, "csky")) + return __perf_reg_ip_csky(); + else if (!strcmp(arch, "loongarch")) + return __perf_reg_ip_loongarch(); + else if (!strcmp(arch, "mips")) + return __perf_reg_ip_mips(); + else if (!strcmp(arch, "powerpc")) + return __perf_reg_ip_powerpc(); + else if (!strcmp(arch, "riscv")) + return __perf_reg_ip_riscv(); + else if (!strcmp(arch, "s390")) + return __perf_reg_ip_s390(); + else if (!strcmp(arch, "x86")) + return __perf_reg_ip_x86(); + + pr_err("Fail to find IP register for arch %s, returns 0\n", arch); + return 0; +} + +uint64_t perf_arch_reg_sp(const char *arch) +{ + if (!strcmp(arch, "arm")) + return __perf_reg_sp_arm(); + else if (!strcmp(arch, "arm64")) + return __perf_reg_sp_arm64(); + else if (!strcmp(arch, "csky")) + return __perf_reg_sp_csky(); + else if (!strcmp(arch, "loongarch")) + return __perf_reg_sp_loongarch(); + else if (!strcmp(arch, "mips")) + return __perf_reg_sp_mips(); + else if (!strcmp(arch, "powerpc")) + return __perf_reg_sp_powerpc(); + else if (!strcmp(arch, "riscv")) + return __perf_reg_sp_riscv(); + else if (!strcmp(arch, "s390")) + return __perf_reg_sp_s390(); + else if (!strcmp(arch, "x86")) + return __perf_reg_sp_x86(); + + pr_err("Fail to find SP register for arch %s, returns 0\n", arch); + return 0; +} + #endif diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 6b19a2867171..790c1a26bbfe 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -32,25 +32,46 @@ extern const struct sample_reg sample_reg_masks[]; #include -#define DWARF_MINIMAL_REGS ((1ULL << PERF_REG_IP) | (1ULL << PERF_REG_SP)) +#define DWARF_MINIMAL_REGS(arch) \ + ((1ULL << perf_arch_reg_ip(arch)) | (1ULL << perf_arch_reg_sp(arch))) const char *perf_reg_name(int id, const char *arch); int perf_reg_value(u64 *valp, struct regs_dump *regs, int id); +uint64_t perf_arch_reg_ip(const char *arch); +uint64_t perf_arch_reg_sp(const char *arch); const char *__perf_reg_name_arm64(int id); +uint64_t __perf_reg_ip_arm64(void); +uint64_t __perf_reg_sp_arm64(void); const char *__perf_reg_name_arm(int id); +uint64_t __perf_reg_ip_arm(void); +uint64_t __perf_reg_sp_arm(void); const char *__perf_reg_name_csky(int id); +uint64_t __perf_reg_ip_csky(void); +uint64_t __perf_reg_sp_csky(void); const char *__perf_reg_name_loongarch(int id); +uint64_t __perf_reg_ip_loongarch(void); +uint64_t __perf_reg_sp_loongarch(void); const char *__perf_reg_name_mips(int id); +uint64_t __perf_reg_ip_mips(void); +uint64_t __perf_reg_sp_mips(void); const char *__perf_reg_name_powerpc(int id); +uint64_t __perf_reg_ip_powerpc(void); +uint64_t __perf_reg_sp_powerpc(void); const char *__perf_reg_name_riscv(int id); +uint64_t __perf_reg_ip_riscv(void); +uint64_t __perf_reg_sp_riscv(void); const char *__perf_reg_name_s390(int id); +uint64_t __perf_reg_ip_s390(void); +uint64_t __perf_reg_sp_s390(void); const char *__perf_reg_name_x86(int id); +uint64_t __perf_reg_ip_x86(void); +uint64_t __perf_reg_sp_x86(void); #else #define PERF_REGS_MASK 0 #define PERF_REGS_MAX 0 -#define DWARF_MINIMAL_REGS PERF_REGS_MASK +#define DWARF_MINIMAL_REGS(arch) PERF_REGS_MASK static inline const char *perf_reg_name(int id __maybe_unused, const char *arch __maybe_unused) { @@ -63,5 +84,16 @@ static inline int perf_reg_value(u64 *valp __maybe_unused, { return 0; } + +static inline uint64_t perf_arch_reg_ip(const char *arch __maybe_unused) +{ + return 0; +} + +static inline uint64_t perf_arch_reg_sp(const char *arch __maybe_unused) +{ + return 0; +} + #endif /* HAVE_PERF_REGS_SUPPORT */ #endif /* __PERF_REGS_H */