FAILED: patch "[PATCH] perf: Replace perf_event_header__init_id with full header" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x b9d1fdc6f4ac1b6e49f9deafaf137da1407d9af1
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100508-operation-lapping-3aef@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From b9d1fdc6f4ac1b6e49f9deafaf137da1407d9af1 Mon Sep 17 00:00:00 2001
From: Ian Rogers <[email protected]>
Date: Tue, 29 Sep 2026 15:23:32 -0700
Subject: [PATCH] perf: Replace perf_event_header__init_id with full header
init
perf_iterate_sb() invokes its callback for each matching perf_event on the CPU and task context, passing a shared caller-allocated event structure.
perf_event_header__init_id() mutated header->size in place by adding event->id_header_size, requiring sideband output callbacks to save and restore header fields across iterations. Three sideband callbacks failed to save and restore header.size around perf_event_header__init_id():
- perf_event_ksymbol_output()
- perf_event_bpf_output()
- perf_event_text_poke_output()
When multiple events with attr.ksymbol, attr.bpf_event, or attr.text_poke and sample_id_all are active on the same CPU, each subsequent event receives a record whose header.size is inflated by all preceding events' id_header_size values while only a single id_sample is written, leaving uninitialized ring-buffer bytes at the end of the record and causing userspace perf to fail with -EFAULT ("Bad address") when parsing the sample_id trailer.
Similarly, perf_event_mmap_output() set PERF_RECORD_MISC_MMAP_BUILD_ID in mmap_event->event_id.header.misc when event->attr.build_id was enabled, but only saved and restored header.size and header.type. If an event with attr.build_id was followed by an event with attr.mmap2 and !attr.build_id, the second event received PERF_RECORD_MISC_MMAP_BUILD_ID in header.misc while its payload contained maj/min/ino/ino_generation instead of a build ID.
Rather than splitting header initialization between callers and output callbacks and saving/restoring mutated header fields, replace perf_event_header__init_id() with perf_event_header__init(), which initializes header->type, header->misc, and header->size alongside the sample_id fields on each invocation.
arch/powerpc/perf/imc-pmu.c +12 -11
@@ -1275,6 +1275,8 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem,struct perf_event_header *header, struct perf_event *event) { + u16 misc = 0; +/* Sanity checks for a valid record */ if (be64_to_cpu (READ_ONCE (mem->tb1)) > *prev_tb) *prev_tb =be64_to_cpu (READ_ONCE (mem->tb1));
@@ -1289,23 +1291,19 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem, data->ip =be64_to_cpu (READ_ONCE (mem->ip)); data->period = event->hw.last_period; - header->type =PERF_RECORD_SAMPLE ; - header->size =sizeof (*header) + event->header_size; - header->misc =0 ; -if (cpu_has_feature (CPU_FTR_ARCH_31 )) {switch (IMC_TRACE_RECORD_VAL_HVPR (be64_to_cpu (READ_ONCE (mem->val)))) {case 0 :/* when MSR HV and PR not set in the trace-record */ - header->misc |=PERF_RECORD_MISC_GUEST_KERNEL ; + misc |=PERF_RECORD_MISC_GUEST_KERNEL ;break ;case 1 :/* MSR HV is 0 and PR is 1 */ - header->misc |=PERF_RECORD_MISC_GUEST_USER ; + misc |=PERF_RECORD_MISC_GUEST_USER ;break ;case 2 :/* MSR HV is 1 and PR is 0 */ - header->misc |=PERF_RECORD_MISC_KERNEL ; + misc |=PERF_RECORD_MISC_KERNEL ;break ;case 3 :/* MSR HV is 1 and PR is 1 */ - header->misc |=PERF_RECORD_MISC_USER ; + misc |=PERF_RECORD_MISC_USER ;break ;default :pr_info ("IMC: Unable to set the flag based on MSR bits\n" );
@@ -1313,11 +1311,14 @@ static int trace_imc_prepare_sample(struct trace_imc_data *mem, } }else {if (is_kernel_addr (data->ip)) - header->misc |=PERF_RECORD_MISC_KERNEL ; + misc |=PERF_RECORD_MISC_KERNEL ;else - header->misc |=PERF_RECORD_MISC_USER ; + misc |=PERF_RECORD_MISC_USER ; } -perf_event_header__init_id (header, data, event); +perf_event_header__init (header, data, +PERF_RECORD_SAMPLE , misc, +sizeof (*header) + event->header_size, + event);return 0 ; }
include/linux/perf_event.h +4 -3
@@ -1506,9 +1506,10 @@ is_default_overflow_handler(struct perf_event *event) }extern void -perf_event_header__init_id (struct perf_event_header *header, -struct perf_sample_data *data, -struct perf_event *event); +perf_event_header__init (struct perf_event_header *header, +struct perf_sample_data *data, +u32 type,u16 misc,u16 size, +struct perf_event *event); extern void perf_event__output_id_sample(struct perf_event *event, struct perf_output_handle *handle,
kernel/events/core.c +127 -176
652 lines not on this page · raw message
kernel/events/ring_buffer.c +3 -4
@@ -246,14 +246,13 @@ __perf_output_begin(struct perf_output_handle *handle, handle->size = (1UL << page_shift) - offset;if (unlikely (have_lost)) { - lost_event.header.size =sizeof (lost_event); - lost_event.header.type =PERF_RECORD_LOST ; - lost_event.header.misc =0 ; lost_event.id = event->id; lost_event.lost =local_xchg (&rb->lost,0 );/* XXX mostly redundant; @data is already fully initializes */ -perf_event_header__init_id (&lost_event.header, data, event); +perf_event_header__init (&lost_event.header, data, +PERF_RECORD_LOST ,/* misc= */ 0 , +sizeof (lost_event), event);perf_output_put (handle, lost_event);perf_event__output_id_sample (event, handle, data); }