The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Dapeng Mi <dapeng1.mi@linux.intel.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	Zide Chen <zide.chen@intel.com>,
	Falcon Thomas <thomas.falcon@intel.com>,
	Dapeng Mi <dapeng1.mi@intel.com>,
	Xudong Hao <xudong.hao@intel.com>,
	Dapeng Mi <dapeng1.mi@linux.intel.com>
Subject: [Patch v9 08/10] perf dwarf-regs: Add SIMD/eGPRs support for x86 DWARF registers
Date: Mon,  6 Jul 2026 10:34:42 +0800	[thread overview]
Message-ID: <20260706023444.3067660-9-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20260706023444.3067660-1-dapeng1.mi@linux.intel.com>

Enhance the x86-specific DWARF register handling by adding support for
SIMD and eGPRs registers.

This update is based on the "DWARF Register Number Mapping" table from
the "System V Application Binary Interface AMD64 Architecture Processor
Supplement" (version 1.0).

Modifications include:
- Updating the x86_64_regidx_table[] array to incorporate SIMD and eGPRs
  registers.
- Enhancing the __get_dwarf_regnum_for_perf_regnum_x86_64() function to
  retrieve the DWARF register index for eGPRs.

Since currently libdw doesn't support SIMD and APX eGPRs registers yet,
still keep the original return value for get_libdw_frame_nregs() helper.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 .../util/dwarf-regs-arch/dwarf-regs-x86.c     | 138 +++++++++++++++---
 tools/perf/util/dwarf-regs.c                  |   9 +-
 tools/perf/util/include/dwarf-regs.h          |   7 +-
 tools/perf/util/unwind-libdw.c                |   6 +-
 4 files changed, 132 insertions(+), 28 deletions(-)

diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c
index c2a70e03b1a9..bb17d779036a 100644
--- a/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c
+++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c
@@ -90,22 +90,22 @@ static const struct dwarf_regs_idx x86_64_regidx_table[] = {
 	{ "r14", 14 }, { "r14d", 14 }, { "r14w", 14 }, { "r14b", 14 },
 	{ "r15", 15 }, { "r15d", 15 }, { "r15w", 15 }, { "r15b", 15 },
 	// 16 - Return Address RA
-	{ "xmm0", 17},
-	{ "xmm1", 18},
-	{ "xmm2", 19},
-	{ "xmm3", 20},
-	{ "xmm4", 21},
-	{ "xmm5", 22},
-	{ "xmm6", 23},
-	{ "xmm7", 24},
-	{ "xmm8", 25},
-	{ "xmm9", 26},
-	{ "xmm10", 27},
-	{ "xmm11", 28},
-	{ "xmm12", 29},
-	{ "xmm13", 30},
-	{ "xmm14", 31},
-	{ "xmm15", 32},
+	{ "zmm0", 17 }, { "ymm0", 17 }, { "xmm0", 17 },
+	{ "zmm1", 18 }, { "ymm1", 18 }, { "xmm1", 18 },
+	{ "zmm2", 19 }, { "ymm2", 19 }, { "xmm2", 19 },
+	{ "zmm3", 20 }, { "ymm3", 20 }, { "xmm3", 20 },
+	{ "zmm4", 21 }, { "ymm4", 21 }, { "xmm4", 21 },
+	{ "zmm5", 22 }, { "ymm5", 22 }, { "xmm5", 22 },
+	{ "zmm6", 23 }, { "ymm6", 23 }, { "xmm6", 23 },
+	{ "zmm7", 24 }, { "ymm7", 24 }, { "xmm7", 24 },
+	{ "zmm8", 25 }, { "ymm8", 25 }, { "xmm8", 25 },
+	{ "zmm9", 26 }, { "ymm9", 26 }, { "xmm9", 26 },
+	{ "zmm10", 27 }, { "ymm10", 27 }, { "xmm10", 27 },
+	{ "zmm11", 28 }, { "ymm11", 28 }, { "xmm11", 28 },
+	{ "zmm12", 29 }, { "ymm12", 29 }, { "xmm12", 29 },
+	{ "zmm13", 30 }, { "ymm13", 30 }, { "xmm13", 30 },
+	{ "zmm14", 31 }, { "ymm14", 31 }, { "xmm14", 31 },
+	{ "zmm15", 32 }, { "ymm15", 32 }, { "xmm15", 32 },
 	{ "st0", 33},
 	{ "st1", 34},
 	{ "st2", 35},
@@ -129,7 +129,7 @@ static const struct dwarf_regs_idx x86_64_regidx_table[] = {
 	{ "ds", 53},
 	{ "fs", 54},
 	{ "gs", 55},
-	// 56-47 - reserved
+	// 56-57 - reserved
 	{ "fs.base", 58},
 	{ "gs.base", 59},
 	// 60-61 - reserved
@@ -138,6 +138,49 @@ static const struct dwarf_regs_idx x86_64_regidx_table[] = {
 	{ "mxcsr", 64}, // 128-bit Media Control and Status
 	{ "fcw", 65}, // x87 Control Word
 	{ "fsw", 66}, // x87 Status Word
+	// 67-82 - Upper Vector Registers 16–31
+	{ "zmm16", 67 }, { "ymm16", 67 }, { "xmm16", 67 },
+	{ "zmm17", 68 }, { "ymm17", 68 }, { "xmm17", 68 },
+	{ "zmm18", 69 }, { "ymm18", 69 }, { "xmm18", 69 },
+	{ "zmm19", 70 }, { "ymm19", 70 }, { "xmm19", 70 },
+	{ "zmm20", 71 }, { "ymm20", 71 }, { "xmm20", 71 },
+	{ "zmm21", 72 }, { "ymm21", 72 }, { "xmm21", 72 },
+	{ "zmm22", 73 }, { "ymm22", 73 }, { "xmm22", 73 },
+	{ "zmm23", 74 }, { "ymm23", 74 }, { "xmm23", 74 },
+	{ "zmm24", 75 }, { "ymm24", 75 }, { "xmm24", 75 },
+	{ "zmm25", 76 }, { "ymm25", 76 }, { "xmm25", 76 },
+	{ "zmm26", 77 }, { "ymm26", 77 }, { "xmm26", 77 },
+	{ "zmm27", 78 }, { "ymm27", 78 }, { "xmm27", 78 },
+	{ "zmm28", 79 }, { "ymm28", 79 }, { "xmm28", 79 },
+	{ "zmm29", 80 }, { "ymm29", 80 }, { "xmm29", 80 },
+	{ "zmm30", 81 }, { "ymm30", 81 }, { "xmm30", 81 },
+	{ "zmm31", 82 }, { "ymm31", 82 }, { "xmm31", 82 },
+	// 118-125 - Vector Mask Registers 0–7
+	{ "k0", 118 },
+	{ "k1", 119 },
+	{ "k2", 120 },
+	{ "k3", 121 },
+	{ "k4", 122 },
+	{ "k5", 123 },
+	{ "k6", 124 },
+	{ "k7", 125 },
+	// 130-145 - APX Integer Registers 16-31
+	{ "r16", 130 }, { "r16d", 130 }, { "r16w", 130 }, { "r16b", 130 },
+	{ "r17", 131 }, { "r17d", 131 }, { "r17w", 131 }, { "r17b", 131 },
+	{ "r18", 132 }, { "r18d", 132 }, { "r18w", 132 }, { "r18b", 132 },
+	{ "r19", 133 }, { "r19d", 133 }, { "r19w", 133 }, { "r19b", 133 },
+	{ "r20", 134 }, { "r20d", 134 }, { "r20w", 134 }, { "r20b", 134 },
+	{ "r21", 135 }, { "r21d", 135 }, { "r21w", 135 }, { "r21b", 135 },
+	{ "r22", 136 }, { "r22d", 136 }, { "r22w", 136 }, { "r22b", 136 },
+	{ "r23", 137 }, { "r23d", 137 }, { "r23w", 137 }, { "r23b", 137 },
+	{ "r24", 138 }, { "r24d", 138 }, { "r24w", 138 }, { "r24b", 138 },
+	{ "r25", 139 }, { "r25d", 139 }, { "r25w", 139 }, { "r25b", 139 },
+	{ "r26", 140 }, { "r26d", 140 }, { "r26w", 140 }, { "r26b", 140 },
+	{ "r27", 141 }, { "r27d", 141 }, { "r27w", 141 }, { "r27b", 141 },
+	{ "r28", 142 }, { "r28d", 142 }, { "r28w", 142 }, { "r28b", 142 },
+	{ "r29", 143 }, { "r29d", 143 }, { "r29w", 143 }, { "r29b", 143 },
+	{ "r30", 144 }, { "r30d", 144 }, { "r30w", 144 }, { "r30b", 144 },
+	{ "r31", 145 }, { "r31d", 145 }, { "r31w", 145 }, { "r31b", 145 },
 	// End of regular dwarf registers.
 	{ "rip", DWARF_REG_PC }, { "eip", DWARF_REG_PC }, { "ip", DWARF_REG_PC },
 };
@@ -204,7 +247,7 @@ int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum)
 	return dwarf_i386_regnums[perf_regnum];
 }
 
-int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum)
+int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi)
 {
 	static const int dwarf_x86_64_regnums[] = {
 		[PERF_REG_X86_AX] = 0,
@@ -248,13 +291,66 @@ int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum)
 		[PERF_REG_X86_XMM14] = 31,
 		[PERF_REG_X86_XMM15] = 32,
 	};
+	static const int dwarf_x86_64_regnums_apx[] = {
+		[PERF_REG_X86_AX] = 0,
+		[PERF_REG_X86_BX] = 3,
+		[PERF_REG_X86_CX] = 2,
+		[PERF_REG_X86_DX] = 1,
+		[PERF_REG_X86_SI] = 4,
+		[PERF_REG_X86_DI] = 5,
+		[PERF_REG_X86_BP] = 6,
+		[PERF_REG_X86_SP] = 7,
+		[PERF_REG_X86_IP] = 16,
+		[PERF_REG_X86_FLAGS] = 49,
+		[PERF_REG_X86_CS] = 51,
+		[PERF_REG_X86_SS] = 52,
+		[PERF_REG_X86_DS] = 53,
+		[PERF_REG_X86_ES] = 50,
+		[PERF_REG_X86_FS] = 54,
+		[PERF_REG_X86_GS] = 55,
+		[PERF_REG_X86_R8] = 8,
+		[PERF_REG_X86_R9] = 9,
+		[PERF_REG_X86_R10] = 10,
+		[PERF_REG_X86_R11] = 11,
+		[PERF_REG_X86_R12] = 12,
+		[PERF_REG_X86_R13] = 13,
+		[PERF_REG_X86_R14] = 14,
+		[PERF_REG_X86_R15] = 15,
+		[PERF_REG_X86_R16] = 130,
+		[PERF_REG_X86_R17] = 131,
+		[PERF_REG_X86_R18] = 132,
+		[PERF_REG_X86_R19] = 133,
+		[PERF_REG_X86_R20] = 134,
+		[PERF_REG_X86_R21] = 135,
+		[PERF_REG_X86_R22] = 136,
+		[PERF_REG_X86_R23] = 137,
+		[PERF_REG_X86_R24] = 138,
+		[PERF_REG_X86_R25] = 139,
+		[PERF_REG_X86_R26] = 140,
+		[PERF_REG_X86_R27] = 141,
+		[PERF_REG_X86_R28] = 142,
+		[PERF_REG_X86_R29] = 143,
+		[PERF_REG_X86_R30] = 144,
+		[PERF_REG_X86_R31] = 145,
+	};
 
 	if (perf_regnum == 0)
 		return 0;
 
-	if (perf_regnum < 0 || perf_regnum >= (int)ARRAY_SIZE(dwarf_x86_64_regnums) ||
-	    dwarf_x86_64_regnums[perf_regnum] == 0)
+	if (perf_regnum < 0)
+		return -ENOENT;
+
+	if (!(abi & PERF_SAMPLE_REGS_ABI_SIMD) &&
+	    (perf_regnum >= (int)ARRAY_SIZE(dwarf_x86_64_regnums) ||
+	     dwarf_x86_64_regnums[perf_regnum] == 0))
+		return -ENOENT;
+
+	if ((abi & PERF_SAMPLE_REGS_ABI_SIMD) &&
+	    (perf_regnum >= (int)ARRAY_SIZE(dwarf_x86_64_regnums_apx) ||
+	     dwarf_x86_64_regnums_apx[perf_regnum] == 0))
 		return -ENOENT;
 
