From nobody Mon Feb 9 10:26:06 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0E8532E721 for ; Sat, 17 Jan 2026 05:29:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768627795; cv=none; b=rhhbZ4JPaysriMD9TPYD9n5CE4Yikt2Xtp9xkfvee9oJPpa2Q0ILS1xY3BlX0fqJ7RUfiW9Cd44klvWM34abOJoqLi10qZmHGjP9wXAe03PTXzx22MtCtqyssXlaLjSTlNKfRDrWxks0QPmyClMgDwEJGTDC+7+hYp9qvyT+c8M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768627795; c=relaxed/simple; bh=xvrfmRGwN50DWc39nR8IudM0hWgXMsfj7kakQ4UFT3A=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=C7aHjA7DbE49EKSFkSE789SpPtAYWDkAfKZG09xLRAvEttVVF15PBh9yPDZx3fd1qcuOWXnREHBd7Zn3pMDsopYTgmW1NrNUcs3AkapZVP0TyMIsaySKnVhQBjN80piaeGKO4J521AaQEVSp+6zFNBywDfH+VvzVTNWz4wExjoE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=mA56SJad; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="mA56SJad" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-11b9786fb51so17153205c88.1 for ; Fri, 16 Jan 2026 21:29:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1768627791; x=1769232591; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=iYVgloMaIeMWmcnEWxnIXuJDky8ZiRg8gWqhum1bLc0=; b=mA56SJadBdtnWOFIURo+7nIIjZWkzNXrCee1UXz2Fq4eC2RpjTBT83NLssGMd5dnv+ iyL58PCPxjLpnq5UvIJ88z5HyoYumi4jfKlEGeHGx1HZz/ar841mihn+UwkmAkqyirOF 46rAZy7HiH+kYza3WLNnGaHrLQ5pHnL2eTQZt1lgbe7sQQdSwOjsJNg3Tf3jKQFuK6kl 5gkGpNJPKuwXrt0SoLDf3b7ZH4WmlL/81+MkQ+zhYX1AfdRvz/tDwbw5Mvj3Pczw3ljh khe5n5b3y9a83pWEt5m1rWGhnc6KJ2jXj6O6oDz9nKq1t9SS56MWRH11lPYE8BNfEirB rsbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768627791; x=1769232591; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iYVgloMaIeMWmcnEWxnIXuJDky8ZiRg8gWqhum1bLc0=; b=lAwhKx8GITj7xumqUDCKHR5iPTLllZ0Q0QOa3q/k/MGIgEZSdvK3fm+m02rNSSQK9z SAxmj4qBUiMK8lwsZDuL4F8QMADLngiKQVjxyF+Qi7nSuY3A2GQ3RT7VIV4EZrIdPRr9 bKnMVYjmPxzTZUNNmlnbaMfXaW5chBzBlMkG5NRxKvcL4GCoqoHTsi37jEq5DpP3GzWa oQK3Xj/sAQamu/4b+0f1J+2FMgzrF8R1ZK9VwhZk6fhqktM3Kgo6MPpQIDhZb4m4eGF7 wx9qcpDgqFkyDiJWA30Ni/h8H3srWH9JgHIbVekKphIuC1izOcxea5ltoE4TLFaQn6gP k0Hw== X-Forwarded-Encrypted: i=1; AJvYcCVaeefUiiJKOVmHSlPxBWjDVjYp2LiINnwJqMXsBlotcMHk1uLD6zAPNzO2rCLBxLFlbPyGJc4CUjg8ZQo=@vger.kernel.org X-Gm-Message-State: AOJu0YwwYICdGvTfUhAoOLGUDNJ1pYUpX8LmaWG7dMXbpva70U+fdpry 9+TfVhQIZGVJZzY2TJOBQ9gXUEf6md2EUbPzYIhTdU0ogLvhEk8SrluPKXm3YJtHGbCx3W05iDY fQ0Sjv9fxHg== X-Received: from dlaj19.prod.google.com ([2002:a05:701b:2813:b0:119:49ca:6bae]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6990:b0:11f:2c69:32 with SMTP id a92af1059eb24-1244a717f0amr3961097c88.7.1768627790635; Fri, 16 Jan 2026 21:29:50 -0800 (PST) Date: Fri, 16 Jan 2026 21:28:43 -0800 In-Reply-To: <20260117052849.2205545-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260117052849.2205545-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260117052849.2205545-18-irogers@google.com> Subject: [PATCH v1 17/23] perf dwarf-regs: Add powerpc perf to dwarf register number mapping functions From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , John Garry , Will Deacon , Leo Yan , Guo Ren , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Shimin Guo , Athira Rajeev , Stephen Brennan , Howard Chu , Thomas Falcon , Andi Kleen , "Dr. David Alan Gilbert" , Dmitry Vyukov , "=?UTF-8?q?Krzysztof=20=C5=81opatowski?=" , Chun-Tse Shao , Aditya Bodkhe , Haibo Xu , Sergei Trofimovich , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-csky@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Wielaard Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" These functions allow the generic initial register state code in unwind-libdw to be used. Note, the link register was being coped to dwarf register 65 that the SysV ABI spec claims is FPSCR. It is corrected here to 108, but this is unlikely to matter as FPSCR has little to no impact on unwinding. Signed-off-by: Ian Rogers --- .../util/dwarf-regs-arch/dwarf-regs-powerpc.c | 77 ++++++++++++++++++- tools/perf/util/dwarf-regs.c | 4 + tools/perf/util/include/dwarf-regs.h | 1 + tools/perf/util/unwind-libdw-arch/Build | 1 - .../unwind-libdw-arch/unwind-libdw-powerpc.c | 76 ------------------ tools/perf/util/unwind-libdw.c | 5 +- tools/perf/util/unwind-libdw.h | 1 - 7 files changed, 82 insertions(+), 83 deletions(-) delete mode 100644 tools/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-powerpc.c b/tools/p= erf/util/dwarf-regs-arch/dwarf-regs-powerpc.c index caf77a234c78..51892a09725b 100644 --- a/tools/perf/util/dwarf-regs-arch/dwarf-regs-powerpc.c +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-powerpc.c @@ -4,8 +4,9 @@ * * Copyright (C) 2010 Ian Munsie, IBM Corporation. */ - +#include #include +#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h" =20 #define PPC_OP(op) (((op) >> 26) & 0x3F) #define PPC_RA(a) (((a) >> 16) & 0x1f) @@ -59,3 +60,77 @@ void get_powerpc_regs(u32 raw_insn, int is_source, if ((op_loc->mem_ref) && (PPC_OP(raw_insn) !=3D 31)) op_loc->offset =3D get_offset_opcode(raw_insn); } + +int __get_dwarf_regnum_for_perf_regnum_powerpc(int perf_regnum) +{ + static const int dwarf_powerpc_regnums[] =3D { + [PERF_REG_POWERPC_R0] =3D 0, + [PERF_REG_POWERPC_R1] =3D 1, + [PERF_REG_POWERPC_R2] =3D 2, + [PERF_REG_POWERPC_R3] =3D 3, + [PERF_REG_POWERPC_R4] =3D 4, + [PERF_REG_POWERPC_R5] =3D 5, + [PERF_REG_POWERPC_R6] =3D 6, + [PERF_REG_POWERPC_R7] =3D 7, + [PERF_REG_POWERPC_R8] =3D 8, + [PERF_REG_POWERPC_R9] =3D 9, + [PERF_REG_POWERPC_R10] =3D 10, + [PERF_REG_POWERPC_R11] =3D 11, + [PERF_REG_POWERPC_R12] =3D 12, + [PERF_REG_POWERPC_R13] =3D 13, + [PERF_REG_POWERPC_R14] =3D 14, + [PERF_REG_POWERPC_R15] =3D 15, + [PERF_REG_POWERPC_R16] =3D 16, + [PERF_REG_POWERPC_R17] =3D 17, + [PERF_REG_POWERPC_R18] =3D 18, + [PERF_REG_POWERPC_R19] =3D 19, + [PERF_REG_POWERPC_R20] =3D 20, + [PERF_REG_POWERPC_R21] =3D 21, + [PERF_REG_POWERPC_R22] =3D 22, + [PERF_REG_POWERPC_R23] =3D 23, + [PERF_REG_POWERPC_R24] =3D 24, + [PERF_REG_POWERPC_R25] =3D 25, + [PERF_REG_POWERPC_R26] =3D 26, + [PERF_REG_POWERPC_R27] =3D 27, + [PERF_REG_POWERPC_R28] =3D 28, + [PERF_REG_POWERPC_R29] =3D 29, + [PERF_REG_POWERPC_R30] =3D 30, + [PERF_REG_POWERPC_R31] =3D 31, + /* TODO: PERF_REG_POWERPC_NIP */ + [PERF_REG_POWERPC_MSR] =3D 66, + /* TODO: PERF_REG_POWERPC_ORIG_R3 */ + [PERF_REG_POWERPC_CTR] =3D 109, + [PERF_REG_POWERPC_LINK] =3D 108, /* Note, previously in perf encoded as = 65? */ + [PERF_REG_POWERPC_XER] =3D 101, + /* TODO: PERF_REG_POWERPC_CCR */ + /* TODO: PERF_REG_POWERPC_SOFTE */ + /* TODO: PERF_REG_POWERPC_TRAP */ + /* TODO: PERF_REG_POWERPC_DAR */ + /* TODO: PERF_REG_POWERPC_DSISR */ + /* TODO: PERF_REG_POWERPC_SIER */ + /* TODO: PERF_REG_POWERPC_MMCRA */ + /* TODO: PERF_REG_POWERPC_MMCR0 */ + /* TODO: PERF_REG_POWERPC_MMCR1 */ + /* TODO: PERF_REG_POWERPC_MMCR2 */ + /* TODO: PERF_REG_POWERPC_MMCR3 */ + /* TODO: PERF_REG_POWERPC_SIER2 */ + /* TODO: PERF_REG_POWERPC_SIER3 */ + /* TODO: PERF_REG_POWERPC_PMC1 */ + /* TODO: PERF_REG_POWERPC_PMC2 */ + /* TODO: PERF_REG_POWERPC_PMC3 */ + /* TODO: PERF_REG_POWERPC_PMC4 */ + /* TODO: PERF_REG_POWERPC_PMC5 */ + /* TODO: PERF_REG_POWERPC_PMC6 */ + /* TODO: PERF_REG_POWERPC_SDAR */ + /* TODO: PERF_REG_POWERPC_SIAR */ + }; + + if (perf_regnum =3D=3D 0) + return 0; + + if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_powerpc_regnu= ms) || + dwarf_powerpc_regnums[perf_regnum] =3D=3D 0) + return -ENOENT; + + return dwarf_powerpc_regnums[perf_regnum]; +} diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index 033218f14b36..3b1c2a436806 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -205,6 +205,10 @@ int get_dwarf_regnum_for_perf_regnum(int perf_regnum, = unsigned int machine, case EM_CSKY: reg =3D __get_dwarf_regnum_for_perf_regnum_csky(perf_regnum, flags); break; + case EM_PPC: + case EM_PPC64: + reg =3D __get_dwarf_regnum_for_perf_regnum_powerpc(perf_regnum); + break; case EM_LOONGARCH: reg =3D __get_dwarf_regnum_for_perf_regnum_loongarch(perf_regnum); break; diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include= /dwarf-regs.h index bec15fb53e73..9ebb3ba33fba 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -110,6 +110,7 @@ int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_r= egnum); =20 int __get_dwarf_regnum_for_perf_regnum_csky(int perf_regnum, unsigned int = flags); int __get_dwarf_regnum_for_perf_regnum_loongarch(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_powerpc(int perf_regnum); =20 /* * get_dwarf_regnum - Returns DWARF regnum from register name diff --git a/tools/perf/util/unwind-libdw-arch/Build b/tools/perf/util/unwi= nd-libdw-arch/Build index 62a4cbf2dca8..e6c97e842cd6 100644 --- a/tools/perf/util/unwind-libdw-arch/Build +++ b/tools/perf/util/unwind-libdw-arch/Build @@ -1,3 +1,2 @@ -perf-util-y +=3D unwind-libdw-powerpc.o perf-util-y +=3D unwind-libdw-riscv.o perf-util-y +=3D unwind-libdw-s390.o diff --git a/tools/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c b/too= ls/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c deleted file mode 100644 index 1560db45e7b4..000000000000 --- a/tools/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include "../arch/powerpc/include/uapi/asm/perf_regs.h" -#include "util/unwind-libdw.h" -#include "util/perf_regs.h" -#include "util/sample.h" - -/* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */ -static const int special_regs[3][2] =3D { - { 65, PERF_REG_POWERPC_LINK }, - { 101, PERF_REG_POWERPC_XER }, - { 109, PERF_REG_POWERPC_CTR }, -}; - -bool libdw_set_initial_registers_powerpc(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui =3D arg; - struct regs_dump *user_regs =3D perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[32], dwarf_nip; - size_t i; - -#define REG(r) ({ \ - Dwarf_Word val =3D 0; \ - perf_reg_value(&val, user_regs, PERF_REG_POWERPC_##r); \ - val; \ -}) - - dwarf_regs[0] =3D REG(R0); - dwarf_regs[1] =3D REG(R1); - dwarf_regs[2] =3D REG(R2); - dwarf_regs[3] =3D REG(R3); - dwarf_regs[4] =3D REG(R4); - dwarf_regs[5] =3D REG(R5); - dwarf_regs[6] =3D REG(R6); - dwarf_regs[7] =3D REG(R7); - dwarf_regs[8] =3D REG(R8); - dwarf_regs[9] =3D REG(R9); - dwarf_regs[10] =3D REG(R10); - dwarf_regs[11] =3D REG(R11); - dwarf_regs[12] =3D REG(R12); - dwarf_regs[13] =3D REG(R13); - dwarf_regs[14] =3D REG(R14); - dwarf_regs[15] =3D REG(R15); - dwarf_regs[16] =3D REG(R16); - dwarf_regs[17] =3D REG(R17); - dwarf_regs[18] =3D REG(R18); - dwarf_regs[19] =3D REG(R19); - dwarf_regs[20] =3D REG(R20); - dwarf_regs[21] =3D REG(R21); - dwarf_regs[22] =3D REG(R22); - dwarf_regs[23] =3D REG(R23); - dwarf_regs[24] =3D REG(R24); - dwarf_regs[25] =3D REG(R25); - dwarf_regs[26] =3D REG(R26); - dwarf_regs[27] =3D REG(R27); - dwarf_regs[28] =3D REG(R28); - dwarf_regs[29] =3D REG(R29); - dwarf_regs[30] =3D REG(R30); - dwarf_regs[31] =3D REG(R31); - if (!dwfl_thread_state_registers(thread, 0, 32, dwarf_regs)) - return false; - - dwarf_nip =3D REG(NIP); - dwfl_thread_state_register_pc(thread, dwarf_nip); - for (i =3D 0; i < ARRAY_SIZE(special_regs); i++) { - Dwarf_Word val =3D 0; - perf_reg_value(&val, user_regs, special_regs[i][1]); - if (!dwfl_thread_state_registers(thread, - special_regs[i][0], 1, - &val)) - return false; - } - - return true; -} diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 9c8dad643cd0..e9ba050e7ab1 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -292,15 +292,12 @@ static const Dwfl_Thread_Callbacks callbacks_generic = =3D { .set_initial_registers =3D libdw_set_initial_registers_generic, }; =20 -DEFINE_DWFL_THREAD_CALLBACKS(powerpc); DEFINE_DWFL_THREAD_CALLBACKS(riscv); DEFINE_DWFL_THREAD_CALLBACKS(s390); =20 static const Dwfl_Thread_Callbacks *get_thread_callbacks(const char *arch) { - if (!strcmp(arch, "powerpc")) - return &callbacks_powerpc; - else if (!strcmp(arch, "riscv")) + if (!strcmp(arch, "riscv")) return &callbacks_riscv; else if (!strcmp(arch, "s390")) return &callbacks_s390; diff --git a/tools/perf/util/unwind-libdw.h b/tools/perf/util/unwind-libdw.h index 9d177d70f15c..0ec1abdabbe7 100644 --- a/tools/perf/util/unwind-libdw.h +++ b/tools/perf/util/unwind-libdw.h @@ -10,7 +10,6 @@ struct perf_sample; struct thread; =20 bool libdw_set_initial_registers_mips(Dwfl_Thread *thread, void *arg); -bool libdw_set_initial_registers_powerpc(Dwfl_Thread *thread, void *arg); bool libdw_set_initial_registers_riscv(Dwfl_Thread *thread, void *arg); bool libdw_set_initial_registers_s390(Dwfl_Thread *thread, void *arg); =20 --=20 2.52.0.457.g6b5491de43-goog