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>,
Thomas Gleixner <tglx@linutronix.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Jiri Olsa <jolsa@kernel.org>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Andi Kleen <ak@linux.intel.com>,
Eranian Stephane <eranian@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
broonie@kernel.org, Ravi Bangoria <ravi.bangoria@amd.com>,
linux-kernel@vger.kernel.org, linux-perf-users@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>,
Kan Liang <kan.liang@linux.intel.com>
Subject: [Patch v9 16/24] perf/x86: Support ZMM sampling using sample_simd_vec_reg_* fields
Date: Mon, 6 Jul 2026 09:54:31 +0800 [thread overview]
Message-ID: <20260706015439.3040804-17-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20260706015439.3040804-1-dapeng1.mi@linux.intel.com>
Support sampling of ZMM registers via the sample_simd_vec_reg_* fields.
Each ZMM register consists of 8 u64 words. Current x86 hardware supports
up to 32 ZMM registers. For ZMM registers from ZMM0 to ZMM15, they are
assembled from three parts: XMM (the lower 2 u64 words),
YMMH (the middle 2 u64 words), and ZMMH (the upper 4 u64 words). The
perf_simd_reg_value() function is responsible for assembling these three
parts into a complete ZMM register for output to userspace.
For ZMM registers ZMM16 to ZMM31, each register can be read as a whole
and directly outputted to userspace.
Additionally, sample_simd_vec_reg_qwords should be set to 8 to indicate
ZMM sampling.
ZMM sampling will be enabled in a subsequent patch that sets
PERF_PMU_CAP_SIMD_REGS.
Co-developed-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/core.c | 16 +++++++++++++
arch/x86/events/perf_event.h | 33 +++++++++++++++++++++++++++
arch/x86/include/asm/perf_event.h | 8 +++++++
arch/x86/include/uapi/asm/perf_regs.h | 8 +++++--
arch/x86/kernel/perf_regs.c | 16 ++++++++++++-
5 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 10d90050def3..ef0e238a4678 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -729,6 +729,12 @@ int x86_pmu_hw_config(struct perf_event *event)
if (event_needs_ymm(event) &&
!(x86_pmu.ext_regs_mask & XFEATURE_MASK_YMM))
return -EINVAL;
+ if (event_needs_low16_zmm(event) &&
+ !(x86_pmu.ext_regs_mask & XFEATURE_MASK_ZMM_Hi256))
+ return -EINVAL;
+ if (event_needs_high16_zmm(event) &&
+ !(x86_pmu.ext_regs_mask & XFEATURE_MASK_Hi16_ZMM))
+ return -EINVAL;
}
}
@@ -1774,6 +1780,8 @@ void x86_pmu_clear_perf_regs(struct pt_regs *regs)
perf_regs->abi = PERF_SAMPLE_REGS_ABI_NONE;
perf_regs->xmm_regs = NULL;
perf_regs->ymmh_regs = NULL;
+ perf_regs->zmmh_regs = NULL;
+ perf_regs->h16zmm_regs = NULL;
}
static void update_perf_regs(struct x86_perf_regs *perf_regs,
@@ -1791,6 +1799,10 @@ static void update_perf_regs(struct x86_perf_regs *perf_regs,
perf_regs->xmm_space = xsave->i387.xmm_space;
if (mask & XFEATURE_MASK_YMM)
perf_regs->ymmh = get_xsave_addr(xsave, XFEATURE_YMM);
+ if (mask & XFEATURE_MASK_ZMM_Hi256)
+ perf_regs->zmmh = get_xsave_addr(xsave, XFEATURE_ZMM_Hi256);
+ if (mask & XFEATURE_MASK_Hi16_ZMM)
+ perf_regs->h16zmm = get_xsave_addr(xsave, XFEATURE_Hi16_ZMM);
}
/*
@@ -1984,6 +1996,10 @@ static void x86_pmu_sample_xregs(struct perf_event *event,
mask |= XFEATURE_MASK_SSE;
if (event_needs_ymm(event))
mask |= XFEATURE_MASK_YMM;
+ if (event_needs_low16_zmm(event))
+ mask |= XFEATURE_MASK_ZMM_Hi256;
+ if (event_needs_high16_zmm(event))
+ mask |= XFEATURE_MASK_Hi16_ZMM;
mask &= x86_pmu.ext_regs_mask;
if ((sample_type & PERF_SAMPLE_REGS_USER) && data->regs_user.regs) {
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 13f1f34ff8b0..01414b3a88fd 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -176,6 +176,39 @@ static inline bool event_needs_ymm(struct perf_event *event)
return false;
}
+static inline bool event_needs_low16_zmm(struct perf_event *event)
+{
+ if (!(event->attr.sample_type &
+ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER)))
+ return false;
+
+ if (event->attr.sample_simd_regs_enabled &&
+ event->attr.sample_simd_vec_reg_qwords >= PERF_X86_ZMM_QWORDS)
+ return true;
+
+ return false;
+}
+
+static inline bool event_needs_high16_zmm(struct perf_event *event)
+{
+ if (!(event->attr.sample_type &
+ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER)))
+ return false;
+
+ if (!event->attr.sample_simd_regs_enabled)
+ return false;
+
+ if ((event->attr.sample_type & PERF_SAMPLE_REGS_INTR) &&
+ (fls64(event->attr.sample_simd_vec_reg_intr) > PERF_X86_H16ZMM_BASE))
+ return true;
+
+ if ((event->attr.sample_type & PERF_SAMPLE_REGS_USER) &&
+ (fls64(event->attr.sample_simd_vec_reg_user) > PERF_X86_H16ZMM_BASE))
+ return true;
+
+ return false;
+}
+
struct amd_nb {
int nb_id; /* NorthBridge id */
int refcnt; /* reference count */
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index da77845e1f02..75394c4e8bc3 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -737,6 +737,14 @@ struct x86_perf_regs {
u64 *ymmh_regs;
struct ymmh_struct *ymmh;
};
+ union {
+ u64 *zmmh_regs;
+ struct avx_512_zmm_uppers_state *zmmh;
+ };
+ union {
+ u64 *h16zmm_regs;
+ struct avx_512_hi16_state *h16zmm;
+ };
};
extern unsigned long perf_arch_instruction_pointer(struct pt_regs *regs);
diff --git a/arch/x86/include/uapi/asm/perf_regs.h b/arch/x86/include/uapi/asm/perf_regs.h
index d544f6d79871..b88d0b6822fd 100644
--- a/arch/x86/include/uapi/asm/perf_regs.h
+++ b/arch/x86/include/uapi/asm/perf_regs.h
@@ -60,16 +60,20 @@ enum perf_event_x86_regs {
enum {
PERF_X86_SIMD_XMM_REGS = 16,
PERF_X86_SIMD_YMM_REGS = 16,
- PERF_X86_SIMD_VEC_REGS_MAX = PERF_X86_SIMD_YMM_REGS,
+ PERF_X86_SIMD_ZMM_REGS = 32,
+ PERF_X86_SIMD_VEC_REGS_MAX = PERF_X86_SIMD_ZMM_REGS,
};
#define PERF_X86_SIMD_VEC_MASK __GENMASK_ULL(PERF_X86_SIMD_VEC_REGS_MAX - 1, 0)
+#define PERF_X86_H16ZMM_BASE 16
+
enum {
/* 1 qword = 8 bytes */
PERF_X86_XMM_QWORDS = 2,
PERF_X86_YMM_QWORDS = 4,
- PERF_X86_SIMD_QWORDS_MAX = PERF_X86_YMM_QWORDS,
+ PERF_X86_ZMM_QWORDS = 8,
+ PERF_X86_SIMD_QWORDS_MAX = PERF_X86_ZMM_QWORDS,
};
#endif /* _ASM_X86_PERF_REGS_H */
diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c
index 316d18c13c02..b4a584057fe4 100644
--- a/arch/x86/kernel/perf_regs.c
+++ b/arch/x86/kernel/perf_regs.c
@@ -78,6 +78,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx)
}
#define PERF_X86_YMMH_QWORDS (PERF_X86_YMM_QWORDS / 2)
+#define PERF_X86_ZMMH_QWORDS (PERF_X86_ZMM_QWORDS / 2)
u64 perf_simd_reg_value(struct pt_regs *regs, int idx,
u16 qwords_idx, bool pred)
@@ -95,6 +96,13 @@ u64 perf_simd_reg_value(struct pt_regs *regs, int idx,
qwords_idx >= PERF_X86_SIMD_QWORDS_MAX))
return 0;
+ if (idx >= PERF_X86_H16ZMM_BASE) {
+ if (!perf_regs->h16zmm_regs)
+ return 0;
+ return perf_regs->h16zmm_regs[(idx - PERF_X86_H16ZMM_BASE) *
+ PERF_X86_ZMM_QWORDS + qwords_idx];
+ }
+
if (qwords_idx < PERF_X86_XMM_QWORDS) {
if (!perf_regs->xmm_regs)
return 0;
@@ -105,6 +113,11 @@ u64 perf_simd_reg_value(struct pt_regs *regs, int idx,
return 0;
return perf_regs->ymmh_regs[idx * PERF_X86_YMMH_QWORDS +
qwords_idx - PERF_X86_XMM_QWORDS];
+ } else if (qwords_idx < PERF_X86_ZMM_QWORDS) {
+ if (!perf_regs->zmmh_regs)
+ return 0;
+ return perf_regs->zmmh_regs[idx * PERF_X86_ZMMH_QWORDS +
+ qwords_idx - PERF_X86_YMM_QWORDS];
}
return 0;
@@ -126,7 +139,8 @@ int perf_simd_reg_validate(u64 sample_type, u16 simd_enabled,
if (vec_qwords) {
if (vec_qwords != PERF_X86_XMM_QWORDS &&
- vec_qwords != PERF_X86_YMM_QWORDS)
+ vec_qwords != PERF_X86_YMM_QWORDS &&
+ vec_qwords != PERF_X86_ZMM_QWORDS)
return -EINVAL;
if (!vec_mask_intr && !vec_mask_user)
return -EINVAL;
--
2.34.1
next prev parent reply other threads:[~2026-07-06 2:02 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-06 1:54 [Patch v9 00/24] Support SIMD/eGPRs/SSP registers sampling for perf Dapeng Mi
2026-07-06 1:54 ` [Patch v9 01/24] perf/x86: Fix two error-path and hybrid PMU guard issues Dapeng Mi
2026-07-06 2:21 ` sashiko-bot
2026-07-06 8:05 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 02/24] perf/x86: Move hybrid PMU initialization before x86_pmu_starting_cpu() Dapeng Mi
2026-07-06 2:18 ` sashiko-bot
2026-07-06 8:33 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 03/24] perf/x86/intel: Enable large PEBS sampling for XMMs Dapeng Mi
2026-07-06 1:54 ` [Patch v9 04/24] perf/x86/intel: Convert x86_perf_regs to per-cpu variables Dapeng Mi
2026-07-06 1:54 ` [Patch v9 05/24] perf: Eliminate duplicate arch-specific function definitions Dapeng Mi
2026-07-06 1:54 ` [Patch v9 06/24] perf/x86: Use x86_perf_regs in NMI handlers Dapeng Mi
2026-07-06 2:31 ` sashiko-bot
2026-07-06 8:43 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 07/24] x86/fpu/xstate: Add xsaves_nmi() helper Dapeng Mi
2026-07-06 2:18 ` sashiko-bot
2026-07-06 9:09 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 08/24] x86/fpu: Add update_fpu_state_and_flag() helper Dapeng Mi
2026-07-06 2:22 ` sashiko-bot
2026-07-06 9:15 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 09/24] perf: Move and enhance has_extended_regs() for arch-specific use Dapeng Mi
2026-07-06 1:54 ` [Patch v9 10/24] perf/x86/intel: Consolidate PMU capability updates Dapeng Mi
2026-07-06 1:54 ` [Patch v9 11/24] perf/x86: Enable XMM register sampling for non-PEBS events Dapeng Mi
2026-07-06 2:34 ` sashiko-bot
2026-07-06 9:47 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 12/24] perf/x86: Enable XMM register sampling for REGS_USER case Dapeng Mi
2026-07-06 2:35 ` sashiko-bot
2026-07-07 9:59 ` Mi, Dapeng
2026-07-08 0:56 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 13/24] perf: Add sampling support for SIMD registers Dapeng Mi
2026-07-06 2:34 ` sashiko-bot
2026-07-08 1:13 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 14/24] perf/x86: Support XMM sampling using sample_simd_vec_reg_* fields Dapeng Mi
2026-07-06 6:45 ` sashiko-bot
2026-07-08 1:27 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 15/24] perf/x86: Support YMM " Dapeng Mi
2026-07-06 1:54 ` Dapeng Mi [this message]
2026-07-06 1:54 ` [Patch v9 17/24] perf/x86: Support OPMASK sampling using sample_simd_pred_reg_* fields Dapeng Mi
2026-07-06 1:54 ` [Patch v9 18/24] perf: Enhance perf_reg_validate() with simd_enabled argument Dapeng Mi
2026-07-06 1:54 ` [Patch v9 19/24] perf/x86: Support eGPRs sampling using sample_regs_* fields Dapeng Mi
2026-07-06 1:54 ` [Patch v9 20/24] perf/x86: Support SSP " Dapeng Mi
2026-07-06 1:54 ` [Patch v9 21/24] perf/x86/intel: Support arch-PEBS based SIMD/eGPRs/SSP sampling Dapeng Mi
2026-07-06 1:54 ` [Patch v9 22/24] perf/x86/intel: Enable PERF_PMU_CAP_SIMD_REGS capability Dapeng Mi
2026-07-06 2:57 ` sashiko-bot
2026-07-08 1:51 ` Mi, Dapeng
2026-07-06 1:54 ` [Patch v9 23/24] perf/x86: Activate back-to-back NMI detection for arch-PEBS induced NMIs Dapeng Mi
2026-07-06 1:54 ` [Patch v9 24/24] perf/x86/intel: Add sanity check for PEBS fragment size Dapeng Mi
2026-07-06 5:04 ` sashiko-bot
2026-07-08 2:03 ` Mi, Dapeng
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=20260706015439.3040804-17-dapeng1.mi@linux.intel.com \
--to=dapeng1.mi@linux.intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=broonie@kernel.org \
--cc=dapeng1.mi@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=eranian@google.com \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=ravi.bangoria@amd.com \
--cc=tglx@linutronix.de \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.