linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes
@ 2024-06-24 20:10 Adrian Hunter
  2024-06-24 20:10 ` [PATCH 1/7] perf/x86/intel/pt: Fix topa_entry base length Adrian Hunter
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

Hi

Here are some fixes.

I have taken the liberty of re-posting Marco Cavenati's patch from:

	https://lore.kernel.org/lkml/20240618110617.22626-1-cavenati.marco@gmail.com/

with updated commit suggested by Dave Hansen.


Adrian Hunter (6):
      perf/x86/intel/pt: Fix a topa_entry base address calculation
      perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation
      perf: Fix perf_aux_size() for greater-than 32-bit size
      perf: Prevent passing zero nr_pages to rb_alloc_aux()
      perf: Fix default aux_watermark calculation
      perf: Make rb_alloc_aux() return an error immediately if nr_pages <= 0

Marco Cavenati (1):
      perf/x86/intel/pt: Fix topa_entry base length

 arch/x86/events/intel/pt.c  | 4 ++--
 arch/x86/events/intel/pt.h  | 4 ++--
 kernel/events/core.c        | 2 ++
 kernel/events/internal.h    | 2 +-
 kernel/events/ring_buffer.c | 7 ++++++-
 5 files changed, 13 insertions(+), 6 deletions(-)


Regards
Adrian

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

* [PATCH 1/7] perf/x86/intel/pt: Fix topa_entry base length
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
@ 2024-06-24 20:10 ` Adrian Hunter
  2024-06-24 20:10 ` [PATCH 2/7] perf/x86/intel/pt: Fix a topa_entry base address calculation Adrian Hunter
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

From: Marco Cavenati <cavenati.marco@gmail.com>

topa_entry->base needs to store a pfn.  It obviously needs to be
large enough to store the largest possible x86 pfn which is
MAXPHYADDR-PAGE_SIZE (52-12).  So it is 4 bits too small.

Increase the size of topa_entry->base from 36 bits to 40 bits.

Note, systems where physical addresses can be 256TiB or more are affected.

[ Adrian: Amend commit message as suggested by Dave Hansen ]

Signed-off-by: Marco Cavenati <cavenati.marco@gmail.com>
Fixes: 52ca9ced3f70 ("perf/x86/intel/pt: Add Intel PT PMU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 arch/x86/events/intel/pt.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index 96906a62aacd..f5e46c04c145 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -33,8 +33,8 @@ struct topa_entry {
 	u64	rsvd2	: 1;
 	u64	size	: 4;
 	u64	rsvd3	: 2;
-	u64	base	: 36;
-	u64	rsvd4	: 16;
+	u64	base	: 40;
+	u64	rsvd4	: 12;
 };
 
 /* TSC to Core Crystal Clock Ratio */
-- 
2.34.1


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

* [PATCH 2/7] perf/x86/intel/pt: Fix a topa_entry base address calculation
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
  2024-06-24 20:10 ` [PATCH 1/7] perf/x86/intel/pt: Fix topa_entry base length Adrian Hunter
@ 2024-06-24 20:10 ` Adrian Hunter
  2024-06-24 20:10 ` [PATCH 3/7] perf/x86/intel/pt: Fix pt_topa_entry_for_page() " Adrian Hunter
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

topa_entry->base is a bit-field. Bit-fields are not promoted to a 64-bit
type, even if the underlying type is 64-bit, and so, if necessary, must
be cast to a larger type when calculations are done.

Fix a topa_entry->base address calculation by adding a cast.

Without the cast, the address was limited to 36-bits i.e. 64GiB.

The address calculation is used on systems that do not support Multiple
Entry ToPA (only Broadwell), and affects physical addresses on or above
64GiB. Instead of writing to the correct address, the address comprising
the first 36 bits would be written to.

Intel PT snapshot and sampling modes are not affected.

