From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (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 59A4E3AA9E2; Mon, 6 Jul 2026 02:41:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783305677; cv=none; b=ZrkiR1fmZavHZia3C1pY2sVffhEzLHi1sEo84oHJoUrlOgJL4JJe/SB8dURb3XwGqVqdNYwvdtsGg9DyeymVKu41b1qgntJ9dVqHiVwaYxIBa1KO9HSxz5Bkk6he1Bb4HjPbjbQOdqWOuuuyHOmQJzSPMSVjXlwDWjZlnsOg/MQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783305677; c=relaxed/simple; bh=vg6A1TG5ZR+eJho5kgtQ7Tfw6dnVr3Nqkv5u6dIsNds=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=gUPEPRgVc/Zg3INQuGkOUcMnw8yYsBBC+W0iZb03emhDMwy0YaMLu7XQ6eiDPFLcVr1XGZantOQy4xFENOVtOTOW+5CKnDxi7waEWXegLSmjhMcqXHTe9ATt+PS+/eUHGBZsmfFeaVYCPFXaLFWaSP9WyHMDnAM5/yRrnunhs0U= 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=WghoFkZn; arc=none smtp.client-ip=198.175.65.15 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="WghoFkZn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1783305676; x=1814841676; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vg6A1TG5ZR+eJho5kgtQ7Tfw6dnVr3Nqkv5u6dIsNds=; b=WghoFkZn52AQJyLO2TE5zI6d34OxPdDRkHeMNkUkB/deglVn7npQ+FCA QSJEatTc+s4jh1JB0KqcEpjthi79NP5GWF0Enwzqs8fIacyrujVEqiwQQ RKxq9nlidtcaAfYL8TeMVnTGbIxw7lNETbgReKAR9HxMMed2AKxxVeiqa 0UcGDPpVTqflfaQMR/uMqMk8GGH5aTjQB1xfilSc8cjSanV0zda+kGLp7 p5GdfKg0n31CYyliKzPkckEH64lZ2UG5ITFyBJYic8hQWr+4NFKv/v6Wg f+UWm/BhgXH4OzTUtiPWAs1u4WSHRysgpFkL0ysoJbTkxNgoOjF++POUH A==; X-CSE-ConnectionGUID: zXC192BVS3uLcxMKPrjcwA== X-CSE-MsgGUID: r8XVybOeToOl1m8ueQ3c5g== X-IronPort-AV: E=McAfee;i="6800,10657,11838"; a="87614068" X-IronPort-AV: E=Sophos;i="6.25,149,1779174000"; d="scan'208";a="87614068" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2026 19:41:16 -0700 X-CSE-ConnectionGUID: oLZzKz1NQxiqULvRjmEE0g== X-CSE-MsgGUID: 0+G26BR9S9mjxxL45FetnA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,149,1779174000"; d="scan'208";a="253716730" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa007.jf.intel.com with ESMTP; 05 Jul 2026 19:41:12 -0700 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zide Chen , Falcon Thomas , Dapeng Mi , Xudong Hao , Dapeng Mi 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 Message-Id: <20260706023444.3067660-9-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706023444.3067660-1-dapeng1.mi@linux.intel.com> References: <20260706023444.3067660-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-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../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