Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH v2 0/3] perf hisi-ptt: Fix TLP header parsing and naming
@ 2026-07-30  6:27 Sizhe Liu
  2026-07-30  6:27 ` [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing Sizhe Liu
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Sizhe Liu @ 2026-07-30  6:27 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, corbet, skhan, bhelgaas,
	yangyccccc, jic23, john.g.garry, will, james.clark, mike.leach,
	leo.yan, peterz, mingo, acme, namhyung, mark.rutland,
	alexander.shishkin, jolsa, irogers, adrian.hunter, wangyushan12
  Cc: linux-kernel, linux-pci, linux-perf-users, linux-arm-kernel,
	linux-doc, linuxarm, prime.zeng, wuyifan50, liusizhe5

This series fixes bugs and issues in the hisi_ptt packet decoder that were
introduced by commit 5e91e57e6809 ("perf auxtrace arm64: Add support
for parsing HiSilicon PCIe Trace packet").

Patch 1: Bugfix:
The DW0 bit-field layout of the hisi_ptt_4dw union does not match
the actual little-endian memory ordering, so the extracted
Format/Type/T9/T8/TH/SO/Length/Time fields are wrong.

Meanwhile, make all DW hex values printed in big-endian byte order
for readability.

Patch 2: Fix endianness / Heap out-of-bounds read / Integer truncation
issues.

Patch 3: Fix spelling / abbreviation errors in symbol names and macros.

---
Changes in v2:
- Move spelling error fixes to the end of the patch series.
- Add fixes tag only for bugfix.
- Use get_unaligned_le32() to make memory read more robust.
- Fix pre-existing issues reported by Sashiko in patch 2.
- Link to v1: https://lore.kernel.org/linux-pci/20260729060220.624250-1-liusizhe5@huawei.com/

---
Sizhe Liu (3):
  perf hisi-ptt: Fix PTT trace TLP header parsing
  perf hisi-ptt: Strengthen auxtrace event handling and packet type
    detection
  perf hisi-ptt: Fix spelling and abbreviation errors

 Documentation/trace/hisi-ptt.rst              | 28 ++++-----
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c   | 63 ++++++++++---------
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h   | 14 ++++-
 tools/perf/util/hisi-ptt.c                    | 24 +++++--
 4 files changed, 77 insertions(+), 52 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing
  2026-07-30  6:27 [PATCH v2 0/3] perf hisi-ptt: Fix TLP header parsing and naming Sizhe Liu
@ 2026-07-30  6:27 ` Sizhe Liu
  2026-07-30  6:43   ` sashiko-bot
  2026-07-30  6:27 ` [PATCH v2 2/3] perf hisi-ptt: Strengthen auxtrace event handling and packet type detection Sizhe Liu
  2026-07-30  6:27 ` [PATCH v2 3/3] perf hisi-ptt: Fix spelling and abbreviation errors Sizhe Liu
  2 siblings, 1 reply; 7+ messages in thread
From: Sizhe Liu @ 2026-07-30  6:27 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, corbet, skhan, bhelgaas,
	yangyccccc, jic23, john.g.garry, will, james.clark, mike.leach,
	leo.yan, peterz, mingo, acme, namhyung, mark.rutland,
	alexander.shishkin, jolsa, irogers, adrian.hunter, wangyushan12
  Cc: linux-kernel, linux-pci, linux-perf-users, linux-arm-kernel,
	linux-doc, linuxarm, prime.zeng, wuyifan50, liusizhe5

TLP Headers traced by HiSilicon PCIe tune and trace device (PTT) in
4DW format are shown in the document as below:
bits [31:30] [ 29:25 ][24][23][22][21][    20:11   ][    10:0    ]
     |-----|---------|---|---|---|---|-------------|-------------|
DW0  [ Fmt ][  Type  ][T9][T8][TH][SO][   Length   ][    Time    ]
DW1  [                     Header DW1                            ]
DW2  [                     Header DW2                            ]
DW3  [                     Header DW3                            ]

Problem:
The DW0 bit field layout of the hisi_ptt_4dw union does not match the
actual bit ordering in little-endian memory, causing incorrect field
decoding.

Test on Kunpeng 930 SOC, generating data flow with `iperf` commands:
- server side:
    iperf -s
- client side:
    iperf -c $ip_addr -t 30

Trace the TLP headers with hisi_ptt on server side at the same time:
  perf record -e hisi_ptt12_0/type=4,filter=0x05101,direction=2,format=0/ \
  --max-size 50M -o perf.data &
The trace aims to capture completion TLPs, learn more in the document:
  https://docs.kernel.org/trace/hisi-ptt.html

Decode perf.data with hisi_ptt decoder:
  perf report -D

The hisi_ptt decoder produces the following result:
[...perf headers and other information]
. ... HISI PTT data: size 8388608 bytes
.  00000000: 68 87 20 94                                 Format 3 Type 1a T9 0 T8 1 TH 1 SO 1 Length 10 Time 4a1
.  00000004: 40 00 00 00                                 Header DW1
.  00000008: 40 00 01 51                                 Header DW2
.  0000000c: 00 00 00 00                                 Header DW3
[...other hisi_ptt TLP headers]

According to PCIe r5.0 sec 2.2.1, the Fmt & Type of Cpl/CplD is supposed
to be 8b'00001010' / 8b'01001010'
However, the Format & Type decoder analyzing result is 8b'01111010'.
It does not match field encodings of any TLP.

Correct decoder result should be:
[...perf headers and other information]
. ... HISI PTT data: size 8388608 bytes
.  00000000: 94 20 87 68                                 Format 2 Type a T9 0 T8 0 TH 0 SO 1 Length 10 Time 768
.  00000004: 00 00 00 40                                 Header DW1
.  00000008: 51 01 00 40                                 Header DW2
.  0000000c: 00 00 00 00                                 Header DW3
[...other hisi_ptt TLP headers]

To solve the problem:
1. Drop the union and C bitfield struct, store the raw DW value in
a plain uint32_t, and extract the fields with FIELD_GET() against
GENMASK/BIT masks declared in the header so they can be reused by
other translation units. The masks are portable across endianness and
compilers.

2. Print all DW hex values in big-endian byte order for readability,
matching the bit field layout shown in the 4DW format diagram.

3. Read the DW value with get_unaligned_le32() instead of an unaligned
pointer cast, avoiding both strict-aliasing violations and
alignment hazards on hosts that do not support unaligned access.

Cc: stable@vger.kernel.org
Fixes: 5e91e57e6809 ("perf auxtrace arm64: Add support for parsing HiSilicon PCIe Trace packet")
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Sizhe Liu <liusizhe5@huawei.com>
---
 Documentation/trace/hisi-ptt.rst              | 28 +++++------
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c   | 47 ++++++++++---------
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h   | 12 +++++
 3 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
index 6eef28ebb0c7..f6a2655f99e5 100644
--- a/Documentation/trace/hisi-ptt.rst
+++ b/Documentation/trace/hisi-ptt.rst
@@ -285,20 +285,20 @@ according to the format described previously (take 8DW as an example):
     [...perf headers and other information]
     . ... HISI PTT data: size 4194304 bytes
     .  00000000: 00 00 00 00                                 Prefix
-    .  00000004: 01 00 00 60                                 Header DW0
-    .  00000008: 0f 1e 00 01                                 Header DW1
-    .  0000000c: 04 00 00 00                                 Header DW2
-    .  00000010: 40 00 81 02                                 Header DW3
-    .  00000014: 33 c0 04 00                                 Time
+    .  00000004: 60 00 00 01                                 Header DW0
+    .  00000008: 01 00 1e 0f                                 Header DW1
+    .  0000000c: 00 00 00 04                                 Header DW2
+    .  00000010: 02 81 00 40                                 Header DW3
+    .  00000014: 00 04 c0 33                                 Time
     .  00000020: 00 00 00 00                                 Prefix
-    .  00000024: 01 00 00 60                                 Header DW0
-    .  00000028: 0f 1e 00 01                                 Header DW1
-    .  0000002c: 04 00 00 00                                 Header DW2
-    .  00000030: 40 00 81 02                                 Header DW3
-    .  00000034: 02 00 00 00                                 Time
+    .  00000024: 60 00 00 01                                 Header DW0
+    .  00000028: 01 00 1e 0f                                 Header DW1
+    .  0000002c: 00 00 00 04                                 Header DW2
+    .  00000030: 02 81 00 40                                 Header DW3
+    .  00000034: 00 00 00 02                                 Time
     .  00000040: 00 00 00 00                                 Prefix
-    .  00000044: 01 00 00 60                                 Header DW0
-    .  00000048: 0f 1e 00 01                                 Header DW1
-    .  0000004c: 04 00 00 00                                 Header DW2
-    .  00000050: 40 00 81 02                                 Header DW3
+    .  00000044: 60 00 00 01                                 Header DW0
+    .  00000048: 01 00 1e 0f                                 Header DW1
+    .  0000004c: 00 00 00 04                                 Header DW2
+    .  00000050: 02 81 00 40                                 Header DW3
     [...]
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
index a17c423a526d..5db44556fc4f 100644
--- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
@@ -10,6 +10,8 @@
 #include <endian.h>
 #include <byteswap.h>
 #include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/unaligned.h>
 #include <stdarg.h>
 
 #include "../color.h"
@@ -73,29 +75,20 @@ static const char * const hisi_ptt_4dw_pkt_field_name[] = {
 	[HISI_PTT_4DW_HEAD3]	= "Header DW3",
 };
 
-union hisi_ptt_4dw {
-	struct {
-		uint32_t format : 2;
-		uint32_t type : 5;
-		uint32_t t9 : 1;
-		uint32_t t8 : 1;
-		uint32_t th : 1;
-		uint32_t so : 1;
-		uint32_t len : 10;
-		uint32_t time : 11;
-	};
-	uint32_t value;
-};
-
 static void hisi_ptt_print_pkt(const unsigned char *buf, int pos, const char *desc)
 {
 	const char *color = PERF_COLOR_BLUE;
+	uint8_t byte;
+	uint32_t dw;
 	int i;
 
+	dw = get_unaligned_le32(buf + pos);
 	printf(".");
 	color_fprintf(stdout, color, "  %08x: ", pos);
-	for (i = 0; i < HISI_PTT_FIELD_LENTH; i++)
-		color_fprintf(stdout, color, "%02x ", buf[pos + i]);
+	for (i = 0; i < HISI_PTT_FIELD_LENTH; i++) {
+		byte = (dw >> (24 - i * 8)) & 0xFF;
+		color_fprintf(stdout, color, "%02x ", byte);
+	}
 	for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++)
 		color_fprintf(stdout, color, "   ");
 	color_fprintf(stdout, color, "  %s\n", desc);
@@ -122,22 +115,30 @@ static int hisi_ptt_8dw_kpt_desc(const unsigned char *buf, int pos)
 static void hisi_ptt_4dw_print_dw0(const unsigned char *buf, int pos)
 {
 	const char *color = PERF_COLOR_BLUE;
-	union hisi_ptt_4dw dw0;
+	uint8_t byte;
+	uint32_t dw;
 	int i;
 
-	dw0.value = *(uint32_t *)(buf + pos);
+	dw = get_unaligned_le32(buf + pos);
 	printf(".");
 	color_fprintf(stdout, color, "  %08x: ", pos);
-	for (i = 0; i < HISI_PTT_FIELD_LENTH; i++)
-		color_fprintf(stdout, color, "%02x ", buf[pos + i]);
+	for (i = 0; i < HISI_PTT_FIELD_LENTH; i++) {
+		byte = (dw >> (24 - i * 8)) & 0xFF;
+		color_fprintf(stdout, color, "%02x ", byte);
+	}
 	for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++)
 		color_fprintf(stdout, color, "   ");
 
 	color_fprintf(stdout, color,
 		      "  %s %x %s %x %s %x %s %x %s %x %s %x %s %x %s %x\n",
-		      "Format", dw0.format, "Type", dw0.type, "T9", dw0.t9,
-		      "T8", dw0.t8, "TH", dw0.th, "SO", dw0.so, "Length",
-		      dw0.len, "Time", dw0.time);
+		      "Format", FIELD_GET(HISI_PTT_HEAD0_4DW_FORMAT, dw),
+		      "Type", FIELD_GET(HISI_PTT_HEAD0_4DW_TYPE, dw),
+		      "T9", FIELD_GET(HISI_PTT_HEAD0_4DW_T9, dw),
+		      "T8", FIELD_GET(HISI_PTT_HEAD0_4DW_T8, dw),
+		      "TH", FIELD_GET(HISI_PTT_HEAD0_4DW_TH, dw),
+		      "SO", FIELD_GET(HISI_PTT_HEAD0_4DW_SO, dw),
+		      "Length", FIELD_GET(HISI_PTT_HEAD0_4DW_LEN, dw),
+		      "Time", FIELD_GET(HISI_PTT_HEAD0_4DW_TIME, dw));
 }
 
 static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf, int pos)
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
index e78f1b5bc836..333eee02b19d 100644
--- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
@@ -9,12 +9,24 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
 
 #define HISI_PTT_8DW_CHECK_MASK		GENMASK(31, 11)
 #define HISI_PTT_IS_8DW_PKT		GENMASK(31, 11)
 #define HISI_PTT_MAX_SPACE_LEN		10
 #define HISI_PTT_FIELD_LENTH		4
 
+/* Header DW0 fields for 4DW format */
+#define HISI_PTT_HEAD0_4DW_TIME		GENMASK_U32(10, 0)
+#define HISI_PTT_HEAD0_4DW_LEN		GENMASK_U32(20, 11)
+#define HISI_PTT_HEAD0_4DW_SO		BIT_U32(21)
+#define HISI_PTT_HEAD0_4DW_TH		BIT_U32(22)
+#define HISI_PTT_HEAD0_4DW_T8		BIT_U32(23)
+#define HISI_PTT_HEAD0_4DW_T9		BIT_U32(24)
+#define HISI_PTT_HEAD0_4DW_TYPE		GENMASK_U32(29, 25)
+#define HISI_PTT_HEAD0_4DW_FORMAT	GENMASK_U32(31, 30)
+
 enum hisi_ptt_pkt_type {
 	HISI_PTT_4DW_PKT,
 	HISI_PTT_8DW_PKT,
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] perf hisi-ptt: Strengthen auxtrace event handling and packet type detection
  2026-07-30  6:27 [PATCH v2 0/3] perf hisi-ptt: Fix TLP header parsing and naming Sizhe Liu
  2026-07-30  6:27 ` [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing Sizhe Liu
@ 2026-07-30  6:27 ` Sizhe Liu
  2026-07-30  6:50   ` sashiko-bot
  2026-07-30  6:27 ` [PATCH v2 3/3] perf hisi-ptt: Fix spelling and abbreviation errors Sizhe Liu
  2 siblings, 1 reply; 7+ messages in thread
From: Sizhe Liu @ 2026-07-30  6:27 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, corbet, skhan, bhelgaas,
	yangyccccc, jic23, john.g.garry, will, james.clark, mike.leach,
	leo.yan, peterz, mingo, acme, namhyung, mark.rutland,
	alexander.shishkin, jolsa, irogers, adrian.hunter, wangyushan12
  Cc: linux-kernel, linux-pci, linux-perf-users, linux-arm-kernel,
	linux-doc, linuxarm, prime.zeng, wuyifan50, liusizhe5

Fix pre-existing robustness issues in the hisi-ptt auxtrace decoder
reported by Sashiko:

1. Endianness in hisi_ptt_check_packet_type(): The first 32-bit word was
read with a host-endian memory cast (*(uint32_t *)buf). On big-endian
hosts analyzing a little-endian trace, the bit[31:11] 8DW magic check
fails and every 8DW packet is misclassified as 4DW. Read the header
with get_unaligned_le32().

2. Heap out-of-bounds read: hisi_ptt_dump() called
hisi_ptt_check_packet_type() which dereferenced 4 bytes of the buffer
without any size check. A malformed or truncated event with
auxtrace.size in {0,1,2,3} may cause a heap OOB read. Pass the buffer
length to hisi_ptt_check_packet_type() and return (defaulting to
4DW) when the buffer is shorter than HISI_PTT_FIELD_LENTH.

3. Integer truncation: event->auxtrace.size is __u64 but was stored in
an int. Traces larger than 2GB became negative (malloc failure), and
huge sizes wrapping to a small positive caused a short readn() that
left unread payload in the pipe and permanently desynchronized the
stream. Use u64 for the size, reject anything larger than SSIZE_MAX
before malloc (same bound used by auxtrace_copy_data()), and compare
readn()'s return value against (ssize_t)size to detect truncation.

Signed-off-by: Sizhe Liu <liusizhe5@huawei.com>
---
 tools/perf/util/hisi-ptt.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/hisi-ptt.c b/tools/perf/util/hisi-ptt.c
index e4cc4785f744..d6f48993fdd6 100644
--- a/tools/perf/util/hisi-ptt.c
+++ b/tools/perf/util/hisi-ptt.c
@@ -8,10 +8,12 @@
 #include <endian.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <limits.h>
 #include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/log2.h>
 #include <linux/types.h>
+#include <linux/unaligned.h>
 #include <linux/zalloc.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -35,9 +37,15 @@ struct hisi_ptt {
 	u32 pmu_type;
 };
 
-static enum hisi_ptt_pkt_type hisi_ptt_check_packet_type(unsigned char *buf)
+static enum hisi_ptt_pkt_type hisi_ptt_check_packet_type(unsigned char *buf,
+							 size_t len)
 {
-	uint32_t head = *(uint32_t *)buf;
+	uint32_t head;
+
+	if (len < HISI_PTT_FIELD_LENTH)
+		return HISI_PTT_4DW_PKT;
+
+	head = get_unaligned_le32(buf);
 
 	if ((HISI_PTT_8DW_CHECK_MASK & head) == HISI_PTT_IS_8DW_PKT)
 		return HISI_PTT_8DW_PKT;
@@ -53,7 +61,7 @@ static void hisi_ptt_dump(struct hisi_ptt *ptt __maybe_unused,
 	size_t pos = 0;
 	int pkt_len;
 
-	type = hisi_ptt_check_packet_type(buf);
+	type = hisi_ptt_check_packet_type(buf, len);
 	len = round_down(len, hisi_ptt_pkt_size[type]);
 	color_fprintf(stdout, color, ". ... HISI PTT data: size %zu bytes\n",
 		      len);
@@ -91,11 +99,15 @@ static int hisi_ptt_process_auxtrace_event(struct perf_session *session,
 	struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt,
 					    auxtrace);
 	int fd = perf_data__fd(session->data);
-	int size = event->auxtrace.size;
-	void *data = malloc(size);
+	u64 size = event->auxtrace.size;
 	off_t data_offset;
-	int err;
+	ssize_t err;
+	void *data;
+
+	if (size > SSIZE_MAX)
+		return -EINVAL;
 
+	data = malloc(size);
 	if (!data)
 		return -errno;
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] perf hisi-ptt: Fix spelling and abbreviation errors
  2026-07-30  6:27 [PATCH v2 0/3] perf hisi-ptt: Fix TLP header parsing and naming Sizhe Liu
  2026-07-30  6:27 ` [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing Sizhe Liu
  2026-07-30  6:27 ` [PATCH v2 2/3] perf hisi-ptt: Strengthen auxtrace event handling and packet type detection Sizhe Liu
@ 2026-07-30  6:27 ` Sizhe Liu
  2026-07-30  6:34   ` sashiko-bot
  2 siblings, 1 reply; 7+ messages in thread
From: Sizhe Liu @ 2026-07-30  6:27 UTC (permalink / raw)
  To: rostedt, mhiramat, mathieu.desnoyers, corbet, skhan, bhelgaas,
	yangyccccc, jic23, john.g.garry, will, james.clark, mike.leach,
	leo.yan, peterz, mingo, acme, namhyung, mark.rutland,
	alexander.shishkin, jolsa, irogers, adrian.hunter, wangyushan12
  Cc: linux-kernel, linux-pci, linux-perf-users, linux-arm-kernel,
	linux-doc, linuxarm, prime.zeng, wuyifan50, liusizhe5

Fix spelling and abbreviation errors in the PTT packet decoder:
- HISI_PTT_FIELD_LENTH -> HISI_PTT_FIELD_LENGTH
- hisi_ptt_8dw_kpt_desc -> hisi_ptt_8dw_pkt_desc
- hisi_ptt_4dw_kpt_desc -> hisi_ptt_4dw_pkt_desc

Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Sizhe Liu <liusizhe5@huawei.com>
---
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c   | 20 +++++++++----------
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h   |  2 +-
 tools/perf/util/hisi-ptt.c                    |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
index 5db44556fc4f..72a877fd7236 100644
--- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
@@ -85,7 +85,7 @@ static void hisi_ptt_print_pkt(const unsigned char *buf, int pos, const char *de
 	dw = get_unaligned_le32(buf + pos);
 	printf(".");
 	color_fprintf(stdout, color, "  %08x: ", pos);
-	for (i = 0; i < HISI_PTT_FIELD_LENTH; i++) {
+	for (i = 0; i < HISI_PTT_FIELD_LENGTH; i++) {
 		byte = (dw >> (24 - i * 8)) & 0xFF;
 		color_fprintf(stdout, color, "%02x ", byte);
 	}
@@ -94,19 +94,19 @@ static void hisi_ptt_print_pkt(const unsigned char *buf, int pos, const char *de
 	color_fprintf(stdout, color, "  %s\n", desc);
 }
 
-static int hisi_ptt_8dw_kpt_desc(const unsigned char *buf, int pos)
+static int hisi_ptt_8dw_pkt_desc(const unsigned char *buf, int pos)
 {
 	int i;
 
 	for (i = 0; i < HISI_PTT_8DW_TYPE_MAX; i++) {
 		/* Do not show 8DW check field and reserved fields */
 		if (i == HISI_PTT_8DW_CHK_AND_RSV0 || i == HISI_PTT_8DW_RSV1) {
-			pos += HISI_PTT_FIELD_LENTH;
+			pos += HISI_PTT_FIELD_LENGTH;
 			continue;
 		}
 
 		hisi_ptt_print_pkt(buf, pos, hisi_ptt_8dw_pkt_field_name[i]);
-		pos += HISI_PTT_FIELD_LENTH;
+		pos += HISI_PTT_FIELD_LENGTH;
 	}
 
 	return hisi_ptt_pkt_size[HISI_PTT_8DW_PKT];
@@ -122,7 +122,7 @@ static void hisi_ptt_4dw_print_dw0(const unsigned char *buf, int pos)
 	dw = get_unaligned_le32(buf + pos);
 	printf(".");
 	color_fprintf(stdout, color, "  %08x: ", pos);
-	for (i = 0; i < HISI_PTT_FIELD_LENTH; i++) {
+	for (i = 0; i < HISI_PTT_FIELD_LENGTH; i++) {
 		byte = (dw >> (24 - i * 8)) & 0xFF;
 		color_fprintf(stdout, color, "%02x ", byte);
 	}
@@ -141,16 +141,16 @@ static void hisi_ptt_4dw_print_dw0(const unsigned char *buf, int pos)
 		      "Time", FIELD_GET(HISI_PTT_HEAD0_4DW_TIME, dw));
 }
 
-static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf, int pos)
+static int hisi_ptt_4dw_pkt_desc(const unsigned char *buf, int pos)
 {
 	int i;
 
 	hisi_ptt_4dw_print_dw0(buf, pos);
-	pos += HISI_PTT_FIELD_LENTH;
+	pos += HISI_PTT_FIELD_LENGTH;
 
 	for (i = 0; i < HISI_PTT_4DW_TYPE_MAX; i++) {
 		hisi_ptt_print_pkt(buf, pos, hisi_ptt_4dw_pkt_field_name[i]);
-		pos += HISI_PTT_FIELD_LENTH;
+		pos += HISI_PTT_FIELD_LENGTH;
 	}
 
 	return hisi_ptt_pkt_size[HISI_PTT_4DW_PKT];
@@ -159,7 +159,7 @@ static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf, int pos)
 int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, enum hisi_ptt_pkt_type type)
 {
 	if (type == HISI_PTT_8DW_PKT)
-		return hisi_ptt_8dw_kpt_desc(buf, pos);
+		return hisi_ptt_8dw_pkt_desc(buf, pos);
 
-	return hisi_ptt_4dw_kpt_desc(buf, pos);
+	return hisi_ptt_4dw_pkt_desc(buf, pos);
 }
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
index 333eee02b19d..3b349fcc24ae 100644
--- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
@@ -15,7 +15,7 @@
 #define HISI_PTT_8DW_CHECK_MASK		GENMASK(31, 11)
 #define HISI_PTT_IS_8DW_PKT		GENMASK(31, 11)
 #define HISI_PTT_MAX_SPACE_LEN		10
-#define HISI_PTT_FIELD_LENTH		4
+#define HISI_PTT_FIELD_LENGTH		4
 
 /* Header DW0 fields for 4DW format */
 #define HISI_PTT_HEAD0_4DW_TIME		GENMASK_U32(10, 0)
diff --git a/tools/perf/util/hisi-ptt.c b/tools/perf/util/hisi-ptt.c
index d6f48993fdd6..e73c57f9e8a4 100644
--- a/tools/perf/util/hisi-ptt.c
+++ b/tools/perf/util/hisi-ptt.c
@@ -42,7 +42,7 @@ static enum hisi_ptt_pkt_type hisi_ptt_check_packet_type(unsigned char *buf,
 {
 	uint32_t head;
 
-	if (len < HISI_PTT_FIELD_LENTH)
+	if (len < HISI_PTT_FIELD_LENGTH)
 		return HISI_PTT_4DW_PKT;
 
 	head = get_unaligned_le32(buf);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 3/3] perf hisi-ptt: Fix spelling and abbreviation errors
  2026-07-30  6:27 ` [PATCH v2 3/3] perf hisi-ptt: Fix spelling and abbreviation errors Sizhe Liu
@ 2026-07-30  6:34   ` sashiko-bot
  0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-07-30  6:34 UTC (permalink / raw)
  To: Sizhe Liu; +Cc: linux-perf-users, linux-pci

> Fix spelling and abbreviation errors in the PTT packet decoder:
> - HISI_PTT_FIELD_LENTH -> HISI_PTT_FIELD_LENGTH
> - hisi_ptt_8dw_kpt_desc -> hisi_ptt_8dw_pkt_desc
> - hisi_ptt_4dw_kpt_desc -> hisi_ptt_4dw_pkt_desc
> 
> Reviewed-by: James Clark <james.clark@linaro.org>
> Signed-off-by: Sizhe Liu <liusizhe5@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730062709.534139-1-liusizhe5@huawei.com?part=3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing
  2026-07-30  6:27 ` [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing Sizhe Liu
@ 2026-07-30  6:43   ` sashiko-bot
  0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-07-30  6:43 UTC (permalink / raw)
  To: Sizhe Liu; +Cc: linux-perf-users, linux-pci

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Medium] The patch fixes endianness and strict-aliasing for packet decoding by replacing unaligned casts with `get_unaligned_le32()`, but misses `hisi_ptt_check_packet_type()` which dictates the packet format for the entire trace.
- [Medium] Missing length validation before packet type detection can lead to an out-of-bounds read and potential crash when processing an auxtrace event with a size less than 4 bytes.
--

--- Patch [1]: [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing ---
commit 94e8b50cd3127d5e0f6a440877771f9ffe7c6e0e
Author: Sizhe Liu <liusizhe5@huawei.com>

perf hisi-ptt: Fix PTT trace TLP header parsing

This commit fixes incorrect field decoding of HiSilicon PTT trace TLP headers
in 4DW format. It replaces the C bitfield struct with explicit bitmasks and
uses get_unaligned_le32() to extract the fields, resolving endianness and
strict-aliasing issues.

> diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
> index a17c423a526dd..5db44556fc4f5 100644
> --- a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
> +++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
[ ... ]
> @@ -73,29 +75,20 @@ static const char * const hisi_ptt_4dw_pkt_field_name[] = {
[ ... ]
>  static void hisi_ptt_print_pkt(const unsigned char *buf, int pos, const char *desc)
>  {
>  	const char *color = PERF_COLOR_BLUE;
> +	uint8_t byte;
> +	uint32_t dw;
>  	int i;
>  
> +	dw = get_unaligned_le32(buf + pos);

[Severity: Medium]
This is a pre-existing issue, but while this patch fixes endianness and
strict-aliasing during packet decoding, there appears to be another unaligned
pointer cast in hisi_ptt_check_packet_type() in tools/perf/util/hisi-ptt.c:

tools/perf/util/hisi-ptt.c:hisi_ptt_check_packet_type() {
    ...
    uint32_t head = *(uint32_t *)buf;
    ...
}

Will this cause decoding failures on big-endian hosts because the native
unaligned 32-bit cast interprets the little-endian packet header with
incorrect byte order, causing the packet type bitmask check to misidentify
packets?

[Severity: Medium]
This is also a pre-existing issue, but can missing length validation before
packet type detection lead to an out-of-bounds read?

When processing an auxtrace event with a size less than 4 bytes,
hisi_ptt_dump() in tools/perf/util/hisi-ptt.c unconditionally calls
hisi_ptt_check_packet_type() without verifying len:

tools/perf/util/hisi-ptt.c:hisi_ptt_dump() {
    ...
    type = hisi_ptt_check_packet_type(buf);
    ...
}

This immediately dereferences 4 bytes in hisi_ptt_check_packet_type():

tools/perf/util/hisi-ptt.c:hisi_ptt_check_packet_type() {
    ...
    uint32_t head = *(uint32_t *)buf;
    ...
}

Could this result in a heap out-of-bounds read and potential crash?

>  	printf(".");

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730062709.534139-1-liusizhe5@huawei.com?part=1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] perf hisi-ptt: Strengthen auxtrace event handling and packet type detection
  2026-07-30  6:27 ` [PATCH v2 2/3] perf hisi-ptt: Strengthen auxtrace event handling and packet type detection Sizhe Liu
@ 2026-07-30  6:50   ` sashiko-bot
  0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-07-30  6:50 UTC (permalink / raw)
  To: Sizhe Liu; +Cc: linux-perf-users, linux-pci

> Fix pre-existing robustness issues in the hisi-ptt auxtrace decoder
> reported by Sashiko:
> 
> 1. Endianness in hisi_ptt_check_packet_type(): The first 32-bit word was
> read with a host-endian memory cast (*(uint32_t *)buf). On big-endian
> hosts analyzing a little-endian trace, the bit[31:11] 8DW magic check
> fails and every 8DW packet is misclassified as 4DW. Read the header
> with get_unaligned_le32().
> 
> 2. Heap out-of-bounds read: hisi_ptt_dump() called
> hisi_ptt_check_packet_type() which dereferenced 4 bytes of the buffer
> without any size check. A malformed or truncated event with
> auxtrace.size in {0,1,2,3} may cause a heap OOB read. Pass the buffer
> length to hisi_ptt_check_packet_type() and return (defaulting to
> 4DW) when the buffer is shorter than HISI_PTT_FIELD_LENTH.
> 
> 3. Integer truncation: event->auxtrace.size is __u64 but was stored in
> an int. Traces larger than 2GB became negative (malloc failure), and
> huge sizes wrapping to a small positive caused a short readn() that
> left unread payload in the pipe and permanently desynchronized the
> stream. Use u64 for the size, reject anything larger than SSIZE_MAX
> before malloc (same bound used by auxtrace_copy_data()), and compare
> readn()'s return value against (ssize_t)size to detect truncation.
> 
> Signed-off-by: Sizhe Liu <liusizhe5@huawei.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260730062709.534139-1-liusizhe5@huawei.com?part=2


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-07-30  6:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30  6:27 [PATCH v2 0/3] perf hisi-ptt: Fix TLP header parsing and naming Sizhe Liu
2026-07-30  6:27 ` [PATCH v2 1/3] perf hisi-ptt: Fix PTT trace TLP header parsing Sizhe Liu
2026-07-30  6:43   ` sashiko-bot
2026-07-30  6:27 ` [PATCH v2 2/3] perf hisi-ptt: Strengthen auxtrace event handling and packet type detection Sizhe Liu
2026-07-30  6:50   ` sashiko-bot
2026-07-30  6:27 ` [PATCH v2 3/3] perf hisi-ptt: Fix spelling and abbreviation errors Sizhe Liu
2026-07-30  6:34   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox