Linux Perf Users
 help / color / mirror / Atom feed
From: Athira Rajeev <atrajeev@linux.ibm.com>
To: sashiko-reviews@lists.linux.dev
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH V3 4/6] powerpc/perf: Capture the HTM memory configuration as part of perf data
Date: Sun, 26 Jul 2026 13:48:09 +0530	[thread overview]
Message-ID: <DA364026-B783-4EDA-BF6B-A3C965FCD803@linux.ibm.com> (raw)
In-Reply-To: <20260725074300.D145E1F000E9@smtp.kernel.org>



> On 25 Jul 2026, at 1:13 PM, sashiko-bot@kernel.org wrote:
> 
> Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
> - [High] HTM_MEM_BUF_SIZE (65440 bytes) leaves insufficient headroom for dynamic perf sample fields, causing perf_event_header.size to overflow its u16 limit and corrupt the ring buffer.
> - [High] Uninitialized kernel stack memory in struct pt_regs is leaked to userspace when the event is configured with PERF_SAMPLE_REGS_INTR.
> - [High] Misinterpretation of perf_event_overflow() return value causes silent data loss when the ring buffer is full, and data duplication when the event is throttled.
> - [High] htm_mem_buf is allocated with kmalloc_node instead of kzalloc_node, potentially leaking uninitialized kernel heap memory to userspace.
> - [Medium] htm_collect_memory_config fails to accumulate the emitted entry counts across its loop iterations, resulting in metric under-reporting.
> --
> 
> --- Patch [4]: [PATCH V3 4/6] powerpc/perf: Capture the HTM memory configuration as part of perf data ---
> commit ace2c86ce33c6759f7015fdf1bd6da0f6b6ecba3
> Author: Athira Rajeev <atrajeev@linux.ibm.com>
> Subject: powerpc/perf: Capture the HTM memory configuration as part of perf data
> 
> This commit captures HTM system memory configuration records by dumping them
> into the AUX buffer and emitting them as raw perf samples. It introduces
> buffers for the hypervisor dump, handles layout sizing, and iterates through
> memory config batches using H_HTM_OP_DUMP_SYSMEM_CONF.
> 
>> diff --git a/arch/powerpc/perf/htm-perf.c b/arch/powerpc/perf/htm-perf.c
>> index f880a5fc88330..af9a8412ff20f 100644
>> --- a/arch/powerpc/perf/htm-perf.c
>> +++ b/arch/powerpc/perf/htm-perf.c
> 
> [ ... ]
> 
>> +/*
>> + * HTM_MEM_BUF_SIZE is the allocation size for the hcall staging buffer.
> [ ... ]
>> + * 65440 = 32 + 2043 * 32 is the largest multiple of 32 satisfying all
>> + * three constraints:
>> + *   - covers 64480 with 960 bytes headroom
>> + *   - total record: 65440 + 92 = 65532 < 65535 (3-byte u16 margin)
>> + *
>> + * HTM_MEM_MAX_ENTRIES is derived from HTM_MEM_BUF_SIZE — not the other
>> + * way around — so the hcall is always given the true buffer size and
>> + * the WARN_ON_ONCE(to_copy > HTM_MEM_BUF_SIZE) guard is a genuine
>> + * impossibility check rather than a post-overflow assertion.
>> + */
>> +#define HTM_MEM_BUF_SIZE 65440U
> 
> [Severity: High]
> Could the buffer size calculation cause an overflow if dynamic sample
> attributes are used?
> 
> The commit message states the fixed overhead is 92 bytes, which leaves
> (65535 - 92 = 65443) bytes for the payload. However, if the event is
> configured with PERF_SAMPLE_REGS_INTR, the size of struct pt_regs (which is
> over 300 bytes on PowerPC) is added to the sample size.
> 
> Does this cause perf_sample_data_size() to return a value greater than 65535,
> which would wrap around when assigned to the __u16 header.size in
> perf_prepare_header(), potentially leading to ring buffer corruption?