Reported-by: Dave Hansen <dave.hansen@linux.intel.com>
Fixes: 52ca9ced3f70 ("perf/x86/intel/pt: Add Intel PT PMU driver")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 arch/x86/events/intel/pt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 14db6d9d318b..047a2cd5b3fe 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -878,7 +878,7 @@ static void pt_update_head(struct pt *pt)
  */
 static void *pt_buffer_region(struct pt_buffer *buf)
 {
-	return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
+	return phys_to_virt((phys_addr_t)TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
 }
 
 /**
-- 
2.34.1


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

* [PATCH 3/7] perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
  2024-06-24 20:10 ` [PATCH 1/7] perf/x86/intel/pt: Fix topa_entry base length Adrian Hunter
  2024-06-24 20:10 ` [PATCH 2/7] perf/x86/intel/pt: Fix a topa_entry base address calculation Adrian Hunter
@ 2024-06-24 20:10 ` Adrian Hunter
  2024-06-24 20:10 ` [PATCH 4/7] perf: Fix perf_aux_size() for greater-than 32-bit size Adrian Hunter
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

Currently, perf allocates an array of page pointers which is limited in
size by MAX_PAGE_ORDER. That in turn limits the maximum Intel PT buffer
size to 2GiB. Should that limitation be lifted, the Intel PT driver can
support larger sizes, except for one calculation in
pt_topa_entry_for_page(), which is limited to 32-bits.

Fix pt_topa_entry_for_page() address calculation by adding a cast.

Fixes: 39152ee51b77 ("perf/x86/intel/pt: Get rid of reverse lookup table for ToPA")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 arch/x86/events/intel/pt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 047a2cd5b3fe..b4aa8daa4773 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -990,7 +990,7 @@ pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg)
 	 * order allocations, there shouldn't be many of these.
 	 */
 	list_for_each_entry(topa, &buf->tables, list) {
-		if (topa->offset + topa->size > pg << PAGE_SHIFT)
+		if (topa->offset + topa->size > (unsigned long)pg << PAGE_SHIFT)
 			goto found;
 	}
 
-- 
2.34.1


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

* [PATCH 4/7] perf: Fix perf_aux_size() for greater-than 32-bit size
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
                   ` (2 preceding siblings ...)
  2024-06-24 20:10 ` [PATCH 3/7] perf/x86/intel/pt: Fix pt_topa_entry_for_page() " Adrian Hunter
@ 2024-06-24 20:10 ` Adrian Hunter
  2024-06-24 20:10 ` [PATCH 5/7] perf: Prevent passing zero nr_pages to rb_alloc_aux() Adrian Hunter
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

perf_buffer->aux_nr_pages uses a 32-bit type, so a cast is needed to
calculate a 64-bit size.

Fixes: 45bfb2e50471 ("perf: Add AUX area to ring buffer for raw data streams")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 kernel/events/internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index 5150d5f84c03..386d21c7edfa 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -128,7 +128,7 @@ static inline unsigned long perf_data_size(struct perf_buffer *rb)
 
 static inline unsigned long perf_aux_size(struct perf_buffer *rb)
 {
-	return rb->aux_nr_pages << PAGE_SHIFT;
+	return (unsigned long)rb->aux_nr_pages << PAGE_SHIFT;
 }
 
 #define __DEFINE_OUTPUT_COPY_BODY(advance_buf, memcpy_func, ...)	\
-- 
2.34.1


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

* [PATCH 5/7] perf: Prevent passing zero nr_pages to rb_alloc_aux()
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
                   ` (3 preceding siblings ...)
  2024-06-24 20:10 ` [PATCH 4/7] perf: Fix perf_aux_size() for greater-than 32-bit size Adrian Hunter
@ 2024-06-24 20:10 ` Adrian Hunter
  2024-06-24 20:11 ` [PATCH 6/7] perf: Fix default aux_watermark calculation Adrian Hunter
  2024-06-24 20:11 ` [PATCH 7/7] perf: Make rb_alloc_aux() return an error immediately if nr_pages <= 0 Adrian Hunter
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:10 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

nr_pages is unsigned long but gets passed to rb_alloc_aux() as an int,
and is stored as an int.

Only power-of-2 values are accepted, so if nr_pages is a 64_bit value, it
will be passed to rb_alloc_aux() as zero.

That is not ideal because:
 1. the value is incorrect
 2. rb_alloc_aux() is at risk of misbehaving, although it manages to
 return -ENOMEM in that case, it is a result of passing zero to get_order()
 even though the get_order() result is documented to be undefined in that
 case.

Fix by simply validating the maximum supported value in the first place.
Use -ENOMEM error code for consistency with the current error code that
is returned in that case.

Fixes: 45bfb2e50471 ("perf: Add AUX area to ring buffer for raw data streams")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 kernel/events/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 8f908f077935..053e546d5bf0 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6509,6 +6509,8 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 			return -EINVAL;
 
 		nr_pages = vma_size / PAGE_SIZE;
+		if (nr_pages > INT_MAX)
+			return -ENOMEM;
 
 		mutex_lock(&event->mmap_mutex);
 		ret = -EINVAL;
-- 
2.34.1


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

* [PATCH 6/7] perf: Fix default aux_watermark calculation
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
                   ` (4 preceding siblings ...)
  2024-06-24 20:10 ` [PATCH 5/7] perf: Prevent passing zero nr_pages to rb_alloc_aux() Adrian Hunter
@ 2024-06-24 20:11 ` Adrian Hunter
  2024-06-24 20:11 ` [PATCH 7/7] perf: Make rb_alloc_aux() return an error immediately if nr_pages <= 0 Adrian Hunter
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:11 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

The default aux_watermark is half the AUX area buffer size. In general,
on a 64-bit architecture, the AUX area buffer size could be a bigger than
fits in a 32-bit type, but the calculation does not allow for that
possibility.

However the aux_watermark value is recorded in a u32, so should not be
more than U32_MAX either.

Fix by doing the calculation in a correctly sized type, and limiting the
result to U32_MAX.

Fixes: d68e6799a5c8 ("perf: Cap allocation order at aux_watermark")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 kernel/events/ring_buffer.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 4013408ce012..485cf0a66631 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -688,7 +688,9 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
 		 * max_order, to aid PMU drivers in double buffering.
 		 */
 		if (!watermark)
-			watermark = nr_pages << (PAGE_SHIFT - 1);
+			watermark = min_t(unsigned long,
+					  U32_MAX,
+					  (unsigned long)nr_pages << (PAGE_SHIFT - 1));
 
 		/*
 		 * Use aux_watermark as the basis for chunking to
-- 
2.34.1


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

* [PATCH 7/7] perf: Make rb_alloc_aux() return an error immediately if nr_pages <= 0
  2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
                   ` (5 preceding siblings ...)
  2024-06-24 20:11 ` [PATCH 6/7] perf: Fix default aux_watermark calculation Adrian Hunter
@ 2024-06-24 20:11 ` Adrian Hunter
  6 siblings, 0 replies; 8+ messages in thread
From: Adrian Hunter @ 2024-06-24 20:11 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
	H Peter Anvin, Mark Rutland, Alexander Shishkin, Marco Cavenati,
	Arnaldo Carvalho de Melo, Jiri Olsa, Namhyung Kim, Ian Rogers,
	Kan Liang, linux-kernel, linux-perf-users

rb_alloc_aux() should not be called with nr_pages <= 0. Make it more robust
and readable by returning an error immediately in that case.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
 kernel/events/ring_buffer.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 485cf0a66631..8cadf97bc290 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -682,6 +682,9 @@ int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
 	if (!has_aux(event))
 		return -EOPNOTSUPP;
 
+	if (nr_pages <= 0)
+		return -EINVAL;
+
 	if (!overwrite) {
 		/*
 		 * Watermark defaults to half the buffer, and so does the
-- 
2.34.1


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

end of thread, other threads:[~2024-06-24 20:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-24 20:10 [PATCH 0/7] perf: Intel PT and 64-bit AUX area size fixes Adrian Hunter
2024-06-24 20:10 ` [PATCH 1/7] perf/x86/intel/pt: Fix topa_entry base length Adrian Hunter
2024-06-24 20:10 ` [PATCH 2/7] perf/x86/intel/pt: Fix a topa_entry base address calculation Adrian Hunter
2024-06-24 20:10 ` [PATCH 3/7] perf/x86/intel/pt: Fix pt_topa_entry_for_page() " Adrian Hunter
2024-06-24 20:10 ` [PATCH 4/7] perf: Fix perf_aux_size() for greater-than 32-bit size Adrian Hunter
2024-06-24 20:10 ` [PATCH 5/7] perf: Prevent passing zero nr_pages to rb_alloc_aux() Adrian Hunter
2024-06-24 20:11 ` [PATCH 6/7] perf: Fix default aux_watermark calculation Adrian Hunter
2024-06-24 20:11 ` [PATCH 7/7] perf: Make rb_alloc_aux() return an error immediately if nr_pages <= 0 Adrian Hunter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).