From nobody Tue Dec 2 02:05:17 2025 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 1AD4F3002CE; Thu, 20 Nov 2025 05:37:06 +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=1763617028; cv=none; b=ccbUhcWVSU9zV80dQzHYYaEIoMdmNhXYOcaO71/L7085IPwe3jat/qGJLqjcgp7fFZazwUffkkC7ux/GN3H7LqORgr/jjZZn+//YU8xC2Zenhb2+6RjeSukuoGQ7jq+w+MvGEF4ikfLv5o99DCgmdY0iZzx9e+QJ0fEj/YrubOE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617028; c=relaxed/simple; bh=mxmtB5LHf+KKSdJFHtNgNUq3nDPZqEkLcEPvhZhRNmA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rCFx/bx6tF6jVYlPhpGmY1ZrUyeTf+eWbBIf6hNFd6mSxvxVCJMr9bDCm3W2QMB6jhveNOzBeuUqjSux1j5dVkYpsOfclm0dvfuXzDPsYXZbKghK6agRIRVFuGAhKs4MwaiuiQl15rX8XQ9keroqt349xlEOZEG5YmVV3+Nvi7Y= 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=Swf/pdUt; 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="Swf/pdUt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617026; x=1795153026; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mxmtB5LHf+KKSdJFHtNgNUq3nDPZqEkLcEPvhZhRNmA=; b=Swf/pdUt33GyZ2ftYH2/FvS6FKjxO5u69zXfaCkkCFl8xw8/kkfz0V3Q 8OmAzRuTsYqJX2tcGo3JdlXWRfPm+umrUmXeAQwXWb5XMUEpLtMg0f2DR YgLjkcAN7pywU0ffyPV4lVcZsN4Se0+6sUi6DkKGlldUeffq70Pf5HZj0 79VEvTonSizb5hSyfqTo+fHsP2Ny/JjYQOaPgZ78LSCjnriDM7cqgD7t5 hf3Y3LvFSbvsipC0qDGgs5l2uWgP/CYIPBSl+kJpdNa+0otN8A8m/570E U14ST/4q2HjXqNGey6RhRtAhwMf1tql4I+lJSc1CZAth3yDX/DLvmBZE5 A==; X-CSE-ConnectionGUID: Pag2Yc0hTDyPusKaFKhqGg== X-CSE-MsgGUID: qC1HBc26SLW+T7fozX99lg== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710149" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710149" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:05 -0800 X-CSE-ConnectionGUID: GU14klhDQNCFYErxadC4og== X-CSE-MsgGUID: DitVtM4PRp2xnU+7SH7lsg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055523" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:02 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 1/7] perf/x86/intel: Support newly introduced 4 OMR MSRs for DMR & NVL Date: Thu, 20 Nov 2025 13:34:25 +0800 Message-Id: <20251120053431.491677-2-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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" Diamond Rapids and Nova Lake feature an expanded facility called the Off-Module Response (OMR) facility, which replaces the Off-Core Response (OCR) Performance Monitoring of previous processors. Legacy microarchitectures used the OCR facility to evaluate off-core and multi-core off-module transactions. The properly renamed, OMR facility, improves the OCR capability for scalable coverage of new memory systems of multi-core module systems. Similarly with OCR, 4 additional off-module configuration MSRs OFFMODULE_RSP_0 ~ OFFMODULE_RSP_3 are introduced to specify attributes of the off-module transaction. For more details about OMR, please refer to section 16.1 "OFF-MODULE RESPONSE (OMR) FACILITY" in ISE documentation. This patch adds support for these 4 OMR events. ISE link: https://www.intel.com/content/www/us/en/content-details/869288/in= tel-architecture-instruction-set-extensions-programming-reference.html Signed-off-by: Dapeng Mi --- arch/x86/events/intel/core.c | 45 +++++++++++++++++++++++--------- arch/x86/events/perf_event.h | 5 ++++ arch/x86/include/asm/msr-index.h | 5 ++++ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index aad89c9d9514..5970f7c20101 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3529,17 +3529,24 @@ static int intel_alt_er(struct cpu_hw_events *cpuc, struct extra_reg *extra_regs =3D hybrid(cpuc->pmu, extra_regs); int alt_idx =3D idx; =20 - if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) - return idx; - - if (idx =3D=3D EXTRA_REG_RSP_0) - alt_idx =3D EXTRA_REG_RSP_1; - - if (idx =3D=3D EXTRA_REG_RSP_1) - alt_idx =3D EXTRA_REG_RSP_0; + if (idx =3D=3D EXTRA_REG_RSP_0 || idx =3D=3D EXTRA_REG_RSP_1) { + if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1)) + return idx; + if (++alt_idx > EXTRA_REG_RSP_1) + alt_idx =3D EXTRA_REG_RSP_0; + if (config & ~extra_regs[alt_idx].valid_mask) + return idx; + } =20 - if (config & ~extra_regs[alt_idx].valid_mask) - return idx; + if (idx >=3D EXTRA_REG_OMR_0 && idx <=3D EXTRA_REG_OMR_3) { + if (!(x86_pmu.flags & PMU_FL_HAS_OMR)) + return idx; + if (++alt_idx > EXTRA_REG_OMR_3) + alt_idx =3D EXTRA_REG_OMR_0; + if (config & + ~extra_regs[alt_idx - EXTRA_REG_OMR_0].valid_mask) + return idx; + } =20 return alt_idx; } @@ -3547,16 +3554,28 @@ static int intel_alt_er(struct cpu_hw_events *cpuc, static void intel_fixup_er(struct perf_event *event, int idx) { struct extra_reg *extra_regs =3D hybrid(event->pmu, extra_regs); - event->hw.extra_reg.idx =3D idx; + int omr_idx; =20 - if (idx =3D=3D EXTRA_REG_RSP_0) { + event->hw.extra_reg.idx =3D idx; + switch (idx) { + case EXTRA_REG_RSP_0: event->hw.config &=3D ~INTEL_ARCH_EVENT_MASK; event->hw.config |=3D extra_regs[EXTRA_REG_RSP_0].event; event->hw.extra_reg.reg =3D MSR_OFFCORE_RSP_0; - } else if (idx =3D=3D EXTRA_REG_RSP_1) { + break; + case EXTRA_REG_RSP_1: event->hw.config &=3D ~INTEL_ARCH_EVENT_MASK; event->hw.config |=3D extra_regs[EXTRA_REG_RSP_1].event; event->hw.extra_reg.reg =3D MSR_OFFCORE_RSP_1; + break; + case EXTRA_REG_OMR_0 ... EXTRA_REG_OMR_3: + omr_idx =3D idx - EXTRA_REG_OMR_0; + event->hw.config &=3D ~ARCH_PERFMON_EVENTSEL_UMASK; + event->hw.config |=3D 1ULL << (8 + omr_idx); + event->hw.extra_reg.reg =3D MSR_OMR_0 + omr_idx; + break; + default: + pr_warn("The extra reg idx %d is not supported.\n", idx); } } =20 diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 3161ec0a3416..586e3fdfe6d8 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -45,6 +45,10 @@ enum extra_reg_type { EXTRA_REG_FE =3D 4, /* fe_* */ EXTRA_REG_SNOOP_0 =3D 5, /* snoop response 0 */ EXTRA_REG_SNOOP_1 =3D 6, /* snoop response 1 */ + EXTRA_REG_OMR_0 =3D 7, /* OMR 0 */ + EXTRA_REG_OMR_1 =3D 8, /* OMR 1 */ + EXTRA_REG_OMR_2 =3D 9, /* OMR 2 */ + EXTRA_REG_OMR_3 =3D 10, /* OMR 3 */ =20 EXTRA_REG_MAX /* number of entries needed */ }; @@ -1099,6 +1103,7 @@ do { \ #define PMU_FL_RETIRE_LATENCY 0x200 /* Support Retire Latency in PEBS */ #define PMU_FL_BR_CNTR 0x400 /* Support branch counter logging */ #define PMU_FL_DYN_CONSTRAINT 0x800 /* Needs dynamic constraint */ +#define PMU_FL_HAS_OMR 0x1000 /* has 4 equivalent OMR regs */ =20 #define EVENT_VAR(_id) event_attr_##_id #define EVENT_PTR(_id) &event_attr_##_id.attr.attr diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-in= dex.h index 65cc528fbad8..170cece31e3c 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -259,6 +259,11 @@ #define MSR_SNOOP_RSP_0 0x00001328 #define MSR_SNOOP_RSP_1 0x00001329 =20 +#define MSR_OMR_0 0x000003e0 +#define MSR_OMR_1 0x000003e1 +#define MSR_OMR_2 0x000003e2 +#define MSR_OMR_3 0x000003e3 + #define MSR_LBR_SELECT 0x000001c8 #define MSR_LBR_TOS 0x000001c9 =20 --=20 2.34.1 From nobody Tue Dec 2 02:05:17 2025 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 6445930148A; Thu, 20 Nov 2025 05:37:10 +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=1763617032; cv=none; b=k3lgrEPq9Ml2YyhYeoqUpWTyeCsh7tjkv95RXJblxuRedttSkh5nbllvoKJEApT4Cx13v/4wMDFGVlTUq+1uhbl2manI6eI3dZL2kDWmdjg5IMBemC6d5xbSfULxf74tYiLHbQj4b6Ysj7EgaGq0UzTiKlrExGyAjc9TEIc41c0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617032; c=relaxed/simple; bh=JrzsjrJhCWoiS8cNkmNAnc/xM/s9xJjcyofKiFnAHWE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HDjJHY4+O/AOnOjRvwkjOmw1SwkuFypc8k6U7D3LxXFM4lc9WMcFvk25N816xDF/CdfaeZPoI1GD5KHd24KhYCWk5QP683AtIf2FUu1GXQBeYfuVXSmCJDf47EPkkqE4O0Q2kJEID+8Qx1rm9a36N08GNld5xPTc6ngTO6Glpj0= 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=MICBEgIc; 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="MICBEgIc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617030; x=1795153030; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JrzsjrJhCWoiS8cNkmNAnc/xM/s9xJjcyofKiFnAHWE=; b=MICBEgIcxPrjdHJCUs4v312CSavHFiUBQKS8cxb2KwY8OmKeiBDllTta krHzc6JvfX40rfpSv4Q7+QZB9vH3XQTyUEdVmzXFCkrpVN40xrAuvj3WA M1SBqIdXLgj5BB/zS+HWNs/l1Y32zAODDarZIaRozC9m5w/clvpmS65W3 IFVifuSGAtNh2VhwoAex2CGEur1Ib9xZZkrhq/dtB1jOBV/xbjKgy6QCx 2jpPHVJD8heH1GLoKBSNaVj1wEW3HeZ0KYLBbqE+jgpghQkcu3jz6QHPX GBOj0Iid0gh5gsucO/vJ81DWwPloLO+yAk/7DvYWZdoOy8ph4zxmiLwYQ A==; X-CSE-ConnectionGUID: 8DeEvCmWReyIaTnC1NOIlA== X-CSE-MsgGUID: oTUHwJcJRwG7pCHmNczMww== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710157" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710157" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:10 -0800 X-CSE-ConnectionGUID: r0Iz2gg3RZeT4GfTdGPlPg== X-CSE-MsgGUID: 39OxR0ssRXWr+y/SfNRpRA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055534" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:06 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 2/7] perf/x86/intel: Add support for PEBS memory auxiliary info field in DMR Date: Thu, 20 Nov 2025 13:34:26 +0800 Message-Id: <20251120053431.491677-3-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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" With the introduction of the OMR feature, the PEBS memory auxiliary info field for load and store latency events has been restructured for DMR. The memory auxiliary info field's bit[8] indicates whether a L2 cache miss occurred for a memory load or store instruction. If bit[8] is 0, it signifies no L2 cache miss, and bits[7:0] specify the exact cache data source (up to the L2 cache level). If bit[8] is 1, bits[7:0] represent the OMR encoding, indicating the specific L3 cache or memory region involved in the memory access. A significant enhancement is OMR encoding provides up to 8 fine-grained memmory regions besides the cache region. A significant enhancement for OMR encoding is the ability to provide up to 8 fine-grained memory regions in addition to the cache region, offering more detailed insights into memory access regions. For detailed information on the memory auxiliary info encoding, please refer to section 16.2 "PEBS LOAD LATENCY AND STORE LATENCY FACILITY" in the ISE documentation. his patch ensures that the PEBS memory auxiliary info field is correctly interpreted and utilized in DMR. ISE: https://www.intel.com/content/www/us/en/content-details/869288/intel-a= rchitecture-instruction-set-extensions-programming-reference.html Signed-off-by: Dapeng Mi --- arch/x86/events/intel/ds.c | 140 ++++++++++++++++++++++++++ arch/x86/events/perf_event.h | 2 + include/uapi/linux/perf_event.h | 27 ++++- tools/include/uapi/linux/perf_event.h | 27 ++++- 4 files changed, 190 insertions(+), 6 deletions(-) diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 2e170f2093ac..0b62e1f64f33 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -34,6 +34,17 @@ struct pebs_record_32 { =20 */ =20 +union omr_encoding { + struct { + u8 omr_source : 4; + u8 omr_remote : 1; + u8 omr_hitm : 1; + u8 omr_snoop : 1; + u8 omr_promoted : 1; + }; + u8 omr_full; +}; + union intel_x86_pebs_dse { u64 val; struct { @@ -73,6 +84,18 @@ union intel_x86_pebs_dse { unsigned int lnc_addr_blk:1; unsigned int ld_reserved6:18; }; + struct { + unsigned int pnc_dse: 8; + unsigned int pnc_l2_miss:1; + unsigned int pnc_stlb_clean_hit:1; + unsigned int pnc_stlb_any_hit:1; + unsigned int pnc_stlb_miss:1; + unsigned int pnc_locked:1; + unsigned int pnc_data_blk:1; + unsigned int pnc_addr_blk:1; + unsigned int pnc_fb_full:1; + unsigned int ld_reserved8:16; + }; }; =20 =20 @@ -228,6 +251,85 @@ void __init intel_pmu_pebs_data_source_lnl(void) __intel_pmu_pebs_data_source_cmt(data_source); } =20 +/* Version for Panthercove and later */ + +/* L2 hit */ +#define PNC_PEBS_DATA_SOURCE_MAX 16 +static u64 pnc_pebs_l2_hit_data_source[PNC_PEBS_DATA_SOURCE_MAX] =3D { + P(OP, LOAD) | P(LVL, NA) | LEVEL(NA) | P(SNOOP, NA), /* 0x00: non-cache a= ccess */ + OP_LH | LEVEL(L0) | P(SNOOP, NONE), /* 0x01: L0 hit */ + OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x02: L1 hit */ + OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x03: L1 Miss Handl= ing Buffer hit */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x04: L2 Hit Clean */ + 0, /* 0x05: Reserved */ + 0, /* 0x06: Reserved */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, HIT), /* 0x07: L2 Hit Snoop HI= T */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, HITM), /* 0x08: L2 Hit Snoop H= it Modified */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, MISS), /* 0x09: Prefetch Promo= tion */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, MISS), /* 0x0a: Cross Core Pre= fetch Promotion */ + 0, /* 0x0b: Reserved */ + 0, /* 0x0c: Reserved */ + 0, /* 0x0d: Reserved */ + 0, /* 0x0e: Reserved */ + OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0f: uncached */ +}; + +/* L2 miss */ +#define OMR_DATA_SOURCE_MAX 16 +static u64 omr_data_source[OMR_DATA_SOURCE_MAX] =3D { + P(OP, LOAD) | P(LVL, NA) | LEVEL(NA) | P(SNOOP, NA), /* 0x00: invalid */ + 0, /* 0x01: Reserved */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(REGION, L_SHARE), /* 0x02: local CA sh= ared cache */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(REGION, L_NON_SHARE),/* 0x03: local CA= non-shared cache */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(REGION, O_IO), /* 0x04: other CA IO ag= ent */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(REGION, O_SHARE), /* 0x05: other CA sh= ared cache */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(REGION, O_NON_SHARE),/* 0x06: other CA= non-shared cache */ + OP_LH | LEVEL(RAM) | P(REGION, MMIO), /* 0x07: MMIO */ + OP_LH | LEVEL(RAM) | P(REGION, MEM0), /* 0x08: Memory region 0 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM1), /* 0x09: Memory region 1 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM2), /* 0x0a: Memory region 2 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM3), /* 0x0b: Memory region 3 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM4), /* 0x0c: Memory region 4 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM5), /* 0x0d: Memory region 5 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM6), /* 0x0e: Memory region 6 */ + OP_LH | LEVEL(RAM) | P(REGION, MEM7), /* 0x0f: Memory region 7 */ +}; + +static u64 parse_omr_data_source(u8 dse) +{ + union omr_encoding omr; + u64 val =3D 0; + + omr.omr_full =3D dse; + val =3D omr_data_source[omr.omr_source]; + if (omr.omr_source > 0x1 && omr.omr_source < 0x7) + val |=3D omr.omr_remote ? P(LVL, REM_CCE1) : 0; + else if (omr.omr_source > 0x7) + val |=3D omr.omr_remote ? P(LVL, REM_RAM1) : P(LVL, LOC_RAM); + + if (omr.omr_remote) + val |=3D REM; + + val |=3D omr.omr_hitm ? P(SNOOP, HITM) : P(SNOOP, HIT); + + if (omr.omr_source =3D=3D 0x2) { + u8 snoop =3D omr.omr_snoop | omr.omr_promoted; + + if (snoop =3D=3D 0x0) + val |=3D P(SNOOP, NA); + else if (snoop =3D=3D 0x1) + val |=3D P(SNOOP, MISS); + else if (snoop =3D=3D 0x2) + val |=3D P(SNOOP, HIT); + else if (snoop =3D=3D 0x3) + val |=3D P(SNOOP, NONE); + } else if (omr.omr_source > 0x2 && omr.omr_source < 0x7) { + val |=3D omr.omr_snoop ? P(SNOOPX, FWD) : 0; + } + + return val; +} + static u64 precise_store_data(u64 status) { union intel_x86_pebs_dse dse; @@ -410,6 +512,44 @@ u64 arl_h_latency_data(struct perf_event *event, u64 s= tatus) return lnl_latency_data(event, status); } =20 +u64 pnc_latency_data(struct perf_event *event, u64 status) +{ + union intel_x86_pebs_dse dse; + union perf_mem_data_src src; + u64 val; + + dse.val =3D status; + + if (!dse.pnc_l2_miss) + val =3D pnc_pebs_l2_hit_data_source[dse.pnc_dse & 0xf]; + else + val =3D parse_omr_data_source(dse.pnc_dse); + + if (!val) + val =3D P(OP, LOAD) | LEVEL(NA) | P(SNOOP, NA); + + if (dse.pnc_stlb_miss) + val |=3D P(TLB, MISS) | P(TLB, L2); + else + val |=3D P(TLB, HIT) | P(TLB, L1) | P(TLB, L2); + + if (dse.pnc_locked) + val |=3D P(LOCK, LOCKED); + + if (dse.pnc_data_blk) + val |=3D P(BLK, DATA); + if (dse.pnc_addr_blk) + val |=3D P(BLK, ADDR); + if (!dse.pnc_data_blk && !dse.pnc_addr_blk) + val |=3D P(BLK, NA); + + src.val =3D val; + if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) + src.mem_op =3D P(OP, STORE); + + return src.val; +} + static u64 load_latency_data(struct perf_event *event, u64 status) { union intel_x86_pebs_dse dse; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 586e3fdfe6d8..bd501c2a0f73 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1664,6 +1664,8 @@ u64 lnl_latency_data(struct perf_event *event, u64 st= atus); =20 u64 arl_h_latency_data(struct perf_event *event, u64 status); =20 +u64 pnc_latency_data(struct perf_event *event, u64 status); + extern struct event_constraint intel_core2_pebs_event_constraints[]; =20 extern struct event_constraint intel_atom_pebs_event_constraints[]; diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_even= t.h index d292f96bc06f..99156e1888f7 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -1328,14 +1328,16 @@ union perf_mem_data_src { mem_snoopx : 2, /* Snoop mode, ext */ mem_blk : 3, /* Access blocked */ mem_hops : 3, /* Hop level */ - mem_rsvd : 18; + mem_region : 5, /* cache/memory regions */ + mem_rsvd : 13; }; }; #elif defined(__BIG_ENDIAN_BITFIELD) union perf_mem_data_src { __u64 val; struct { - __u64 mem_rsvd : 18, + __u64 mem_rsvd : 13, + mem_region : 5, /* cache/memory regions */ mem_hops : 3, /* Hop level */ mem_blk : 3, /* Access blocked */ mem_snoopx : 2, /* Snoop mode, ext */ @@ -1392,7 +1394,7 @@ union perf_mem_data_src { #define PERF_MEM_LVLNUM_L4 0x0004 /* L4 */ #define PERF_MEM_LVLNUM_L2_MHB 0x0005 /* L2 Miss Handling Buffer */ #define PERF_MEM_LVLNUM_MSC 0x0006 /* Memory-side Cache */ -/* 0x007 available */ +#define PERF_MEM_LVLNUM_L0 0x0007 /* L0 */ #define PERF_MEM_LVLNUM_UNC 0x0008 /* Uncached */ #define PERF_MEM_LVLNUM_CXL 0x0009 /* CXL */ #define PERF_MEM_LVLNUM_IO 0x000a /* I/O */ @@ -1445,6 +1447,25 @@ union perf_mem_data_src { /* 5-7 available */ #define PERF_MEM_HOPS_SHIFT 43 =20 +/* Cache/Memory region */ +#define PERF_MEM_REGION_NA 0x0 /* Invalid */ +#define PERF_MEM_REGION_RSVD 0x01 /* Reserved */ +#define PERF_MEM_REGION_L_SHARE 0x02 /* Local CA shared cache */ +#define PERF_MEM_REGION_L_NON_SHARE 0x03 /* Local CA non-shared cache */ +#define PERF_MEM_REGION_O_IO 0x04 /* Other CA IO agent */ +#define PERF_MEM_REGION_O_SHARE 0x05 /* Other CA shared cache */ +#define PERF_MEM_REGION_O_NON_SHARE 0x06 /* Other CA non-shared cache */ +#define PERF_MEM_REGION_MMIO 0x07 /* MMIO */ +#define PERF_MEM_REGION_MEM0 0x08 /* Memory region 0 */ +#define PERF_MEM_REGION_MEM1 0x09 /* Memory region 1 */ +#define PERF_MEM_REGION_MEM2 0x0a /* Memory region 2 */ +#define PERF_MEM_REGION_MEM3 0x0b /* Memory region 3 */ +#define PERF_MEM_REGION_MEM4 0x0c /* Memory region 4 */ +#define PERF_MEM_REGION_MEM5 0x0d /* Memory region 5 */ +#define PERF_MEM_REGION_MEM6 0x0e /* Memory region 6 */ +#define PERF_MEM_REGION_MEM7 0x0f /* Memory region 7 */ +#define PERF_MEM_REGION_SHIFT 46 + #define PERF_MEM_S(a, s) \ (((__u64)PERF_MEM_##a##_##s) << PERF_MEM_##a##_SHIFT) =20 diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/lin= ux/perf_event.h index d292f96bc06f..a8d7c8c8551b 100644 --- a/tools/include/uapi/linux/perf_event.h +++ b/tools/include/uapi/linux/perf_event.h @@ -1328,14 +1328,16 @@ union perf_mem_data_src { mem_snoopx : 2, /* Snoop mode, ext */ mem_blk : 3, /* Access blocked */ mem_hops : 3, /* Hop level */ - mem_rsvd : 18; + mem_region : 5, /* cache/memory regions */ + mem_rsvd : 13; }; }; #elif defined(__BIG_ENDIAN_BITFIELD) union perf_mem_data_src { __u64 val; struct { - __u64 mem_rsvd : 18, + __u64 mem_rsvd : 13, + mem_region : 5, /* cache/memory regions */ mem_hops : 3, /* Hop level */ mem_blk : 3, /* Access blocked */ mem_snoopx : 2, /* Snoop mode, ext */ @@ -1392,7 +1394,7 @@ union perf_mem_data_src { #define PERF_MEM_LVLNUM_L4 0x0004 /* L4 */ #define PERF_MEM_LVLNUM_L2_MHB 0x0005 /* L2 Miss Handling Buffer */ #define PERF_MEM_LVLNUM_MSC 0x0006 /* Memory-side Cache */ -/* 0x007 available */ +#define PERF_MEM_LVLNUM_L0 0x0007 /* L0 */ #define PERF_MEM_LVLNUM_UNC 0x0008 /* Uncached */ #define PERF_MEM_LVLNUM_CXL 0x0009 /* CXL */ #define PERF_MEM_LVLNUM_IO 0x000a /* I/O */ @@ -1445,6 +1447,25 @@ union perf_mem_data_src { /* 5-7 available */ #define PERF_MEM_HOPS_SHIFT 43 =20 +/* Cache/Memory region */ +#define PERF_MEM_REGION_NA 0x0 /* Invalid */ +#define PERF_MEM_REGION_RSVD 0x01 /* Reserved */ +#define PERF_MEM_REGION_L_SHARE 0x02 /* Local CA shared cache */ +#define PERF_MEM_REGION_L_NON_SHARE 0x03 /* Local CA non-shared cache */ +#define PERF_MEM_REGION_O_IO 0x04 /* Other CA IO agent */ +#define PERF_MEM_REGION_O_SHARE 0x05 /* Other CA shared cache */ +#define PERF_MEM_REGION_O_NON_SHARE 0x06 /* Other CA non-shared cache */ +#define PERF_MEM_REGION_MMIO 0x07 /* MMIO */ +#define PERF_MEM_REGION_MEM0 0x08 /* Memory region 0 */ +#define PERF_MEM_REGION_MEM1 0x09 /* Memory region 1 */ +#define PERF_MEM_REGION_MEM2 0x0a /* Memory region 2 */ +#define PERF_MEM_REGION_MEM3 0x0b /* Memory region 3 */ +#define PERF_MEM_REGION_MEM4 0x0c /* Memory region 4 */ +#define PERF_MEM_REGION_MEM5 0x0d /* Memory region 5 */ +#define PERF_MEM_REGION_MEM6 0x0e /* Memory region 6 */ +#define PERF_MEM_REGION_MEM7 0x0f /* Memory region 7 */ +#define PERF_MEM_REGION_SHIFT 46 + #define PERF_MEM_S(a, s) \ (((__u64)PERF_MEM_##a##_##s) << PERF_MEM_##a##_SHIFT) =20 --=20 2.34.1 From nobody Tue Dec 2 02:05:17 2025 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 D9F063019D6; Thu, 20 Nov 2025 05:37:14 +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=1763617036; cv=none; b=LAfP2MGbexX5wphcNSpWgqsiRtSIeXo9QCZ0IqMvzepUfw9UsFkWBiS+jTcBXWaZNyPjIlRbcGr2UDFXEc94hdQI7evAiFHifJb8EE12CsT3M7tE7lF2Z/GG1VB6HdOJL816lBmf8m/YVoAe7BwjcwGPeMypp24gTBMCW4/Ab0A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617036; c=relaxed/simple; bh=1SG+Nk7fXs6Rhn29C77LsyulCmsbSDBPK13bQ2VEsqY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Au85sm3qme7XSfgANJqi/DJHZ6dripOGnSUuW4psD0jddaY2rf4qkkBQzb0EdUVGXxLiKnV6Vdyo6WH8jc8pqlqudp5ri7y4ubzjJ1/DG7DAwVvViBuWfIwvg/U+AntuluX7yHfV0rGjxEWIUh6BoboGGaKDnhoD7Qxuot8xvfo= 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=JwW0xjnA; 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="JwW0xjnA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617035; x=1795153035; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1SG+Nk7fXs6Rhn29C77LsyulCmsbSDBPK13bQ2VEsqY=; b=JwW0xjnAJkolIpuzO2jpNvHKcGR2/yZg6/nm0JoL3v2s7Cg07TwqSvti G+23wpudb+5FmKf3/2cJisJ9veyStjPeivQDzLHpAVhSSmOj+54p+/k7R OoJHKqr+tDN3wWrHd4sot9kj0z+tbBVesYhVN8zyrJh4WZ/FeM1wcAX7V SF0sGcwCKf6bOQpuKzKYUkHMxJrAXDyV2jDN3LJ8FFLrIYUc9NisIxjxn fqbpYY85wd44HrveP+oKzDF/Qq8vQB7otq7hnvVBwhXrQRYB6f3RPtCs3 klpxIbJFy4VcsQpEhUeCZ+Ry56Uz7nvnqhLfM3m0kjtGufCCypD05VRs6 w==; X-CSE-ConnectionGUID: ougvEyaCTF6lWfKjw7E7CA== X-CSE-MsgGUID: 9wU0CmJUTPa/eVupdaS5vg== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710164" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710164" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:14 -0800 X-CSE-ConnectionGUID: zR72d1gSSzaiVQpuN3wQIw== X-CSE-MsgGUID: aqCKP1gCQOeDfJq+gr+Elg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055552" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:10 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 3/7] perf/x86/intel: Add core PMU support for DMR Date: Thu, 20 Nov 2025 13:34:27 +0800 Message-Id: <20251120053431.491677-4-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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" This patch enables core PMU features for DMR (PatherCove uarch) which includes PNC specific counter and PEBS constraints, new cache events ID and OMR registers table. For detailed information about counter constraints, please refer to section 16.3 "COUNTER RESTRICTIONS" in the ISE documentation. ISE: https://www.intel.com/content/www/us/en/content-details/869288/intel-a= rchitecture-instruction-set-extensions-programming-reference.html Signed-off-by: Dapeng Mi --- arch/x86/events/intel/core.c | 182 +++++++++++++++++++++++++++++++++++ arch/x86/events/intel/ds.c | 27 ++++++ arch/x86/events/perf_event.h | 2 + 3 files changed, 211 insertions(+) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 5970f7c20101..9f2a93fe23df 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -435,6 +435,62 @@ static struct extra_reg intel_lnc_extra_regs[] __read_= mostly =3D { EVENT_EXTRA_END }; =20 +static struct event_constraint intel_pnc_event_constraints[] =3D { + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x0100, 0), /* INST_RETIRED.PREC_DIST */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ + FIXED_EVENT_CONSTRAINT(0x013c, 2), /* CPU_CLK_UNHALTED.REF_TSC_P */ + FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_RETIRING, 0), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BAD_SPEC, 1), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_FE_BOUND, 2), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BE_BOUND, 3), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_HEAVY_OPS, 4), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_BR_MISPREDICT, 5), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_FETCH_LAT, 6), + METRIC_EVENT_CONSTRAINT(INTEL_TD_METRIC_MEM_BOUND, 7), + + INTEL_EVENT_CONSTRAINT(0x20, 0xf), + INTEL_EVENT_CONSTRAINT(0x79, 0xf), + + INTEL_UEVENT_CONSTRAINT(0x0275, 0xf), + INTEL_UEVENT_CONSTRAINT(0x0176, 0xf), + INTEL_UEVENT_CONSTRAINT(0x04a4, 0x1), + INTEL_UEVENT_CONSTRAINT(0x08a4, 0x1), + INTEL_UEVENT_CONSTRAINT(0x01cd, 0xfc), + INTEL_UEVENT_CONSTRAINT(0x02cd, 0x3), + + INTEL_EVENT_CONSTRAINT(0xd0, 0xf), + INTEL_EVENT_CONSTRAINT(0xd1, 0xf), + INTEL_EVENT_CONSTRAINT(0xd4, 0xf), + INTEL_EVENT_CONSTRAINT(0xd6, 0xf), + INTEL_EVENT_CONSTRAINT(0xdf, 0xf), + INTEL_EVENT_CONSTRAINT(0xce, 0x1), + + INTEL_UEVENT_CONSTRAINT(0x01b1, 0x8), + INTEL_UEVENT_CONSTRAINT(0x0847, 0xf), + INTEL_UEVENT_CONSTRAINT(0x0446, 0xf), + INTEL_UEVENT_CONSTRAINT(0x0846, 0xf), + INTEL_UEVENT_CONSTRAINT(0x0148, 0xf), + + EVENT_CONSTRAINT_END +}; + +static struct extra_reg intel_pnc_extra_regs[] __read_mostly =3D { + /* must define OMR_X first, see intel_alt_er() */ + INTEL_UEVENT_EXTRA_REG(0x012a, MSR_OMR_0, 0x40ffffff0000ffffull, OMR_0), + INTEL_UEVENT_EXTRA_REG(0x022a, MSR_OMR_1, 0x40ffffff0000ffffull, OMR_1), + INTEL_UEVENT_EXTRA_REG(0x042a, MSR_OMR_2, 0x40ffffff0000ffffull, OMR_2), + INTEL_UEVENT_EXTRA_REG(0x082a, MSR_OMR_3, 0x40ffffff0000ffffull, OMR_3), + INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), + INTEL_UEVENT_EXTRA_REG(0x02c6, MSR_PEBS_FRONTEND, 0x9, FE), + INTEL_UEVENT_EXTRA_REG(0x03c6, MSR_PEBS_FRONTEND, 0x7fff1f, FE), + INTEL_UEVENT_EXTRA_REG(0x40ad, MSR_PEBS_FRONTEND, 0xf, FE), + INTEL_UEVENT_EXTRA_REG(0x04c2, MSR_PEBS_FRONTEND, 0x8, FE), + EVENT_EXTRA_END +}; + EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=3D0x0b,umask=3D0x10,ldlat=3D3= "); EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=3D0xcd,umask=3D0x1,ldlat=3D3"= ); EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=3D0xcd,umask=3D0x2"); @@ -650,6 +706,102 @@ static __initconst const u64 glc_hw_cache_extra_regs }, }; =20 +static __initconst const u64 pnc_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] =3D +{ + [ C(L1D ) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x81d0, + [ C(RESULT_MISS) ] =3D 0xe124, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x82d0, + }, + }, + [ C(L1I ) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_MISS) ] =3D 0xe424, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D -1, + }, + }, + [ C(LL ) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x12a, + [ C(RESULT_MISS) ] =3D 0x12a, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x12a, + [ C(RESULT_MISS) ] =3D 0x12a, + }, + }, + [ C(DTLB) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x81d0, + [ C(RESULT_MISS) ] =3D 0xe12, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x82d0, + [ C(RESULT_MISS) ] =3D 0xe13, + }, + }, + [ C(ITLB) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D 0xe11, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D -1, + }, + [ C(OP_PREFETCH) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D -1, + }, + }, + [ C(BPU ) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x4c4, + [ C(RESULT_MISS) ] =3D 0x4c5, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D -1, + }, + [ C(OP_PREFETCH) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D -1, + }, + }, + [ C(NODE) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D -1, + [ C(RESULT_MISS) ] =3D -1, + }, + }, +}; + +static __initconst const u64 pnc_hw_cache_extra_regs + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] =3D +{ + [ C(LL ) ] =3D { + [ C(OP_READ) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x4000000000000001, + [ C(RESULT_MISS) ] =3D 0xFFFFF000000001, + }, + [ C(OP_WRITE) ] =3D { + [ C(RESULT_ACCESS) ] =3D 0x4000000000000002, + [ C(RESULT_MISS) ] =3D 0xFFFFF000000002, + }, + }, +}; + /* * Notes on the events: * - data reads do not include code reads (comparable to earlier tables) @@ -7225,6 +7377,20 @@ static __always_inline void intel_pmu_init_lnc(struc= t pmu *pmu) hybrid(pmu, extra_regs) =3D intel_lnc_extra_regs; } =20 +static __always_inline void intel_pmu_init_pnc(struct pmu *pmu) +{ + intel_pmu_init_glc(pmu); + x86_pmu.flags &=3D ~PMU_FL_HAS_RSP_1; + x86_pmu.flags |=3D PMU_FL_HAS_OMR; + memcpy(hybrid_var(pmu, hw_cache_event_ids), + pnc_hw_cache_event_ids, sizeof(hw_cache_event_ids)); + memcpy(hybrid_var(pmu, hw_cache_extra_regs), + pnc_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); + hybrid(pmu, event_constraints) =3D intel_pnc_event_constraints; + hybrid(pmu, pebs_constraints) =3D intel_pnc_pebs_event_constraints; + hybrid(pmu, extra_regs) =3D intel_pnc_extra_regs; +} + static __always_inline void intel_pmu_init_skt(struct pmu *pmu) { intel_pmu_init_grt(pmu); @@ -7897,6 +8063,22 @@ __init int intel_pmu_init(void) intel_pmu_pebs_data_source_skl(true); break; =20 + case INTEL_DIAMONDRAPIDS_X: + intel_pmu_init_pnc(NULL); + x86_pmu.pebs_ept =3D 1; + x86_pmu.hw_config =3D hsw_hw_config; + x86_pmu.pebs_latency_data =3D pnc_latency_data; + x86_pmu.get_event_constraints =3D glc_get_event_constraints; + extra_attr =3D boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; + extra_skl_attr =3D skl_format_attr; + mem_attr =3D glc_events_attrs; + td_attr =3D glc_td_events_attrs; + tsx_attr =3D glc_tsx_events_attrs; + pr_cont("Panthercove events, "); + name =3D "panthercove"; + break; + case INTEL_ALDERLAKE: case INTEL_ALDERLAKE_L: case INTEL_RAPTORLAKE: diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 0b62e1f64f33..0db6ffc7007e 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -1424,6 +1424,33 @@ struct event_constraint intel_lnc_pebs_event_constra= ints[] =3D { EVENT_CONSTRAINT_END }; =20 +struct event_constraint intel_pnc_pebs_event_constraints[] =3D { + INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL), /* INST_RETIRED.PRE= C_DIST */ + INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), + + INTEL_HYBRID_LDLAT_CONSTRAINT(0x1cd, 0xfc), + INTEL_HYBRID_STLAT_CONSTRAINT(0x2cd, 0x3), + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED= .STLB_MISS_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED= .STLB_MISS_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED= .LOCK_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED= .SPLIT_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED= .SPLIT_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED= .ALL_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED= .ALL_STORES */ + + INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), + + INTEL_FLAGS_EVENT_CONSTRAINT(0xd0, 0xf), + INTEL_FLAGS_EVENT_CONSTRAINT(0xd6, 0xf), + + /* + * Everything else is handled by PMU_FL_PEBS_ALL, because we + * need the full constraints from the main table. + */ + + EVENT_CONSTRAINT_END +}; + struct event_constraint *intel_pebs_constraints(struct perf_event *event) { struct event_constraint *pebs_constraints =3D hybrid(event->pmu, pebs_con= straints); diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index bd501c2a0f73..cbca1888e8f7 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1698,6 +1698,8 @@ extern struct event_constraint intel_glc_pebs_event_c= onstraints[]; =20 extern struct event_constraint intel_lnc_pebs_event_constraints[]; =20 +extern struct event_constraint intel_pnc_pebs_event_constraints[]; + struct event_constraint *intel_pebs_constraints(struct perf_event *event); =20 void intel_pmu_pebs_add(struct perf_event *event); --=20 2.34.1 From nobody Tue Dec 2 02:05:17 2025 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 0CA30302CDB; Thu, 20 Nov 2025 05:37:19 +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=1763617040; cv=none; b=pQQ0RZlCXVuqtXwB8SYVKiR6h+xj8S3d5HeaCt0WgvQoRPPe8lVe76FgRiM0zLp4Z41bKowEeZxFSLph/fvAoB1Zat8ugtxBYKhKYZmpxt1tJ+B6fOPSZ9HoWxmCNnYGstIlmsV+nyz3qeAUJdSupnPqI/R/4dL0T2P2NyrNiRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617040; c=relaxed/simple; bh=3nPLc6AN1mkX+nVuqsfQbjvdtBX9H5HtKheVv+b1h9A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EwijTCOo+5ReDWeKGmqnhCU4WD8zJq9ePVJPIguBRZlOE7BgCYvTIwN+M0uWpIq6aXbYkHyfXJmNdvU0cXvCIfV6pBoNgQTfuPFgGZxG6nsFpymQrs4H7y5ISENGxrUAv82Lty29MYSVltPjp7v+U7zyrMVxwiNBoOmHCnvQ2JQ= 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=cjOturJI; 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="cjOturJI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617039; x=1795153039; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3nPLc6AN1mkX+nVuqsfQbjvdtBX9H5HtKheVv+b1h9A=; b=cjOturJICN9pNaKVLw5CXyfKODyVUr7HKPWbSfYKj6JVFffoD/h/wV/g BexKDoM+dezy3b7KVLF5F8MLTsHfIuunAZd8mhyyjwEBCfQNOm9AOlKyh IFXIrvR9+qlUcNkSOvQzlAWxLkhuCXgvHqypQExNcfKcvWqSTrWFgTGO2 e60mtuxDvJwXkZdKIQFZqSHri7Y97GjPjRGm0C55J/1tzmQ3tj7npYQkE NWoTT/wuucO6EJcT3Tx7bzrY8c1phNrBpdzlAg6Y00nazIy1OlQsLkCMU 8tz8mAYoyHW770xH1rwX7kq1jMSZk+5AhTK3EIbBiEmKmWVTqYDiGjBA8 w==; X-CSE-ConnectionGUID: dWX0Wk78QFC9nh+sNdRhmA== X-CSE-MsgGUID: XOr0M8LZTyOru+CfUrcWrg== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710178" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710178" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:18 -0800 X-CSE-ConnectionGUID: Om2IvvEGQJep3KQtk39gBQ== X-CSE-MsgGUID: ZwCqrg9eQjev8y/ip9gpZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055559" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:15 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 4/7] perf/x86/intel: Add support for PEBS memory auxiliary info field in NVL Date: Thu, 20 Nov 2025 13:34:28 +0800 Message-Id: <20251120053431.491677-5-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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" Similar to DMR (Panther Cove uarch), both P-core (Coyote Cove uarch) and E-core (Arctic Wolf uarch) of NVL adopt the new PEBS memory auxiliary info layout. Coyote Cove microarchitecture shares the same PMU capabilities, including the memory auxiliary info layout, with Panther Cove. Arctic Wolf microarchitecture has a similar layout to Panther Cove, with the only difference being specific data source encoding for L2 hit cases (up to the L2 cache level). The OMR encoding remains the same as in Panther Cove. For detailed information on the memory auxiliary info encoding, please refer to section 16.2 "PEBS LOAD LATENCY AND STORE LATENCY FACILITY" in the latest ISE documentation. This patch defines Arctic Wolf specific data source encoding and then supports PEBS memory auxiliary info field for NVL. ISE: https://www.intel.com/content/www/us/en/content-details/869288/intel-a= rchitecture-instruction-set-extensions-programming-reference.html Signed-off-by: Dapeng Mi --- arch/x86/events/intel/ds.c | 83 ++++++++++++++++++++++++++++++++++++ arch/x86/events/perf_event.h | 2 + 2 files changed, 85 insertions(+) diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 0db6ffc7007e..d082eb160a10 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -96,6 +96,18 @@ union intel_x86_pebs_dse { unsigned int pnc_fb_full:1; unsigned int ld_reserved8:16; }; + struct { + unsigned int arw_dse:8; + unsigned int arw_l2_miss:1; + unsigned int arw_xq_promotion:1; + unsigned int arw_reissue:1; + unsigned int arw_stlb_miss:1; + unsigned int arw_locked:1; + unsigned int arw_data_blk:1; + unsigned int arw_addr_blk:1; + unsigned int arw_fb_full:1; + unsigned int ld_reserved9:16; + }; }; =20 =20 @@ -274,6 +286,29 @@ static u64 pnc_pebs_l2_hit_data_source[PNC_PEBS_DATA_S= OURCE_MAX] =3D { OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0f: uncached */ }; =20 +/* Version for Arctic Wolf and later */ + +/* L2 hit */ +#define ARW_PEBS_DATA_SOURCE_MAX 16 +static u64 arw_pebs_l2_hit_data_source[ARW_PEBS_DATA_SOURCE_MAX] =3D { + P(OP, LOAD) | P(LVL, NA) | LEVEL(NA) | P(SNOOP, NA), /* 0x00: non-cache a= ccess */ + OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 hit */ + OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x02: WCB Hit */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x03: L2 Hit Clean */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, HIT), /* 0x04: L2 Hit Snoop HI= T */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, HITM), /* 0x05: L2 Hit Snoop H= it Modified */ + OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x06: uncached */ + 0, /* 0x07: Reserved */ + 0, /* 0x08: Reserved */ + 0, /* 0x09: Reserved */ + 0, /* 0x0a: Reserved */ + 0, /* 0x0b: Reserved */ + 0, /* 0x0c: Reserved */ + 0, /* 0x0d: Reserved */ + 0, /* 0x0e: Reserved */ + 0, /* 0x0f: Reserved */ +}; + /* L2 miss */ #define OMR_DATA_SOURCE_MAX 16 static u64 omr_data_source[OMR_DATA_SOURCE_MAX] =3D { @@ -457,6 +492,44 @@ u64 cmt_latency_data(struct perf_event *event, u64 sta= tus) dse.mtl_fwd_blk); } =20 +static u64 arw_latency_data(struct perf_event *event, u64 status) +{ + union intel_x86_pebs_dse dse; + union perf_mem_data_src src; + u64 val; + + dse.val =3D status; + + if (!dse.arw_l2_miss) + val =3D arw_pebs_l2_hit_data_source[dse.arw_dse & 0xf]; + else + val =3D parse_omr_data_source(dse.arw_dse); + + if (!val) + val =3D P(OP, LOAD) | LEVEL(NA) | P(SNOOP, NA); + + if (dse.arw_stlb_miss) + val |=3D P(TLB, MISS) | P(TLB, L2); + else + val |=3D P(TLB, HIT) | P(TLB, L1) | P(TLB, L2); + + if (dse.arw_locked) + val |=3D P(LOCK, LOCKED); + + if (dse.arw_data_blk) + val |=3D P(BLK, DATA); + if (dse.arw_addr_blk) + val |=3D P(BLK, ADDR); + if (!dse.arw_data_blk && !dse.arw_addr_blk) + val |=3D P(BLK, NA); + + src.val =3D val; + if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) + src.mem_op =3D P(OP, STORE); + + return src.val; +} + static u64 lnc_latency_data(struct perf_event *event, u64 status) { union intel_x86_pebs_dse dse; @@ -550,6 +623,16 @@ u64 pnc_latency_data(struct perf_event *event, u64 sta= tus) return src.val; } =20 +u64 nvl_latency_data(struct perf_event *event, u64 status) +{ + struct x86_hybrid_pmu *pmu =3D hybrid_pmu(event->pmu); + + if (pmu->pmu_type =3D=3D hybrid_small) + return arw_latency_data(event, status); + + return pnc_latency_data(event, status); +} + static u64 load_latency_data(struct perf_event *event, u64 status) { union intel_x86_pebs_dse dse; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index cbca1888e8f7..aedc1a7762c2 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1666,6 +1666,8 @@ u64 arl_h_latency_data(struct perf_event *event, u64 = status); =20 u64 pnc_latency_data(struct perf_event *event, u64 status); =20 +u64 nvl_latency_data(struct perf_event *event, u64 status); + extern struct event_constraint intel_core2_pebs_event_constraints[]; =20 extern struct event_constraint intel_atom_pebs_event_constraints[]; --=20 2.34.1 From nobody Tue Dec 2 02:05:17 2025 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 0DE76301472; Thu, 20 Nov 2025 05:37:31 +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=1763617054; cv=none; b=CiMFb0E8TYArxn2Cawmx6VWWcD0YIxuXX4ndwg3R5XP7HkKnFsEeWlwemvR1MNlJ7UwzFI5qsz/5st6rg5/0iCs8S9jJLWOSAYb54BAV52oSBlyg56Tf0Aj8oHxAwP3w++Bwje4XUlpKhEI8emPFtA/rNpaYD2Acs2ubPTRIXr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617054; c=relaxed/simple; bh=lZBbp+H21/A2cYsJZkoGZbNA1rryNfZ+cMVHMwgGU6k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LSn5DIG0CYwEoGR/2GQsRoNEu7N/0dpP1Dh7N4PwegX+EP58+ez9gVNarv9JGuRCj5KWilIA9uhjkbAtdsqGqyIA4T3BA2k4+gCHPmL7LQF9uNRvchcAs62IT/e7l8Lac51EvAycRrIZUyZlYOZ83gbYEGW3/1luUoVO7ljvDnE= 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=HCZzNBnv; 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="HCZzNBnv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617052; x=1795153052; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lZBbp+H21/A2cYsJZkoGZbNA1rryNfZ+cMVHMwgGU6k=; b=HCZzNBnvMJLhDtF33+h6JbftAx2PRJkd5rKZEIifs8EKVzJWmJVJcpp4 AZyLEZ+TpnLQAiB3c/FqN8nIosHPetFPTXOQwnoFspt8AfMA5q0C37qmk TRly2I2TgxqyQ66I1jV0/9ps0SzbQsyg676+5gKaINJbejp7Nsjuo5yPq grYwVTRqbBAB8SXEa0BqzyfrE2IN5vKmtmQl7Gwex0Wg0vsNoG70JzsaD 8vM48YaxBM3nZhzwaLL+gxCkMudjJordo60K/2JQh5WsOlpP6g81UGP/d eMCLoBgCsAd0VIhkLlrNphNVQUlsvIRztkt3wWnuUsZs2LXg9X8+KYFIr w==; X-CSE-ConnectionGUID: kgOjhIDASrGDAJIt7EBjIg== X-CSE-MsgGUID: UmE0cpLsQfOHbLIxKDjARw== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710198" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710198" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:22 -0800 X-CSE-ConnectionGUID: iFQbWkp8TVaqJL64cOypsA== X-CSE-MsgGUID: fki4ppnORdyfLXSXJmDEHQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055563" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:19 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 5/7] perf/x86/intel: Add core PMU support for Novalake Date: Thu, 20 Nov 2025 13:34:29 +0800 Message-Id: <20251120053431.491677-6-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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" This patch enables core PMU support for Novalake, covering both P-core and E-core. It includes Arctic Wolf-specific counters, PEBS constraints, and the OMR registers table. Since Coyote Cove shares the same PMU capabilities as Panther Cove, the existing Panther Cove PMU enabling functions are reused for Coyote Cove. For detailed information about counter constraints, please refer to section 16.3 "COUNTER RESTRICTIONS" in the ISE documentation. ISE: https://www.intel.com/content/www/us/en/content-details/869288/intel-a= rchitecture-instruction-set-extensions-programming-reference.html Signed-off-by: Dapeng Mi --- arch/x86/events/intel/core.c | 99 ++++++++++++++++++++++++++++++++++++ arch/x86/events/intel/ds.c | 11 ++++ arch/x86/events/perf_event.h | 2 + 3 files changed, 112 insertions(+) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 9f2a93fe23df..a3a1e6e670f8 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -232,6 +232,29 @@ static struct event_constraint intel_skt_event_constra= ints[] __read_mostly =3D { EVENT_CONSTRAINT_END }; =20 +static struct event_constraint intel_arw_event_constraints[] __read_mostly= =3D { + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + FIXED_EVENT_CONSTRAINT(0x0300, 2), /* pseudo CPU_CLK_UNHALTED.REF */ + FIXED_EVENT_CONSTRAINT(0x013c, 2), /* CPU_CLK_UNHALTED.REF_TSC_P */ + FIXED_EVENT_CONSTRAINT(0x0073, 4), /* TOPDOWN_BAD_SPECULATION.ALL */ + FIXED_EVENT_CONSTRAINT(0x019c, 5), /* TOPDOWN_FE_BOUND.ALL */ + FIXED_EVENT_CONSTRAINT(0x02c2, 6), /* TOPDOWN_RETIRING.ALL */ + INTEL_UEVENT_CONSTRAINT(0x01b7, 0x1), + INTEL_UEVENT_CONSTRAINT(0x02b7, 0x2), + INTEL_UEVENT_CONSTRAINT(0x04b7, 0x4), + INTEL_UEVENT_CONSTRAINT(0x08b7, 0x8), + INTEL_UEVENT_CONSTRAINT(0x01d4, 0x1), + INTEL_UEVENT_CONSTRAINT(0x02d4, 0x2), + INTEL_UEVENT_CONSTRAINT(0x04d4, 0x4), + INTEL_UEVENT_CONSTRAINT(0x08d4, 0x8), + INTEL_UEVENT_CONSTRAINT(0x0175, 0x1), + INTEL_UEVENT_CONSTRAINT(0x0275, 0x2), + INTEL_UEVENT_CONSTRAINT(0x21d3, 0x1), + INTEL_UEVENT_CONSTRAINT(0x22d3, 0x1), + EVENT_CONSTRAINT_END +}; + static struct event_constraint intel_skl_event_constraints[] =3D { FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ @@ -2319,6 +2342,26 @@ static __initconst const u64 tnt_hw_cache_extra_regs }, }; =20 +static __initconst const u64 arw_hw_cache_extra_regs + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] =3D { + [C(LL)] =3D { + [C(OP_READ)] =3D { + [C(RESULT_ACCESS)] =3D 0x4000000000000001, + [C(RESULT_MISS)] =3D 0xFFFFF000000001, + }, + [C(OP_WRITE)] =3D { + [C(RESULT_ACCESS)] =3D 0x4000000000000002, + [C(RESULT_MISS)] =3D 0xFFFFF000000002, + }, + [C(OP_PREFETCH)] =3D { + [C(RESULT_ACCESS)] =3D 0x0, + [C(RESULT_MISS)] =3D 0x0, + }, + }, +}; + EVENT_ATTR_STR(topdown-fe-bound, td_fe_bound_tnt, "event=3D0x= 71,umask=3D0x0"); EVENT_ATTR_STR(topdown-retiring, td_retiring_tnt, "event=3D0x= c2,umask=3D0x0"); EVENT_ATTR_STR(topdown-bad-spec, td_bad_spec_tnt, "event=3D0x= 73,umask=3D0x6"); @@ -2377,6 +2420,22 @@ static struct extra_reg intel_cmt_extra_regs[] __rea= d_mostly =3D { EVENT_EXTRA_END }; =20 +static struct extra_reg intel_arw_extra_regs[] __read_mostly =3D { + /* must define OMR_X first, see intel_alt_er() */ + INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OMR_0, 0xc0ffffffffffffffull, OMR_0), + INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OMR_1, 0xc0ffffffffffffffull, OMR_1), + INTEL_UEVENT_EXTRA_REG(0x04b7, MSR_OMR_2, 0xc0ffffffffffffffull, OMR_2), + INTEL_UEVENT_EXTRA_REG(0x08b7, MSR_OMR_3, 0xc0ffffffffffffffull, OMR_3), + INTEL_UEVENT_EXTRA_REG(0x01d4, MSR_OMR_0, 0xc0ffffffffffffffull, OMR_0), + INTEL_UEVENT_EXTRA_REG(0x02d4, MSR_OMR_1, 0xc0ffffffffffffffull, OMR_1), + INTEL_UEVENT_EXTRA_REG(0x04d4, MSR_OMR_2, 0xc0ffffffffffffffull, OMR_2), + INTEL_UEVENT_EXTRA_REG(0x08d4, MSR_OMR_3, 0xc0ffffffffffffffull, OMR_3), + INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x5d0), + INTEL_UEVENT_EXTRA_REG(0x0127, MSR_SNOOP_RSP_0, 0xffffffffffffffffull, SN= OOP_0), + INTEL_UEVENT_EXTRA_REG(0x0227, MSR_SNOOP_RSP_1, 0xffffffffffffffffull, SN= OOP_1), + EVENT_EXTRA_END +}; + EVENT_ATTR_STR(topdown-fe-bound, td_fe_bound_skt, "event=3D0x= 9c,umask=3D0x01"); EVENT_ATTR_STR(topdown-retiring, td_retiring_skt, "event=3D0x= c2,umask=3D0x02"); EVENT_ATTR_STR(topdown-be-bound, td_be_bound_skt, "event=3D0x= a4,umask=3D0x02"); @@ -7399,6 +7458,19 @@ static __always_inline void intel_pmu_init_skt(struc= t pmu *pmu) static_call_update(intel_pmu_enable_acr_event, intel_pmu_enable_acr); } =20 +static __always_inline void intel_pmu_init_arw(struct pmu *pmu) +{ + intel_pmu_init_grt(pmu); + x86_pmu.flags &=3D ~PMU_FL_HAS_RSP_1; + x86_pmu.flags |=3D PMU_FL_HAS_OMR; + memcpy(hybrid_var(pmu, hw_cache_extra_regs), + arw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); + hybrid(pmu, event_constraints) =3D intel_arw_event_constraints; + hybrid(pmu, pebs_constraints) =3D intel_arw_pebs_event_constraints; + hybrid(pmu, extra_regs) =3D intel_arw_extra_regs; + static_call_update(intel_pmu_enable_acr_event, intel_pmu_enable_acr); +} + __init int intel_pmu_init(void) { struct attribute **extra_skl_attr =3D &empty_attrs; @@ -8239,6 +8311,33 @@ __init int intel_pmu_init(void) name =3D "arrowlake_h_hybrid"; break; =20 + case INTEL_NOVALAKE: + case INTEL_NOVALAKE_L: + pr_cont("Novalake Hybrid events, "); + name =3D "novalake_hybrid"; + intel_pmu_init_hybrid(hybrid_big_small); + + x86_pmu.pebs_latency_data =3D nvl_latency_data; + x86_pmu.get_event_constraints =3D mtl_get_event_constraints; + x86_pmu.hw_config =3D adl_hw_config; + + td_attr =3D lnl_hybrid_events_attrs; + mem_attr =3D mtl_hybrid_mem_attrs; + tsx_attr =3D adl_hybrid_tsx_attrs; + extra_attr =3D boot_cpu_has(X86_FEATURE_RTM) ? + mtl_hybrid_extra_attr_rtm : mtl_hybrid_extra_attr; + + /* Initialize big core specific PerfMon capabilities.*/ + pmu =3D &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX]; + intel_pmu_init_pnc(&pmu->pmu); + + /* Initialize Atom core specific PerfMon capabilities.*/ + pmu =3D &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX]; + intel_pmu_init_arw(&pmu->pmu); + + intel_pmu_pebs_data_source_lnl(); + break; + default: switch (x86_pmu.version) { case 1: diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index d082eb160a10..c6aec7765c02 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -1292,6 +1292,17 @@ struct event_constraint intel_grt_pebs_event_constra= ints[] =3D { EVENT_CONSTRAINT_END }; =20 +struct event_constraint intel_arw_pebs_event_constraints[] =3D { + /* Allow all events as PEBS with no flags */ + INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0xff), + INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0xff), + INTEL_FLAGS_UEVENT_CONSTRAINT(0x01d4, 0x1), + INTEL_FLAGS_UEVENT_CONSTRAINT(0x02d4, 0x2), + INTEL_FLAGS_UEVENT_CONSTRAINT(0x04d4, 0x4), + INTEL_FLAGS_UEVENT_CONSTRAINT(0x08d4, 0x8), + EVENT_CONSTRAINT_END +}; + struct event_constraint intel_nehalem_pebs_event_constraints[] =3D { INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */ INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index aedc1a7762c2..f7caabc5d487 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1680,6 +1680,8 @@ extern struct event_constraint intel_glp_pebs_event_c= onstraints[]; =20 extern struct event_constraint intel_grt_pebs_event_constraints[]; =20 +extern struct event_constraint intel_arw_pebs_event_constraints[]; + extern struct event_constraint intel_nehalem_pebs_event_constraints[]; =20 extern struct event_constraint intel_westmere_pebs_event_constraints[]; --=20 2.34.1 From nobody Tue Dec 2 02:05:17 2025 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 E742C30146E; Thu, 20 Nov 2025 05:37:32 +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=1763617054; cv=none; b=ZnPsCCPIRfzGSP7LptDmaBbNyVcbrJajnSJNkApv8Y/4/9viuS3mUFIpctZSxzKWffXaXRcE56mQ2cuOG95dKGQur1TXLFE0ac4yKDBpvRoHxyPB1Xu9/H8EdHBeclcbb6bMbwWoNkwJ66IEtSETboX3duzj6A/RTPLT2t7xUi8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617054; c=relaxed/simple; bh=ET01FWIucwbW1EkoINqz0VA9PNL+kELjKgw55gDCLD0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uI2ph7RnFv6kXDA3Magbo+Z1QMpjnm9aNKQEiVtTiuhn6qWKWJyvVMKLM2tE98kq4puhKm/UheZxbFATweMVKwxvM21udBQsayGeFTjL8jCx9UWNAc10ZM1LPZomLHdyrlS5gVwOMnyP7ZumojwwmrUHByq0zpV5kr+yLj/sOHY= 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=ejU7Zplv; 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="ejU7Zplv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617053; x=1795153053; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ET01FWIucwbW1EkoINqz0VA9PNL+kELjKgw55gDCLD0=; b=ejU7ZplvHJr9/TurBvSz83pzwXNtEi4qM9Tl4WRu+yAJxuKUvuStqWYT xgoh1s9DoZK1WXftU3vGkYqmM54LndqqvMmxS5lDhLZtZZkL9JEVTJN2B Uy1ywdLvihNO0djw21OCiZ2UCfmEgP8goOck/cQCHYzoqFCgFNAt2KKB2 iTzd1MweXWvkOliPhaGIiWQ/7WvyALDgIvH5no4A+i4ftISlmyQxEr6Fz 5MbHcpuygp3mttW+HnUN94PZBYS0sMa1uB/cfxX21UwzEnBna6VVQvFuf MVTKSIDd6/k5FBbKdkf8I7bYbv1G5otiRKR1zPTQife6y5iruzsTheIbx A==; X-CSE-ConnectionGUID: 6l8anKifT+icWXnALtT7tg== X-CSE-MsgGUID: DAbVRSNqSfyGk2F56T3rAQ== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710211" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710211" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:26 -0800 X-CSE-ConnectionGUID: FJ7cEH7CQbaxaUYIXwe4oA== X-CSE-MsgGUID: m0tbSXxhQ8qv8mJEAmRzhg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055570" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:23 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 6/7] perf/x86: Replace magic numbers with macros for attr_rdpmc Date: Thu, 20 Nov 2025 13:34:30 +0800 Message-Id: <20251120053431.491677-7-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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" Use macros to replace these attr_rdpmc magic numbers, so users are easy to know their meaning. Signed-off-by: Dapeng Mi --- arch/x86/events/core.c | 7 ++++--- arch/x86/events/intel/p6.c | 2 +- arch/x86/events/perf_event.h | 7 +++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 5d0d5e466c62..3d9cc1d7fcfa 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2129,7 +2129,8 @@ static int __init init_hw_perf_events(void) =20 pr_cont("%s PMU driver.\n", x86_pmu.name); =20 - x86_pmu.attr_rdpmc =3D 1; /* enable userspace RDPMC usage by default */ + /* enable userspace RDPMC usage by default */ + x86_pmu.attr_rdpmc =3D X86_USER_RDPMC_CONDITIONAL_ENABLE; =20 for (quirk =3D x86_pmu.quirks; quirk; quirk =3D quirk->next) quirk->func(); @@ -2609,12 +2610,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev, */ if (val =3D=3D 0) static_branch_inc(&rdpmc_never_available_key); - else if (x86_pmu.attr_rdpmc =3D=3D 0) + else if (x86_pmu.attr_rdpmc =3D=3D X86_USER_RDPMC_NEVER_ENABLE) static_branch_dec(&rdpmc_never_available_key); =20 if (val =3D=3D 2) static_branch_inc(&rdpmc_always_available_key); - else if (x86_pmu.attr_rdpmc =3D=3D 2) + else if (x86_pmu.attr_rdpmc =3D=3D X86_USER_RDPMC_ALWAYS_ENABLE) static_branch_dec(&rdpmc_always_available_key); =20 on_each_cpu(cr4_update_pce, NULL, 1); diff --git a/arch/x86/events/intel/p6.c b/arch/x86/events/intel/p6.c index 6e41de355bd8..fb991e0ac614 100644 --- a/arch/x86/events/intel/p6.c +++ b/arch/x86/events/intel/p6.c @@ -243,7 +243,7 @@ static __init void p6_pmu_rdpmc_quirk(void) */ pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n"); x86_pmu.attr_rdpmc_broken =3D 1; - x86_pmu.attr_rdpmc =3D 0; + x86_pmu.attr_rdpmc =3D X86_USER_RDPMC_NEVER_ENABLE; } } =20 diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index f7caabc5d487..24a81d2916e9 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -187,6 +187,13 @@ struct amd_nb { (1ULL << PERF_REG_X86_R14) | \ (1ULL << PERF_REG_X86_R15)) =20 +/* user space rdpmc control values */ +enum { + X86_USER_RDPMC_NEVER_ENABLE =3D 0, + X86_USER_RDPMC_CONDITIONAL_ENABLE =3D 1, + X86_USER_RDPMC_ALWAYS_ENABLE =3D 2, +}; + /* * Per register state. */ --=20 2.34.1 From nobody Tue Dec 2 02:05:17 2025 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 2172B2DEA7D; Thu, 20 Nov 2025 05:37:34 +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=1763617056; cv=none; b=TcvTvc5wjMZUZTFnQYhdcVC59N8qDes4olPL/jxyJXcNclMMJQmY68Pg4X4omP+oPGa58EJk6TpbqEw7D/H+jYmyXh63GtM9Q0UrvoRzjfTmipdxpEqy8g7RwMMtAX8BvKLyTI6QdwXUphvgbru2CtY739BqfXbF43RsvSRMYE8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763617056; c=relaxed/simple; bh=//SJ3p96bcLZLRA1fnT35iANmrZA6Yo+TEo+v5I8b/w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=p7XAPu6WJXYTaC395xeL3GXbe6EnBC2lwOIWn0Wbw1n9EpHi0JmeRktbWqFVcSMlCWBV+lSilkQV6jcUaC0LBDbghLIMn0j4tbCUBffbCcvcft5tkFmRXX0c7CQyvt9bZ13uMsyxE3bVQORJzQOLHsV7l9S1ScYtG3U+j+yOPao= 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=HO06fiZU; 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="HO06fiZU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1763617054; x=1795153054; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=//SJ3p96bcLZLRA1fnT35iANmrZA6Yo+TEo+v5I8b/w=; b=HO06fiZUzB0uYoKLPuLGeQw0CKqoghuzL0Kc61oPDorAxN0YEU2CCUol RazkixCdAUc7BTt8Y+ZNiasEPSxhtQ72cCkVy6VvyCEs36B4guSAoqnKq koewwAaetXOnvE6+81j39ujYDHl8oMzH5uIxGRTfLBqdTdiM5b7fp/cqb W9RMa5EEomal3FiNWozVI/FnnMPvhnU/l339eRrRNQaP6IOA7RAqIwJCd YEvUx385hBBgacygGFuoa046dAtWy3j0WlsBPthfjlEO5TvPSpB16GkNm ayVvDM3WirJVoiyWk6YLxq81cGz1s1hmAM1m+idQ5i/Ew/GT2pvksCot+ g==; X-CSE-ConnectionGUID: K4biVyphTGe2I2Yg02/tqw== X-CSE-MsgGUID: p4wrZex7SDaARH4TPZ29PQ== X-IronPort-AV: E=McAfee;i="6800,10657,11618"; a="65710220" X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="65710220" Received: from orviesa009.jf.intel.com ([10.64.159.149]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2025 21:37:31 -0800 X-CSE-ConnectionGUID: E4HTZrC7TBCoAGAs7LNTIw== X-CSE-MsgGUID: B9/feN8US5ugDVNpJ5nYEA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,317,1754982000"; d="scan'208";a="191055574" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa009.jf.intel.com with ESMTP; 19 Nov 2025 21:37:27 -0800 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin , Andi Kleen , Eranian Stephane Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Dapeng Mi , Zide Chen , Falcon Thomas , Xudong Hao , Dapeng Mi Subject: [PATCH 7/7] perf/x86/intel: Add rdpmc-user-disable support Date: Thu, 20 Nov 2025 13:34:31 +0800 Message-Id: <20251120053431.491677-8-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251120053431.491677-1-dapeng1.mi@linux.intel.com> References: <20251120053431.491677-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: quoted-printable Since panther cove starts, rdpmc user disable feature would be supported. This feature affords perf system the capability to disable user space rdpmc read in counter level. Currently when a global counter is active any user with rdpmc right can read it, even though the perf access permissions may forbid it (e.g. may not allow reading ring 0 counters) This rdpmc user disable feature would mitigate this security concern. The details are - New RDPMC_USR_DISABLE bit in each EVNTSELx[37] MSR to indicate counter can't be read by RDPMC in ring 3. - New RDPMC_USR_DISABLE bits in bits 33,37,41,45 in IA32_FIXED_CTR_CTRL MSR for fixed counters 0-3. - On RDPMC for counter x, use select to choose the final counter value: If (!CPL0 && RDPMC_USR_DISABLE[x] =3D=3D 1 ) ? 0 : counter_value - RDPMC_USR_DISABLE is enumerated by CPUID.0x23.0.EBX[2]. This patch extends current global user space rdpmc control logic by `sysfs interface (sys/devices/cpu/rdpmc) as below. - rdpmc =3D 0 global user space rdpmc and counter level's user space rdpmc of all counters are both disabled. - rdpmc =3D 1 global user space rdpmc is enabled in mmap enabled time window and counter level=E2=80=99s user space rdpmc is only enabled for non system-w= ide events. This won't introduce counter data leak as count data would be cleared when context switches. - rdpmc =3D 2 global user space rdpmc and counter level=E2=80=99s user space rdpmc of a= ll counters are enabled unconditionally. The new changed rdpmc only affects the new activiated perf events, current active perf events won't be impacted. This makes code simpler and cleaner. BTW, the default value of rdpmc is not changed and is still 1. For more details about rdpmc user disable, please refer to chapter 15 "RDPMC USER DISABLE" in ISE documentation. ISE: https://www.intel.com/content/www/us/en/content-details/869288/intel-a= rchitecture-instruction-set-extensions-programming-reference.html Signed-off-by: Dapeng Mi --- .../sysfs-bus-event_source-devices-rdpmc | 40 +++++++++++++++++++ arch/x86/events/core.c | 21 ++++++++++ arch/x86/events/intel/core.c | 26 ++++++++++++ arch/x86/events/perf_event.h | 6 +++ arch/x86/include/asm/perf_event.h | 8 +++- 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-event_source-device= s-rdpmc diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-rdpmc= b/Documentation/ABI/testing/sysfs-bus-event_source-devices-rdpmc new file mode 100644 index 000000000000..d004527ab13e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-rdpmc @@ -0,0 +1,40 @@ +What: /sys/bus/event_source/devices/cpu.../rdpmc +Date: November 2011 +KernelVersion: 3.10 +Contact: Linux kernel mailing list linux-kernel@vger.kernel.org +Description: The /sys/bus/event_source/devices/cpu.../rdpmc attribute + is used to show/manage if rdpmc instruction can be + executed in user space. This attribute supports 3 numbers. + - rdpmc =3D 0 + user space rdpmc is globally disabled for all PMU + counters. + - rdpmc =3D 1 + user space rdpmc is globally enabled only in event mmap + ioctl called time window. If the mmap region is unmapped, + user space rdpmc is disabled again. + - rdpmc =3D 2 + user space rdpmc is globally enabled for all PMU + counters. + + In the Intel platforms supporting counter level's user + space rdpmc disable feature (CPUID.23H.EBX[2] =3D 1), the + meaning of 3 numbers is extended to + - rdpmc =3D 0 + global user space rdpmc and counter level's user space + rdpmc of all counters are both disabled. + - rdpmc =3D 1 + No changes on behavior of global user space rdpmc. + counter level's rdpmc of system-wide events is disabled + but counter level's rdpmc of non-system-wide events is + enabled. + - rdpmc =3D 2 + global user space rdpmc and counter level's user space + rdpmc of all counters are both enabled unconditionally. + + The default value of rdpmc is 1. + + Please notice global user space rdpmc's behavior would + change immediately along with the rdpmc value's change, + but the behavior of counter level's user space rdpmc + won't take effect immediately until the event is + reactivated or recreated. diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 3d9cc1d7fcfa..c1969cc2bb0c 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2582,6 +2582,27 @@ static ssize_t get_attr_rdpmc(struct device *cdev, return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc); } =20 +/* + * Behaviors of rdpmc value: + * - rdpmc =3D 0 + * global user space rdpmc and counter level's user space rdpmc of all + * counters are both disabled. + * - rdpmc =3D 1 + * global user space rdpmc is enabled in mmap enabled time window and + * counter level's user space rdpmc is enabled for only non system-wide + * events. Counter level's user space rdpmc of system-wide events is + * still disabled by default. This won't introduce counter data leak for + * non system-wide events since their count data would be cleared when + * context switches. + * - rdpmc =3D 2 + * global user space rdpmc and counter level's user space rdpmc of all + * counters are enabled unconditionally. + * + * Suppose the rdpmc value won't be changed frequently, don't dynamically + * reschedule events to make the new rpdmc value take effect on active perf + * events immediately, the new rdpmc value would only impact the new + * activated perf events. This makes code simpler and cleaner. + */ static ssize_t set_attr_rdpmc(struct device *cdev, struct device_attribute *attr, const char *buf, size_t count) diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index a3a1e6e670f8..b4344a476a48 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3128,6 +3128,8 @@ static void intel_pmu_enable_fixed(struct perf_event = *event) bits |=3D INTEL_FIXED_0_USER; if (hwc->config & ARCH_PERFMON_EVENTSEL_OS) bits |=3D INTEL_FIXED_0_KERNEL; + if (hwc->config & ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE) + bits |=3D INTEL_FIXED_0_RDPMC_USER_DISABLE; =20 /* * ANY bit is supported in v3 and up @@ -3263,6 +3265,26 @@ static void intel_pmu_enable_event_ext(struct perf_e= vent *event) __intel_pmu_update_event_ext(hwc->idx, ext); } =20 +static void intel_pmu_update_rdpmc_user_disable(struct perf_event *event) +{ + /* + * Counter scope's user-space rdpmc is disabled by default + * except two cases. + * a. rdpmc =3D 2 (user space rdpmc enabled unconditionally) + * b. rdpmc =3D 1 and the event is not a system-wide event. + * The count of non-system-wide events would be cleared when + * context switches, so no count data is leaked. + */ + if (x86_pmu_has_rdpmc_user_disable(event->pmu)) { + if (x86_pmu.attr_rdpmc =3D=3D X86_USER_RDPMC_ALWAYS_ENABLE || + (x86_pmu.attr_rdpmc =3D=3D X86_USER_RDPMC_CONDITIONAL_ENABLE && + event->ctx->task)) + event->hw.config &=3D ~ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE; + else + event->hw.config |=3D ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE; + } +} + DEFINE_STATIC_CALL_NULL(intel_pmu_enable_event_ext, intel_pmu_enable_event= _ext); =20 static void intel_pmu_enable_event(struct perf_event *event) @@ -3271,6 +3293,8 @@ static void intel_pmu_enable_event(struct perf_event = *event) struct hw_perf_event *hwc =3D &event->hw; int idx =3D hwc->idx; =20 + intel_pmu_update_rdpmc_user_disable(event); + if (unlikely(event->attr.precise_ip)) static_call(x86_pmu_pebs_enable)(event); =20 @@ -5860,6 +5884,8 @@ static void update_pmu_cap(struct pmu *pmu) hybrid(pmu, config_mask) |=3D ARCH_PERFMON_EVENTSEL_UMASK2; if (ebx_0.split.eq) hybrid(pmu, config_mask) |=3D ARCH_PERFMON_EVENTSEL_EQ; + if (ebx_0.split.rdpmc_user_disable) + hybrid(pmu, config_mask) |=3D ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE; =20 if (eax_0.split.cntr_subleaf) { cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF, diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 24a81d2916e9..cd337f3ffd01 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -1333,6 +1333,12 @@ static inline u64 x86_pmu_get_event_config(struct pe= rf_event *event) return event->attr.config & hybrid(event->pmu, config_mask); } =20 +static inline bool x86_pmu_has_rdpmc_user_disable(struct pmu *pmu) +{ + return !!(hybrid(pmu, config_mask) & + ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE); +} + extern struct event_constraint emptyconstraint; =20 extern struct event_constraint unconstrained; diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_= event.h index 7276ba70c88a..0356c55d7ec1 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -33,6 +33,7 @@ #define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL #define ARCH_PERFMON_EVENTSEL_BR_CNTR (1ULL << 35) #define ARCH_PERFMON_EVENTSEL_EQ (1ULL << 36) +#define ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE (1ULL << 37) #define ARCH_PERFMON_EVENTSEL_UMASK2 (0xFFULL << 40) =20 #define INTEL_FIXED_BITS_STRIDE 4 @@ -40,6 +41,7 @@ #define INTEL_FIXED_0_USER (1ULL << 1) #define INTEL_FIXED_0_ANYTHREAD (1ULL << 2) #define INTEL_FIXED_0_ENABLE_PMI (1ULL << 3) +#define INTEL_FIXED_0_RDPMC_USER_DISABLE (1ULL << 33) #define INTEL_FIXED_3_METRICS_CLEAR (1ULL << 2) =20 #define HSW_IN_TX (1ULL << 32) @@ -50,7 +52,7 @@ #define INTEL_FIXED_BITS_MASK \ (INTEL_FIXED_0_KERNEL | INTEL_FIXED_0_USER | \ INTEL_FIXED_0_ANYTHREAD | INTEL_FIXED_0_ENABLE_PMI | \ - ICL_FIXED_0_ADAPTIVE) + ICL_FIXED_0_ADAPTIVE | INTEL_FIXED_0_RDPMC_USER_DISABLE) =20 #define intel_fixed_bits_by_idx(_idx, _bits) \ ((_bits) << ((_idx) * INTEL_FIXED_BITS_STRIDE)) @@ -226,7 +228,9 @@ union cpuid35_ebx { unsigned int umask2:1; /* EQ-bit Supported */ unsigned int eq:1; - unsigned int reserved:30; + /* rdpmc user disable Supported */ + unsigned int rdpmc_user_disable:1; + unsigned int reserved:29; } split; unsigned int full; }; --=20 2.34.1