HTM doesn’t support PERF_SAMPLE_REGS_INTR
I will add a check in even_init to handle this and hence we will be good here
> 
>> +#define HTM_MEM_MAX_ENTRIES ((HTM_MEM_BUF_SIZE - 32) / 32) /* 2043 */
> 
> [ ... ]
> 
>> +static ssize_t htm_collect_memory_config(struct perf_event *event,
>> + struct htm_pmu_buf *aux_buf)
>> +{
>> + struct perf_sample_data data;
>> + struct perf_raw_record raw;
>> + struct pt_regs regs;
> 
> [Severity: High]
> Is it possible for this uninitialized stack variable to leak kernel memory?
> 
> The regs structure is partially initialized by perf_fetch_caller_regs(),
> which on PowerPC only sets nip, gpr[1], result, and msr:
> 
> perf_arch_fetch_caller_regs(regs, CALLER_ADDR0) {
>    ...
> }
> 
> If the event uses PERF_SAMPLE_REGS_INTR, will perf_output_sample() write the
> uninitialized portions of this pt_regs structure into the perf ring buffer,
> exposing stale kernel stack contents to userspace? Should this be initialized
> with an empty initialization?

HTM doesn’t support PERF_SAMPLE_REGS_INTR
I will add a check in even_init to handle this and hence we are good with perf_arch_fetch_caller_regs
> 
> 
>> + u8 *htm_mem_buf = aux_buf->htm_mem_buf;
>> + __be64 *num_entries;
> 
> [ ... ]
> 
>> + perf_sample_data_init(&data, 0, event->hw.last_period);
>> + memset(&raw, 0, sizeof(raw));
>> + raw.frag.data = emit_buf;
>> + raw.frag.size = to_copy;
>> + perf_sample_save_raw_data(&data, event, &raw);
>> +
>> + if (perf_event_overflow(event, &data, &regs)) {
> 
> [Severity: High]
> Does this logic misinterpret the return value of perf_event_overflow()?
> 
> Looking at __perf_event_overflow(), it returns non-zero (1) only when an
> event is throttled. If it returns 1, the current sample was already
> successfully written before the throttle triggered. However, the driver
> assumes failure here, skips advancing mem_start, and emits the exact same
> block again on the next pass.
> 
> Conversely, if the ring buffer fills up, the core drops the sample but
> __perf_event_overflow() still returns 0. When it returns 0, the driver
> assumes success, advances mem_start, and silently loses configuration data.
> 
> Is this behavior intended, or should it be adjusted to avoid silent data
> loss and duplication?
Will change this approach in V4.
  
> 
>> + /*
>> + * Event throttled: the record was not written to the
>> + * ring buffer.  Do NOT advance mem_start — the same
>> + * block will be retried on the next htm_event_read()
>> + * call once the event is unthrottled.  Leave
>> + * collect_htm_mem set so the retry path is entered.
>> + * Return -ENOSPC so htm_event_read() sets event->count=1,
>> + * keeping the drain loop alive until the ring buffer
>> + * consumer catches up.
>> + */
>> + ret = -ENOSPC;
>> + break;
>> + }
>> +
>> + /* Record written successfully: advance the iterator */
>> + aux_buf->mem_start = next_start;
>> +
>> + /*
>> + * Return the number of 32-byte memory configuration entries
>> + * in this batch (to_copy / 32).  Dividing here keeps
>> + * htm_event_read() free of format knowledge, consistent with
>> + * the AUX trace path returning chunk_size / 128.
>> + */
>> + ret = (ssize_t)(to_copy / 32);
> 
> [Severity: Medium]
> Does this assignment under-report the emitted entry counts?
> 
> Since this is inside a while (true) loop, multiple chunks of memory
> configuration data might be processed. By directly overwriting ret instead
> of accumulating it (e.g., ret += to_copy / 32), the function seems to return
> only the count from the last chunk processed.
> 
> Will this permanently drop the counts of all records emitted in prior loop
> iterations during the same session?
Sure, will fix this in V4
> 
>> +
>> + if (!next_start) {
>> + aux_buf->collect_htm_mem = 0;
>> + break;
>> + }
>> + }
>> +
>> + return ret;
>> +}
> 
> [ ... ]
> 
>> +static void *htm_setup_aux(struct perf_event *event, void **pages,
>> + int nr_pages, bool snapshot)
>> +{
> 
> [ ... ]
> 
>> + /*
>> + * htm_mem_buf is the staging area passed directly to the
>> + * H_HTM_OP_DUMP_SYSMEM_CONF hcall.  The hypervisor is told the
>> + * buffer length is HTM_MEM_BUF_SIZE (65440 bytes); allocate exactly
>> + * that amount.  See the HTM_MEM_BUF_SIZE comment for the derivation.
>> + */
>> + buf->htm_mem_buf = kmalloc_node(HTM_MEM_BUF_SIZE, GFP_KERNEL, cpu_to_node(cpu));
> 
> [Severity: High]
> Could allocating this buffer with kmalloc_node() lead to an information leak?
> 
> This buffer is passed to the hypervisor and subsequently copied to userspace
> via the perf ring buffer:
> 
> htm_collect_memory_config() {
>    ...
>    memcpy(emit_buf, aux_buf->htm_mem_buf, to_copy);
>    ...
> }
> 
> If the hypervisor successfully returns but writes fewer entries than it
> claims, leaves reserved fields untouched, or inserts padding bytes, will the
> uninitialized kernel heap memory be exposed to userspace? Should this use
> kzalloc_node() instead to defensively zero-initialize the memory?
Will fix this in V4 to use kzalloc_node

Thanks
Athira
> 
>> + if (!buf->htm_mem_buf) {
>> + kfree(buf);
>> + return NULL;
>> + }
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260725065942.78839-1-atrajeev@linux.ibm.com?part=4


  reply	other threads:[~2026-07-26  8:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-25  6:59 [PATCH V3 0/6] powerpc/perf: Add HTM PMU driver and perf AUX support Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 1/6] powerpc/perf: Add HTM PMU driver to expose Hardware Trace Macro data Athira Rajeev
2026-07-25  7:45   ` sashiko-bot
2026-07-26  6:43     ` Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 2/6] powerpc/perf: Reject duplicate HTM target reservations Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 3/6] powerpc/perf: Add AUX buffer management to capture HTM trace data Athira Rajeev
2026-07-25  7:45   ` sashiko-bot
2026-07-26  7:25     ` Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 4/6] powerpc/perf: Capture the HTM memory configuration as part of perf data Athira Rajeev
2026-07-25  7:43   ` sashiko-bot
2026-07-26  8:18     ` Athira Rajeev [this message]
2026-07-25  6:59 ` [PATCH V3 5/6] docs: ABI: sysfs-bus-event_source-devices-htm: Document sysfs event format entries for htm pmu Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 6/6] powerpc/perf/htm: Add documentation for Hardware Trace Macro PMU Athira Rajeev

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=DA364026-B783-4EDA-BF6B-A3C965FCD803@linux.ibm.com \
    --to=atrajeev@linux.ibm.com \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox