Re: [Patch v7 22/24] perf/x86/intel: Enable arch-PEBS based SIMD/eGPRs/SSP sampling

"Mi, Dapeng" <[email protected]>
Newsgroups dev.linux.lists.sashiko,org.kernel.vger.linux-perf-users
Message-ID <[email protected]>
On 4/25/2026 11:08 AM, [email protected] wrote:
> Sashiko AI review found 2 potential issue(s):
> - [Critical] Leaking stale per-CPU FPU/extended register state to user space when a PEBS event triggers in kernel mode and requests PERF_SAMPLE_REGS_USER.
> - [High] Incorrect bitwise AND with a raw u64 bitmask in `intel_pebs_support_regs` permanently disables large PEBS for XMM registers on arch-PEBS platforms.
> --
>
> commit 7ad07fe08e2e0b394952e6f0ccf5f040f99870e3
> Author: Dapeng Mi <[email protected]>
>
> perf/x86/intel: Enable arch-PEBS based SIMD/eGPRs/SSP sampling
>
> This patch enables arch-PEBS based SIMD/eGPRs/SSP registers sampling
> using the XSAVE-Enabled Registers (XER) group.
>
>> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
>> index 3d64f28b7e9ac..b280a39f68bca 100644
>> --- a/arch/x86/events/intel/core.c
>> +++ b/arch/x86/events/intel/core.c
> [ ... ]
>
>> @@ -4416,6 +4431,34 @@ static void intel_pebs_aliases_skl(struct perf_event *event)
>>  	return intel_pebs_aliases_precdist(event);
>>  }
>>  
>> +static inline bool intel_pebs_support_regs(struct perf_event *event, u64 regs)
>> +{
>> +	struct arch_pebs_cap cap = hybrid(event->pmu, arch_pebs_cap);
>> +	int pebs_format = x86_pmu.intel_cap.pebs_format;
>> +	bool supported = true;
>> +
>> +	/* SSP */
>> +	if (regs & PEBS_DATACFG_GP)
>> +		supported &= x86_pmu.arch_pebs && (ARCH_PEBS_GPR & cap.caps);
>> +	if (regs & PEBS_DATACFG_XMMS) {
>> +		supported &= x86_pmu.arch_pebs ?
>> +			     ARCH_PEBS_VECR_XMM & cap.caps :
>> +			     pebs_format > 3 && x86_pmu.intel_cap.pebs_baseline;
>> +	}
> Will this permanently disable large PEBS for XMM registers?
>
> Because supported is a boolean (initially 1), ARCH_PEBS_VECR_XMM & cap.caps
> evaluates to BIT_ULL(49). The bitwise AND operation 1 &= 0x2000000000000ULL
> strictly yields 0.
>
> Should this bitmask be normalized to a boolean value, perhaps using
> !!(ARCH_PEBS_VECR_XMM & cap.caps) inside the ternary operator?

Yes, it's a bug. would fix it in next version.


>
> [ ... ]
>
>> diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
>> index 560f178d7ac92..61d72c58f9a25 100644
>> --- a/arch/x86/events/intel/ds.c
>> +++ b/arch/x86/events/intel/ds.c
> [ ... ]
>
>> @@ -2708,15 +2719,69 @@ static void setup_arch_pebs_sample_data(struct perf_event *event,
>>  					   meminfo->tsx_tuning, ax);
>>  	}
>>  
>> -	if (header->xmm) {
>> +	if (header->xmm || header->ymmh || header->egpr ||
>> +	    header->opmask || header->zmmh || header->h16zmm) {
>> +		struct arch_pebs_xer_header *xer_header = next_record;
>>  		struct pebs_xmm *xmm;
>> +		struct ymmh_struct *ymmh;
>> +		struct avx_512_zmm_uppers_state *zmmh;
>> +		struct avx_512_hi16_state *h16zmm;
>> +		struct avx_512_opmask_state *opmask;
>> +		struct apx_state *egpr;
>>  
>>  		next_record += sizeof(struct arch_pebs_xer_header);
>>  
>> -		ignore_mask |= XFEATURE_MASK_SSE;
>> -		xmm = next_record;
>> -		perf_regs->xmm_regs = xmm->xmm;
>> -		next_record = xmm + 1;
>> +		if (header->xmm) {
>> +			ignore_mask |= XFEATURE_MASK_SSE;
>> +			xmm = next_record;
>> +			/*
>> +			 * Only output XMM regs to user space when arch-PEBS
>> +			 * really writes data into xstate area.
>> +			 */
>> +			if (xer_header->xstate & XFEATURE_MASK_SSE)
>> +				perf_regs->xmm_regs = xmm->xmm;
>> +			next_record = xmm + 1;
>> +		}
> Is it possible for this code to leak stale per-CPU FPU/extended register
> state to user space?
>
> When a PEBS event triggers in kernel mode and requests PERF_SAMPLE_REGS_USER,
> this code processes the PEBS data and sets the corresponding bits
> (e.g., XFEATURE_MASK_SSE) in ignore_mask. It then calls
> x86_pmu_setup_regs_data(), which assigns data->regs_user.regs to the
> static per-CPU x86_user_regs.
>
> If x86_user_regs is never fully cleared, its extended register pointers
> (like xmm_regs) still point to the per-CPU ext_regs_buf from prior samples.
> Because XFEATURE_MASK_SSE is excluded via ignore_mask, xsaves_nmi() and
> x86_pmu_update_xregs() skip updating x86_user_regs.xmm_regs.
>
> Consequently, the xmm_regs pointer remains pointing to the stale data in
> ext_regs_buf. When the perf core outputs the user registers, could it
> read the stale FPU state from ext_regs_buf and leak it across processes?

Yes, it's a known issue. Would be fixed in next version.

Thanks.


>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.