-	return dwarf_x86_64_regnums[perf_regnum];
+	return abi & PERF_SAMPLE_REGS_ABI_SIMD ?
+			dwarf_x86_64_regnums_apx[perf_regnum] :
+			dwarf_x86_64_regnums[perf_regnum];
 }
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 797f455eba0d..67f38342247e 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -158,6 +158,10 @@ static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __mayb
 {
 	switch (machine) {
 	case EM_X86_64:
+		/*
+		 * Since libdw doesn't support SIMD and APX eGPR register yet,
+		 * still keep nregs to 17.
+		 */
 		return 17;
 	case EM_386:
 		return 9;
@@ -187,13 +191,14 @@ static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __mayb
 }
 
 int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine,
-				     unsigned int flags, bool only_libdw_supported)
+				     unsigned int flags,
+				     bool only_libdw_supported, int abi)
 {
 	int reg;
 
 	switch (machine) {
 	case EM_X86_64:
-		reg = __get_dwarf_regnum_for_perf_regnum_x86_64(perf_regnum);
+		reg = __get_dwarf_regnum_for_perf_regnum_x86_64(perf_regnum, abi);
 		break;
 	case EM_386:
 		reg = __get_dwarf_regnum_for_perf_regnum_i386(perf_regnum);
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 46a764cf322f..92cf0af93e9e 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -103,7 +103,7 @@ int __get_csky_regnum(const char *name, unsigned int flags);
 int __get_dwarf_regnum_i386(const char *name);
 int __get_dwarf_regnum_x86_64(const char *name);
 int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);
-int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum);
+int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum, int abi);
 
 int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum);
 int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum);
@@ -125,8 +125,9 @@ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags)
 /*
  * get_dwarf_regnum - Returns DWARF regnum from perf register number.
  */
-int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine, unsigned int flags,
-				     bool only_libdw_supported);
+int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine,
+				     unsigned int flags,
+				     bool only_libdw_supported, int abi);
 
 void get_powerpc_regs(u32 raw_insn, int is_source, struct annotated_op_loc *op_loc);
 
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 7f35042be567..13fd81af5b54 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -273,7 +273,8 @@ static bool libdw_set_initial_registers(Dwfl_Thread *thread, void *arg)
 			int dwarf_reg =
 				get_dwarf_regnum_for_perf_regnum(perf_reg, e_machine,
 								 e_flags,
-								 /*only_libdw_supported=*/true);
+								 /*only_libdw_supported=*/true,
+								 user_regs->abi);
 			if (dwarf_reg > max_dwarf_reg)
 				max_dwarf_reg = dwarf_reg;
 		}
@@ -288,7 +289,8 @@ static bool libdw_set_initial_registers(Dwfl_Thread *thread, void *arg)
 			int dwarf_reg =
 				get_dwarf_regnum_for_perf_regnum(perf_reg, e_machine,
 								 e_flags,
-								 /*only_libdw_supported=*/true);
+								 /*only_libdw_supported=*/true,
+								 user_regs->abi);
 			if (dwarf_reg >= 0) {
 				val = 0;
 				if (perf_reg_value(&val, user_regs, perf_reg) == 0)
-- 
2.34.1


  parent reply	other threads:[~2026-07-06  2:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-06  2:34 [Patch v9 00/10] Perf tools: Support eGPRs/SSP/SIMD registers sampling Dapeng Mi
2026-07-06  2:34 ` [Patch v9 01/10] perf dwarf-regs: Fix DWARF register index bounds check Dapeng Mi
2026-07-06  2:34 ` [Patch v9 02/10] perf util: Add missed fields in _attr__fprintf() and __attr_swap() Dapeng Mi
2026-07-06  2:34 ` [Patch v9 03/10] tools headers: Sync x86 headers with kernel sources Dapeng Mi
2026-07-06  2:34 ` [Patch v9 04/10] perf headers: Sync perf_event.h/perf_regs.h with the kernel headers Dapeng Mi
2026-07-06  2:34 ` [Patch v9 05/10] perf regs: Support x86 eGPRs/SSP sampling Dapeng Mi
2026-07-06  2:34 ` [Patch v9 06/10] perf regs: Support x86 SIMD registers sampling Dapeng Mi
2026-07-06  2:34 ` [Patch v9 07/10] perf regs: Enable dumping of SIMD registers Dapeng Mi
2026-07-06  2:34 ` Dapeng Mi [this message]
2026-07-06  2:34 ` [Patch v9 09/10] perf tests: Add x86 eGPRs/SSP registers sampling test Dapeng Mi
2026-07-06  2:34 ` [Patch v9 10/10] perf tests: Add SIMD " Dapeng Mi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260706023444.3067660-9-dapeng1.mi@linux.intel.com \
    --to=dapeng1.mi@linux.intel.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=dapeng1.mi@intel.com \
    --cc=irogers@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=thomas.falcon@intel.com \
    --cc=xudong.hao@intel.com \
    --cc=zide.chen@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox