From nobody Sat Feb 7 09:37:08 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 806D623909C; Tue, 27 Jan 2026 07:06:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769497603; cv=none; b=lfU45PLQwZswQG5wOZkpf11Ues7M77H4c6ZqaOvbZxUdsq59F4OqEqbAJewwYaGHQPW0jNRld/CiO+iAT5phoE61ZwV9xc0x3YJR55jYNDLPhT3J+bBUYOUEcu0SwLOgWctL6JS05gN/y7Hsl0WHMF5tiOjXDbE3b/SRLiJGfUI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769497603; c=relaxed/simple; bh=17PNpLvaTZJjCb10+2AHJb+L+GZitwhYOgeEv2mtf9I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nQQq1cro6BSXU1oXGZf9zDuwwUOZtnIvh5Oi3T0N87XNOkZGdIngPxhyQ5YsgJ7xiRps1Xn/qiQiswt3v/m1/jCPvRC32RM/Vo2+T7FiomwWuPkbm5bMni0ujYfwUxp230JGfMwrOc8UuwS+T9Hm4ketTmaZeqD1+xE1sMy7ARE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=h+btMEJ5; arc=none smtp.client-ip=192.198.163.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="h+btMEJ5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769497601; x=1801033601; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=17PNpLvaTZJjCb10+2AHJb+L+GZitwhYOgeEv2mtf9I=; b=h+btMEJ5lZG2UTz4M/rsw4T9h2YxAtInXjKl8un605Ishk2f0VCpcIKy I9QNHhDYiRkp4JlqJtG2NwbYKCTBWna5enRruRfCiJ026j2apDb3sL6jz ZJRJUFuRFRp7w1ZTAXBqcZ1VJ6gzuuTzIMnx9HulfDQI2v4XtfZOvQpxR UAG0/4pBqbzxMCnHsNrXt+aKASXIj+aoNvjqKLx9BZRbe+sCRtqv9VOBV d1VpUz4SboiG4uf9nHbssJy+T3DppZ1nt9BiGMmfH2/37+1FEFKy5iKBW NbcMQnhZ2VrTcHMfgoftEoBTOnwPRk9yuIQug2sJmLp8AmgpzFgcLkE84 A==; X-CSE-ConnectionGUID: Drk+q/EgQEaRzv4dvkG4Sg== X-CSE-MsgGUID: zqYMr5u+ROiIrVEVrJbN+g== X-IronPort-AV: E=McAfee;i="6800,10657,11683"; a="70743006" X-IronPort-AV: E=Sophos;i="6.21,256,1763452800"; d="scan'208";a="70743006" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2026 23:06:41 -0800 X-CSE-ConnectionGUID: WD+KbYw5S164kyxyT9fxQg== X-CSE-MsgGUID: hozVYDvOS92M2Ke/bs5uyw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,256,1763452800"; d="scan'208";a="208331272" Received: from spr.sh.intel.com ([10.112.229.196]) by fmviesa009.fm.intel.com with ESMTP; 26 Jan 2026 23:06:35 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , John Garry , Will Deacon , James Clark , Mike Leach , Guo Ren , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-perf-users@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-csky@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Zide Chen , Falcon Thomas , Dapeng Mi , Xudong Hao , Dapeng Mi Subject: [Patch v2 2/3] perf regs: Remove __weak attributive arch__xxx_reg_mask() functions Date: Tue, 27 Jan 2026 15:02:58 +0800 Message-Id: <20260127070259.2720468-3-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260127070259.2720468-1-dapeng1.mi@linux.intel.com> References: <20260127070259.2720468-1-dapeng1.mi@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, some architecture-specific perf-regs functions, such as arch__intr_reg_mask() and arch__user_reg_mask(), are defined with the __weak attribute. This approach ensures that only functions matching the architecture of the build/run host are compiled and executed, reducing build time and binary size. However, this __weak attribute restricts these functions to be called only on the same architecture, preventing cross-architecture functionality. For example, a perf.data file captured on x86 cannot be parsed on an ARM platform. To address this limitation, this patch removes the __weak attribute from these perf-regs functions. The architecture-specific code is moved from the arch/ directory to the util/perf-regs-arch/ directory. The appropriate architectural functions are then called based on the EM_HOST. No functional changes are intended. Suggested-by: Ian Rogers Signed-off-by: Dapeng Mi --- tools/perf/arch/arm/util/Build | 2 - tools/perf/arch/arm/util/perf_regs.c | 13 --- tools/perf/arch/arm64/util/perf_regs.c | 36 --------- tools/perf/arch/csky/Build | 1 - tools/perf/arch/csky/util/Build | 1 - tools/perf/arch/csky/util/perf_regs.c | 13 --- tools/perf/arch/loongarch/util/Build | 1 - tools/perf/arch/loongarch/util/perf_regs.c | 13 --- tools/perf/arch/mips/util/Build | 1 - tools/perf/arch/mips/util/perf_regs.c | 13 --- tools/perf/arch/powerpc/util/perf_regs.c | 47 ----------- tools/perf/arch/riscv/include/perf_regs.h | 7 +- tools/perf/arch/riscv/util/Build | 1 - tools/perf/arch/riscv/util/perf_regs.c | 13 --- tools/perf/arch/s390/util/Build | 1 - tools/perf/arch/s390/util/perf_regs.c | 13 --- tools/perf/arch/x86/util/perf_regs.c | 48 ----------- tools/perf/util/evsel.c | 4 +- tools/perf/util/parse-regs-options.c | 2 +- .../util/perf-regs-arch/perf_regs_aarch64.c | 51 +++++++++++- .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +- .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +- .../util/perf-regs-arch/perf_regs_powerpc.c | 70 +++++++++++++++- .../util/perf-regs-arch/perf_regs_riscv.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_x86.c | 60 +++++++++++++- tools/perf/util/perf_regs.c | 80 ++++++++++++++++++- tools/perf/util/perf_regs.h | 22 ++++- 30 files changed, 319 insertions(+), 236 deletions(-) delete mode 100644 tools/perf/arch/arm/util/perf_regs.c delete mode 100644 tools/perf/arch/csky/Build delete mode 100644 tools/perf/arch/csky/util/Build delete mode 100644 tools/perf/arch/csky/util/perf_regs.c delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c delete mode 100644 tools/perf/arch/mips/util/perf_regs.c delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c delete mode 100644 tools/perf/arch/s390/util/perf_regs.c diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build index 3291f893b943..b94bf3c5279a 100644 --- a/tools/perf/arch/arm/util/Build +++ b/tools/perf/arch/arm/util/Build @@ -1,5 +1,3 @@ -perf-util-y +=3D perf_regs.o - perf-util-$(CONFIG_LOCAL_LIBUNWIND) +=3D unwind-libunwind.o =20 perf-util-y +=3D pmu.o auxtrace.o cs-etm.o diff --git a/tools/perf/arch/arm/util/perf_regs.c b/tools/perf/arch/arm/uti= l/perf_regs.c deleted file mode 100644 index 03a5bc0cf64c..000000000000 --- a/tools/perf/arch/arm/util/perf_regs.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/arm64/util/perf_regs.c b/tools/perf/arch/arm64= /util/perf_regs.c index 9bb768e1bea1..47f58eaba032 100644 --- a/tools/perf/arch/arm64/util/perf_regs.c +++ b/tools/perf/arch/arm64/util/perf_regs.c @@ -103,39 +103,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op) =20 return SDT_ARG_VALID; } - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - struct perf_event_attr attr =3D { - .type =3D PERF_TYPE_HARDWARE, - .config =3D PERF_COUNT_HW_CPU_CYCLES, - .sample_type =3D PERF_SAMPLE_REGS_USER, - .disabled =3D 1, - .exclude_kernel =3D 1, - .sample_period =3D 1, - .sample_regs_user =3D PERF_REGS_MASK - }; - int fd; - - if (getauxval(AT_HWCAP) & HWCAP_SVE) - attr.sample_regs_user |=3D SMPL_REG_MASK(PERF_REG_ARM64_VG); - - /* - * Check if the pmu supports perf extended regs, before - * returning the register mask to sample. - */ - if (attr.sample_regs_user !=3D PERF_REGS_MASK) { - event_attr_init(&attr); - fd =3D sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd !=3D -1) { - close(fd); - return attr.sample_regs_user; - } - } - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/csky/Build b/tools/perf/arch/csky/Build deleted file mode 100644 index e63eabc2c8f4..000000000000 --- a/tools/perf/arch/csky/Build +++ /dev/null @@ -1 +0,0 @@ -perf-util-y +=3D util/ diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Bu= ild deleted file mode 100644 index 6b2d0e021b11..000000000000 --- a/tools/perf/arch/csky/util/Build +++ /dev/null @@ -1 +0,0 @@ -perf-util-y +=3D perf_regs.o diff --git a/tools/perf/arch/csky/util/perf_regs.c b/tools/perf/arch/csky/u= til/perf_regs.c deleted file mode 100644 index 2cf7a54106e0..000000000000 --- a/tools/perf/arch/csky/util/perf_regs.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongar= ch/util/Build index 0aa31986ecb5..0c958c8e0718 100644 --- a/tools/perf/arch/loongarch/util/Build +++ b/tools/perf/arch/loongarch/util/Build @@ -1,5 +1,4 @@ perf-util-y +=3D header.o -perf-util-y +=3D perf_regs.o =20 perf-util-$(CONFIG_LOCAL_LIBUNWIND) +=3D unwind-libunwind.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) +=3D unwind-libdw.o diff --git a/tools/perf/arch/loongarch/util/perf_regs.c b/tools/perf/arch/l= oongarch/util/perf_regs.c deleted file mode 100644 index 03a5bc0cf64c..000000000000 --- a/tools/perf/arch/loongarch/util/perf_regs.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/mips/util/Build b/tools/perf/arch/mips/util/Bu= ild index 691fa2051958..818b808a8247 100644 --- a/tools/perf/arch/mips/util/Build +++ b/tools/perf/arch/mips/util/Build @@ -1,2 +1 @@ -perf-util-y +=3D perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) +=3D unwind-libunwind.o diff --git a/tools/perf/arch/mips/util/perf_regs.c b/tools/perf/arch/mips/u= til/perf_regs.c deleted file mode 100644 index 2cf7a54106e0..000000000000 --- a/tools/perf/arch/mips/util/perf_regs.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/pow= erpc/util/perf_regs.c index 779073f7e992..93f929fc32e3 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c @@ -123,50 +123,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op) =20 return SDT_ARG_VALID; } - -uint64_t arch__intr_reg_mask(void) -{ - struct perf_event_attr attr =3D { - .type =3D PERF_TYPE_HARDWARE, - .config =3D PERF_COUNT_HW_CPU_CYCLES, - .sample_type =3D PERF_SAMPLE_REGS_INTR, - .precise_ip =3D 1, - .disabled =3D 1, - .exclude_kernel =3D 1, - }; - int fd; - u32 version; - u64 extended_mask =3D 0, mask =3D PERF_REGS_MASK; - - /* - * Get the PVR value to set the extended - * mask specific to platform. - */ - version =3D (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF); - if (version =3D=3D PVR_POWER9) - extended_mask =3D PERF_REG_PMU_MASK_300; - else if ((version =3D=3D PVR_POWER10) || (version =3D=3D PVR_POWER11)) - extended_mask =3D PERF_REG_PMU_MASK_31; - else - return mask; - - attr.sample_regs_intr =3D extended_mask; - attr.sample_period =3D 1; - event_attr_init(&attr); - - /* - * check if the pmu supports perf extended regs, before - * returning the register mask to sample. - */ - fd =3D sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd !=3D -1) { - close(fd); - mask |=3D extended_mask; - } - return mask; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/ri= scv/include/perf_regs.h index 89d5bbb8d2b8..af7a1b47bf66 100644 --- a/tools/perf/arch/riscv/include/perf_regs.h +++ b/tools/perf/arch/riscv/include/perf_regs.h @@ -10,10 +10,15 @@ =20 #define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1) #define PERF_REGS_MAX PERF_REG_RISCV_MAX + +#if defined(__riscv_xlen) #if __riscv_xlen =3D=3D 64 -#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 #else #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 #endif +#else +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_NONE +#endif =20 #endif /* ARCH_PERF_REGS_H */ diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/= Build index 628b9ebd418b..da5b12e7f862 100644 --- a/tools/perf/arch/riscv/util/Build +++ b/tools/perf/arch/riscv/util/Build @@ -1,4 +1,3 @@ -perf-util-y +=3D perf_regs.o perf-util-y +=3D header.o =20 perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o diff --git a/tools/perf/arch/riscv/util/perf_regs.c b/tools/perf/arch/riscv= /util/perf_regs.c deleted file mode 100644 index 2cf7a54106e0..000000000000 --- a/tools/perf/arch/riscv/util/perf_regs.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Bu= ild index 5391d26fedd4..3b09c058e0ec 100644 --- a/tools/perf/arch/s390/util/Build +++ b/tools/perf/arch/s390/util/Build @@ -1,6 +1,5 @@ perf-util-y +=3D header.o perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o -perf-util-y +=3D perf_regs.o =20 perf-util-y +=3D machine.o perf-util-y +=3D pmu.o diff --git a/tools/perf/arch/s390/util/perf_regs.c b/tools/perf/arch/s390/u= til/perf_regs.c deleted file mode 100644 index 2cf7a54106e0..000000000000 --- a/tools/perf/arch/s390/util/perf_regs.c +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/uti= l/perf_regs.c index a7ca4154fdf9..41141cebe226 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -233,51 +233,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op) =20 return SDT_ARG_VALID; } - -uint64_t arch__intr_reg_mask(void) -{ - struct perf_event_attr attr =3D { - .type =3D PERF_TYPE_HARDWARE, - .config =3D PERF_COUNT_HW_CPU_CYCLES, - .sample_type =3D PERF_SAMPLE_REGS_INTR, - .sample_regs_intr =3D PERF_REG_EXTENDED_MASK, - .precise_ip =3D 1, - .disabled =3D 1, - .exclude_kernel =3D 1, - }; - int fd; - /* - * In an unnamed union, init it here to build on older gcc versions - */ - attr.sample_period =3D 1; - - if (perf_pmus__num_core_pmus() > 1) { - struct perf_pmu *pmu =3D NULL; - __u64 type =3D PERF_TYPE_RAW; - - /* - * The same register set is supported among different hybrid PMUs. - * Only check the first available one. - */ - while ((pmu =3D perf_pmus__scan_core(pmu)) !=3D NULL) { - type =3D pmu->type; - break; - } - attr.config |=3D type << PERF_PMU_TYPE_SHIFT; - } - - event_attr_init(&attr); - - fd =3D sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd !=3D -1) { - close(fd); - return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK); - } - - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 5ac1a05601b1..a36528fd41c6 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1055,13 +1055,13 @@ static void __evsel__config_callchain(struct evsel = *evsel, struct record_opts *o evsel__set_sample_bit(evsel, REGS_USER); evsel__set_sample_bit(evsel, STACK_USER); if (opts->sample_user_regs && - DWARF_MINIMAL_REGS(e_machine) !=3D arch__user_reg_mask()) { + DWARF_MINIMAL_REGS(e_machine) !=3D perf_user_reg_mask(EM_HOST)) { attr->sample_regs_user |=3D DWARF_MINIMAL_REGS(e_machine); pr_warning("WARNING: The use of --call-graph=3Ddwarf may require all t= he user registers, " "specifying a subset with --user-regs may render DWARF unwinding u= nreliable, " "so the minimal registers set (IP, SP) is explicitly forced.\n"); } else { - attr->sample_regs_user |=3D arch__user_reg_mask(); + attr->sample_regs_user |=3D perf_user_reg_mask(EM_HOST); } attr->sample_stack_user =3D param->dump_size; attr->exclude_callchain_user =3D 1; diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-r= egs-options.c index c0d0ef9fd495..2af6e4ad2a34 100644 --- a/tools/perf/util/parse-regs-options.c +++ b/tools/perf/util/parse-regs-options.c @@ -70,7 +70,7 @@ __parse_regs(const struct option *opt, const char *str, i= nt unset, bool intr) if (!str) return -1; =20 - mask =3D intr ? arch__intr_reg_mask() : arch__user_reg_mask(); + mask =3D intr ? perf_intr_reg_mask(EM_HOST) : perf_user_reg_mask(EM_HOST); =20 /* because str is read-only */ s =3D os =3D strdup(str); diff --git a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c b/tools/per= f/util/perf-regs-arch/perf_regs_aarch64.c index 9dcda80d310f..21a432671f04 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c @@ -1,7 +1,56 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include =20 +#include "../debug.h" +#include "../event.h" #include "../perf_regs.h" -#include "../../../arch/arm64/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/arm64/include/perf_regs.h" + +#define SMPL_REG_MASK(b) (1ULL << (b)) + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +uint64_t __perf_reg_mask_arm64(bool intr) +{ + struct perf_event_attr attr =3D { + .type =3D PERF_TYPE_HARDWARE, + .config =3D PERF_COUNT_HW_CPU_CYCLES, + .sample_type =3D PERF_SAMPLE_REGS_USER, + .disabled =3D 1, + .exclude_kernel =3D 1, + .sample_period =3D 1, + .sample_regs_user =3D PERF_REGS_MASK + }; + int fd; + + if (intr) + return PERF_REGS_MASK; + + if (getauxval(AT_HWCAP) & HWCAP_SVE) + attr.sample_regs_user |=3D SMPL_REG_MASK(PERF_REG_ARM64_VG); + + /* + * Check if the pmu supports perf extended regs, before + * returning the register mask to sample. + */ + if (attr.sample_regs_user !=3D PERF_REGS_MASK) { + event_attr_init(&attr); + fd =3D sys_perf_event_open(&attr, 0, -1, -1, 0); + if (fd !=3D -1) { + close(fd); + return attr.sample_regs_user; + } + } + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_arm64(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_arm.c b/tools/perf/ut= il/perf-regs-arch/perf_regs_arm.c index e29d130a587a..184d6e248dfc 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_arm.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_arm.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include "../perf_regs.h" -#include "../../../arch/arm/include/uapi/asm/perf_regs.h" +#include "../../arch/arm/include/perf_regs.h" + +uint64_t __perf_reg_mask_arm(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_arm(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_csky.c b/tools/perf/u= til/perf-regs-arch/perf_regs_csky.c index 75b461ef2eba..36cafa6a4c42 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_csky.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_csky.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include "../perf_regs.h" -#include "../../arch/csky/include/uapi/asm/perf_regs.h" +#include "../../arch/csky/include/perf_regs.h" + +uint64_t __perf_reg_mask_csky(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_csky(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c b/tools/p= erf/util/perf-regs-arch/perf_regs_loongarch.c index 043f97f4e3ac..478ee889afa1 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include "../perf_regs.h" -#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h" +#include "../../arch/loongarch/include/perf_regs.h" + +uint64_t __perf_reg_mask_loongarch(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_loongarch(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_mips.c b/tools/perf/u= til/perf-regs-arch/perf_regs_mips.c index 793178fc3c78..c5a475f6ec64 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_mips.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_mips.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include "../perf_regs.h" -#include "../../../arch/mips/include/uapi/asm/perf_regs.h" +#include "../../arch/mips/include/perf_regs.h" + +uint64_t __perf_reg_mask_mips(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_mips(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c b/tools/per= f/util/perf-regs-arch/perf_regs_powerpc.c index 08636bb09a3a..5211cc0c4e81 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c @@ -1,7 +1,75 @@ // SPDX-License-Identifier: GPL-2.0 =20 +#include +#include +#include +#include + +#include "../debug.h" +#include "../event.h" +#include "../header.h" #include "../perf_regs.h" -#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/powerpc/util/utils_header.h" +#include "../../arch/powerpc/include/perf_regs.h" + +#include + +#define PVR_POWER9 0x004E +#define PVR_POWER10 0x0080 +#define PVR_POWER11 0x0082 + +#if defined(__powerpc64__) && defined(__powerpc__) +uint64_t __perf_reg_mask_powerpc(bool intr) +{ + struct perf_event_attr attr =3D { + .type =3D PERF_TYPE_HARDWARE, + .config =3D PERF_COUNT_HW_CPU_CYCLES, + .sample_type =3D PERF_SAMPLE_REGS_INTR, + .precise_ip =3D 1, + .disabled =3D 1, + .exclude_kernel =3D 1, + }; + int fd; + u32 version; + u64 extended_mask =3D 0, mask =3D PERF_REGS_MASK; + + if (!intr) + return PERF_REGS_MASK; + + /* + * Get the PVR value to set the extended + * mask specific to platform. + */ + version =3D (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF); + if (version =3D=3D PVR_POWER9) + extended_mask =3D PERF_REG_PMU_MASK_300; + else if ((version =3D=3D PVR_POWER10) || (version =3D=3D PVR_POWER11)) + extended_mask =3D PERF_REG_PMU_MASK_31; + else + return mask; + + attr.sample_regs_intr =3D extended_mask; + attr.sample_period =3D 1; + event_attr_init(&attr); + + /* + * check if the pmu supports perf extended regs, before + * returning the register mask to sample. + */ + fd =3D sys_perf_event_open(&attr, 0, -1, -1, 0); + if (fd !=3D -1) { + close(fd); + mask |=3D extended_mask; + } + return mask; +} +#else +uint64_t __perf_reg_mask_powerpc(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} +#endif =20 const char *__perf_reg_name_powerpc(int id) { 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 337b687c655d..5b5f21fcba8c 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include "../perf_regs.h" -#include "../../../arch/riscv/include/uapi/asm/perf_regs.h" +#include "../../arch/riscv/include/perf_regs.h" + +uint64_t __perf_reg_mask_riscv(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_riscv(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_s390.c b/tools/perf/u= til/perf-regs-arch/perf_regs_s390.c index d69bba881080..c61df24edf0f 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_s390.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_s390.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include "../perf_regs.h" -#include "../../../arch/s390/include/uapi/asm/perf_regs.h" +#include "../../arch/s390/include/perf_regs.h" + +uint64_t __perf_reg_mask_s390(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_s390(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_x86.c b/tools/perf/ut= il/perf-regs-arch/perf_regs_x86.c index 708954a9d35d..d319106dc7b2 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_x86.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_x86.c @@ -1,7 +1,65 @@ // SPDX-License-Identifier: GPL-2.0 =20 +#include +#include +#include +#include +#include + +#include "../debug.h" +#include "../event.h" +#include "../pmu.h" +#include "../pmus.h" #include "../perf_regs.h" -#include "../../../arch/x86/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/x86/include/perf_regs.h" + +uint64_t __perf_reg_mask_x86(bool intr) +{ + struct perf_event_attr attr =3D { + .type =3D PERF_TYPE_HARDWARE, + .config =3D PERF_COUNT_HW_CPU_CYCLES, + .sample_type =3D PERF_SAMPLE_REGS_INTR, + .sample_regs_intr =3D PERF_REG_EXTENDED_MASK, + .precise_ip =3D 1, + .disabled =3D 1, + .exclude_kernel =3D 1, + }; + int fd; + + if (!intr) + return PERF_REGS_MASK; + + /* + * In an unnamed union, init it here to build on older gcc versions + */ + attr.sample_period =3D 1; + + if (perf_pmus__num_core_pmus() > 1) { + struct perf_pmu *pmu =3D NULL; + __u64 type =3D PERF_TYPE_RAW; + + /* + * The same register set is supported among different hybrid PMUs. + * Only check the first available one. + */ + while ((pmu =3D perf_pmus__scan_core(pmu)) !=3D NULL) { + type =3D pmu->type; + break; + } + attr.config |=3D type << PERF_PMU_TYPE_SHIFT; + } + + event_attr_init(&attr); + + fd =3D sys_perf_event_open(&attr, 0, -1, -1, 0); + if (fd !=3D -1) { + close(fd); + return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK); + } + + return PERF_REGS_MASK; +} =20 const char *__perf_reg_name_x86(int id) { diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index f21148478db1..900929cff4b5 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -13,14 +13,86 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_u= nused, return SDT_ARG_SKIP; } =20 -uint64_t __weak arch__intr_reg_mask(void) +uint64_t perf_intr_reg_mask(uint16_t e_machine) { - return 0; + uint64_t mask =3D 0; + + switch (e_machine) { + case EM_ARM: + mask =3D __perf_reg_mask_arm(/*intr=3D*/true); + break; + case EM_AARCH64: + mask =3D __perf_reg_mask_arm64(/*intr=3D*/true); + break; + case EM_CSKY: + mask =3D __perf_reg_mask_csky(/*intr=3D*/true); + break; + case EM_LOONGARCH: + mask =3D __perf_reg_mask_loongarch(/*intr=3D*/true); + break; + case EM_MIPS: + mask =3D __perf_reg_mask_mips(/*intr=3D*/true); + break; + case EM_PPC: + case EM_PPC64: + mask =3D __perf_reg_mask_powerpc(/*intr=3D*/true); + break; + case EM_RISCV: + mask =3D __perf_reg_mask_riscv(/*intr=3D*/true); + break; + case EM_S390: + mask =3D __perf_reg_mask_s390(/*intr=3D*/true); + break; + case EM_386: + case EM_X86_64: + mask =3D __perf_reg_mask_x86(/*intr=3D*/true); + break; + default: + break; + } + + return mask; } =20 -uint64_t __weak arch__user_reg_mask(void) +uint64_t perf_user_reg_mask(uint16_t e_machine) { - return 0; + uint64_t mask =3D 0; + + switch (e_machine) { + case EM_ARM: + mask =3D __perf_reg_mask_arm(/*intr=3D*/false); + break; + case EM_AARCH64: + mask =3D __perf_reg_mask_arm64(/*intr=3D*/false); + break; + case EM_CSKY: + mask =3D __perf_reg_mask_csky(/*intr=3D*/false); + break; + case EM_LOONGARCH: + mask =3D __perf_reg_mask_loongarch(/*intr=3D*/false); + break; + case EM_MIPS: + mask =3D __perf_reg_mask_mips(/*intr=3D*/false); + break; + case EM_PPC: + case EM_PPC64: + mask =3D __perf_reg_mask_powerpc(/*intr=3D*/false); + break; + case EM_RISCV: + mask =3D __perf_reg_mask_riscv(/*intr=3D*/false); + break; + case EM_S390: + mask =3D __perf_reg_mask_s390(/*intr=3D*/false); + break; + case EM_386: + case EM_X86_64: + mask =3D __perf_reg_mask_x86(/*intr=3D*/false); + break; + default: + break; + } + + return mask; } =20 const char *perf_reg_name(int id, uint16_t e_machine) diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 2c2a8de6912d..8531584bc1b1 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -13,37 +13,55 @@ enum { }; =20 int arch_sdt_arg_parse_op(char *old_op, char **new_op); -uint64_t arch__intr_reg_mask(void); -uint64_t arch__user_reg_mask(void); +uint64_t perf_intr_reg_mask(uint16_t e_machine); +uint64_t perf_user_reg_mask(uint16_t e_machine); =20 const char *perf_reg_name(int id, uint16_t e_machine); int perf_reg_value(u64 *valp, struct regs_dump *regs, int id); uint64_t perf_arch_reg_ip(uint16_t e_machine); uint64_t perf_arch_reg_sp(uint16_t e_machine); + +uint64_t __perf_reg_mask_arm64(bool intr); const char *__perf_reg_name_arm64(int id); uint64_t __perf_reg_ip_arm64(void); uint64_t __perf_reg_sp_arm64(void); + +uint64_t __perf_reg_mask_arm(bool intr); const char *__perf_reg_name_arm(int id); uint64_t __perf_reg_ip_arm(void); uint64_t __perf_reg_sp_arm(void); + +uint64_t __perf_reg_mask_csky(bool intr); const char *__perf_reg_name_csky(int id); uint64_t __perf_reg_ip_csky(void); uint64_t __perf_reg_sp_csky(void); + +uint64_t __perf_reg_mask_loongarch(bool intr); const char *__perf_reg_name_loongarch(int id); uint64_t __perf_reg_ip_loongarch(void); uint64_t __perf_reg_sp_loongarch(void); + +uint64_t __perf_reg_mask_mips(bool intr); const char *__perf_reg_name_mips(int id); uint64_t __perf_reg_ip_mips(void); uint64_t __perf_reg_sp_mips(void); + +uint64_t __perf_reg_mask_powerpc(bool intr); const char *__perf_reg_name_powerpc(int id); uint64_t __perf_reg_ip_powerpc(void); uint64_t __perf_reg_sp_powerpc(void); + +uint64_t __perf_reg_mask_riscv(bool intr); const char *__perf_reg_name_riscv(int id); uint64_t __perf_reg_ip_riscv(void); uint64_t __perf_reg_sp_riscv(void); + +uint64_t __perf_reg_mask_s390(bool intr); const char *__perf_reg_name_s390(int id); uint64_t __perf_reg_ip_s390(void); uint64_t __perf_reg_sp_s390(void); + +uint64_t __perf_reg_mask_x86(bool intr); const char *__perf_reg_name_x86(int id); uint64_t __perf_reg_ip_x86(void); uint64_t __perf_reg_sp_x86(void); --=20 2.34.1