diff mbox series

[v12,04/16] x86/mm: get INVLPGB count max from CPUID

Message ID 20250221005345.2156760-5-riel@surriel.com (mailing list archive)
State New
Headers show
Series AMD broadcast TLB invalidation | expand

Commit Message

Rik van Riel Feb. 21, 2025, 12:53 a.m. UTC
The CPU advertises the maximum number of pages that can be shot down
with one INVLPGB instruction in the CPUID data.

Save that information for later use.

Signed-off-by: Rik van Riel <riel@surriel.com>
Tested-by: Manali Shukla <Manali.Shukla@amd.com>
Tested-by: Brendan Jackman <jackmanb@google.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Acked-by: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/Kconfig.cpu               | 5 +++++
 arch/x86/include/asm/cpufeatures.h | 1 +
 arch/x86/include/asm/tlbflush.h    | 3 +++
 arch/x86/kernel/cpu/common.c       | 3 +++
 4 files changed, 12 insertions(+)

Comments

Borislav Petkov Feb. 21, 2025, 1:58 a.m. UTC | #1
On Thu, Feb 20, 2025 at 07:53:03PM -0500, Rik van Riel wrote:
> diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
> index 2a7279d80460..bb6943c21b7f 100644
> --- a/arch/x86/Kconfig.cpu
> +++ b/arch/x86/Kconfig.cpu
> @@ -401,6 +401,10 @@ menuconfig PROCESSOR_SELECT
>  	  This lets you choose what x86 vendor support code your kernel
>  	  will include.
>  
> +config X86_BROADCAST_TLB_FLUSH
> +	def_bool y
> +	depends on CPU_SUP_AMD && 64BIT
> +
>  config CPU_SUP_INTEL
>  	default y
>  	bool "Support Intel processors" if PROCESSOR_SELECT
> @@ -431,6 +435,7 @@ config CPU_SUP_CYRIX_32
>  config CPU_SUP_AMD
>  	default y
>  	bool "Support AMD processors" if PROCESSOR_SELECT
> +	select X86_BROADCAST_TLB_FLUSH
>  	help
>  	  This enables detection, tunings and quirks for AMD processors

You missed my comment again. How about you read review feedback more carefully
please?

CPU_SUP_AMD selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD which
selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD...

You need to make up your mind in which way the dependency should be. Certainly
not circular.
Rik van Riel Feb. 21, 2025, 2:25 a.m. UTC | #2
On Fri, 2025-02-21 at 02:58 +0100, Borislav Petkov wrote:
> On Thu, Feb 20, 2025 at 07:53:03PM -0500, Rik van Riel wrote:
> > diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
> > index 2a7279d80460..bb6943c21b7f 100644
> > --- a/arch/x86/Kconfig.cpu
> > +++ b/arch/x86/Kconfig.cpu
> > @@ -401,6 +401,10 @@ menuconfig PROCESSOR_SELECT
> >  	  This lets you choose what x86 vendor support code your
> > kernel
> >  	  will include.
> >  
> > +config X86_BROADCAST_TLB_FLUSH
> > +	def_bool y
> > +	depends on CPU_SUP_AMD && 64BIT
> > +
> >  config CPU_SUP_INTEL
> >  	default y
> >  	bool "Support Intel processors" if PROCESSOR_SELECT
> > @@ -431,6 +435,7 @@ config CPU_SUP_CYRIX_32
> >  config CPU_SUP_AMD
> >  	default y
> >  	bool "Support AMD processors" if PROCESSOR_SELECT
> > +	select X86_BROADCAST_TLB_FLUSH
> >  	help
> >  	  This enables detection, tunings and quirks for AMD
> > processors
> 
> You missed my comment again. How about you read review feedback more
> carefully
> please?
> 
I try, but most of my brainpower the last round was
spent trying to figure out what to do where you and
Dave both wanted something different :)

> CPU_SUP_AMD selects X86_BROADCAST_TLB_FLUSH which depends on
> CPU_SUP_AMD which
> selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD...

I'll fix that to have it depend only on 64BIT.
Rik van Riel Feb. 21, 2025, 6:03 p.m. UTC | #3
On Fri, 21 Feb 2025 02:58:01 +0100
Borislav Petkov <bp@alien8.de> wrote:


> CPU_SUP_AMD selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD which
> selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD...
> 
> You need to make up your mind in which way the dependency should be. Certainly
> not circular.

I've attached the new version below:

---8<---

From 8da3d9f792427e434900a45e6d6391b28cf834d1 Mon Sep 17 00:00:00 2001
From: Rik van Riel <riel@surriel.com>
Date: Thu, 20 Feb 2025 21:25:08 -0500
Subject: [PATCH 04/16] x86/mm: get INVLPGB count max from CPUID

The CPU advertises the maximum number of pages that can be shot down
with one INVLPGB instruction in the CPUID data.

Save that information for later use.

Signed-off-by: Rik van Riel <riel@surriel.com>
Tested-by: Manali Shukla <Manali.Shukla@amd.com>
Tested-by: Brendan Jackman <jackmanb@google.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Acked-by: Dave Hansen <dave.hansen@intel.com>
---
 arch/x86/Kconfig.cpu               | 5 +++++
 arch/x86/include/asm/cpufeatures.h | 1 +
 arch/x86/include/asm/tlbflush.h    | 3 +++
 arch/x86/kernel/cpu/common.c       | 3 +++
 4 files changed, 12 insertions(+)

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 2a7279d80460..c371b94aa5d7 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -401,6 +401,10 @@ menuconfig PROCESSOR_SELECT
 	  This lets you choose what x86 vendor support code your kernel
 	  will include.
 
+config X86_BROADCAST_TLB_FLUSH
+	def_bool y
+	depends on 64BIT
+
 config CPU_SUP_INTEL
 	default y
 	bool "Support Intel processors" if PROCESSOR_SELECT
@@ -431,6 +435,7 @@ config CPU_SUP_CYRIX_32
 config CPU_SUP_AMD
 	default y
 	bool "Support AMD processors" if PROCESSOR_SELECT
+	select X86_BROADCAST_TLB_FLUSH
 	help
 	  This enables detection, tunings and quirks for AMD processors
 
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 508c0dad116b..b5c66b7465ba 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -338,6 +338,7 @@
 #define X86_FEATURE_CLZERO		(13*32+ 0) /* "clzero" CLZERO instruction */
 #define X86_FEATURE_IRPERF		(13*32+ 1) /* "irperf" Instructions Retired Count */
 #define X86_FEATURE_XSAVEERPTR		(13*32+ 2) /* "xsaveerptr" Always save/restore FP error pointers */
+#define X86_FEATURE_INVLPGB		(13*32+ 3) /* INVLPGB and TLBSYNC instruction supported. */
 #define X86_FEATURE_RDPRU		(13*32+ 4) /* "rdpru" Read processor register at user level */
 #define X86_FEATURE_WBNOINVD		(13*32+ 9) /* "wbnoinvd" WBNOINVD instruction */
 #define X86_FEATURE_AMD_IBPB		(13*32+12) /* Indirect Branch Prediction Barrier */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 3da645139748..09463a2fb05f 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -183,6 +183,9 @@ static inline void cr4_init_shadow(void)
 extern unsigned long mmu_cr4_features;
 extern u32 *trampoline_cr4_features;
 
+/* How many pages can we invalidate with one INVLPGB. */
+extern u16 invlpgb_count_max;
+
 extern void initialize_tlbstate_and_flush(void);
 
 /*
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7cce91b19fb2..742bdb0c4846 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -95,6 +95,8 @@ EXPORT_SYMBOL(__num_cores_per_package);
 unsigned int __num_threads_per_package __ro_after_init = 1;
 EXPORT_SYMBOL(__num_threads_per_package);
 
+u16 invlpgb_count_max __ro_after_init;
+
 static struct ppin_info {
 	int	feature;
 	int	msr_ppin_ctl;
@@ -1030,6 +1032,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
 	if (c->extended_cpuid_level >= 0x80000008) {
 		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
 		c->x86_capability[CPUID_8000_0008_EBX] = ebx;
+		invlpgb_count_max = (edx & 0xffff) + 1;
 	}
 
 	if (c->extended_cpuid_level >= 0x8000000a)
Tom Lendacky Feb. 21, 2025, 6:41 p.m. UTC | #4
On 2/21/25 12:03, Rik van Riel wrote:
> On Fri, 21 Feb 2025 02:58:01 +0100
> Borislav Petkov <bp@alien8.de> wrote:
> 
> 
>> CPU_SUP_AMD selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD which
>> selects X86_BROADCAST_TLB_FLUSH which depends on CPU_SUP_AMD...
>>
>> You need to make up your mind in which way the dependency should be. Certainly
>> not circular.
> 
> I've attached the new version below:
> 
> ---8<---
> 
> From 8da3d9f792427e434900a45e6d6391b28cf834d1 Mon Sep 17 00:00:00 2001
> From: Rik van Riel <riel@surriel.com>
> Date: Thu, 20 Feb 2025 21:25:08 -0500
> Subject: [PATCH 04/16] x86/mm: get INVLPGB count max from CPUID
> 
> The CPU advertises the maximum number of pages that can be shot down
> with one INVLPGB instruction in the CPUID data.
> 
> Save that information for later use.
> 
> Signed-off-by: Rik van Riel <riel@surriel.com>
> Tested-by: Manali Shukla <Manali.Shukla@amd.com>
> Tested-by: Brendan Jackman <jackmanb@google.com>
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Acked-by: Dave Hansen <dave.hansen@intel.com>
> ---
>  arch/x86/Kconfig.cpu               | 5 +++++
>  arch/x86/include/asm/cpufeatures.h | 1 +
>  arch/x86/include/asm/tlbflush.h    | 3 +++
>  arch/x86/kernel/cpu/common.c       | 3 +++
>  4 files changed, 12 insertions(+)
> 
> diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
> index 2a7279d80460..c371b94aa5d7 100644
> --- a/arch/x86/Kconfig.cpu
> +++ b/arch/x86/Kconfig.cpu
> @@ -401,6 +401,10 @@ menuconfig PROCESSOR_SELECT
>  	  This lets you choose what x86 vendor support code your kernel
>  	  will include.
>  
> +config X86_BROADCAST_TLB_FLUSH
> +	def_bool y
> +	depends on 64BIT

I think what you really want is:

	depends on CPU_SUP_AMD && 64BIT

And then delete the select X86_BROADCAST_TLB_FLUSH below.

Otherwise, won't it be y even if CPU_SUP_AMD isn't y?

Thanks,
Tom

> +
>  config CPU_SUP_INTEL
>  	default y
>  	bool "Support Intel processors" if PROCESSOR_SELECT
> @@ -431,6 +435,7 @@ config CPU_SUP_CYRIX_32
>  config CPU_SUP_AMD
>  	default y
>  	bool "Support AMD processors" if PROCESSOR_SELECT
> +	select X86_BROADCAST_TLB_FLUSH
>  	help
>  	  This enables detection, tunings and quirks for AMD processors
>  
> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
> index 508c0dad116b..b5c66b7465ba 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -338,6 +338,7 @@
>  #define X86_FEATURE_CLZERO		(13*32+ 0) /* "clzero" CLZERO instruction */
>  #define X86_FEATURE_IRPERF		(13*32+ 1) /* "irperf" Instructions Retired Count */
>  #define X86_FEATURE_XSAVEERPTR		(13*32+ 2) /* "xsaveerptr" Always save/restore FP error pointers */
> +#define X86_FEATURE_INVLPGB		(13*32+ 3) /* INVLPGB and TLBSYNC instruction supported. */
>  #define X86_FEATURE_RDPRU		(13*32+ 4) /* "rdpru" Read processor register at user level */
>  #define X86_FEATURE_WBNOINVD		(13*32+ 9) /* "wbnoinvd" WBNOINVD instruction */
>  #define X86_FEATURE_AMD_IBPB		(13*32+12) /* Indirect Branch Prediction Barrier */
> diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
> index 3da645139748..09463a2fb05f 100644
> --- a/arch/x86/include/asm/tlbflush.h
> +++ b/arch/x86/include/asm/tlbflush.h
> @@ -183,6 +183,9 @@ static inline void cr4_init_shadow(void)
>  extern unsigned long mmu_cr4_features;
>  extern u32 *trampoline_cr4_features;
>  
> +/* How many pages can we invalidate with one INVLPGB. */
> +extern u16 invlpgb_count_max;
> +
>  extern void initialize_tlbstate_and_flush(void);
>  
>  /*
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index 7cce91b19fb2..742bdb0c4846 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -95,6 +95,8 @@ EXPORT_SYMBOL(__num_cores_per_package);
>  unsigned int __num_threads_per_package __ro_after_init = 1;
>  EXPORT_SYMBOL(__num_threads_per_package);
>  
> +u16 invlpgb_count_max __ro_after_init;
> +
>  static struct ppin_info {
>  	int	feature;
>  	int	msr_ppin_ctl;
> @@ -1030,6 +1032,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
>  	if (c->extended_cpuid_level >= 0x80000008) {
>  		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
>  		c->x86_capability[CPUID_8000_0008_EBX] = ebx;
> +		invlpgb_count_max = (edx & 0xffff) + 1;
>  	}
>  
>  	if (c->extended_cpuid_level >= 0x8000000a)
diff mbox series

Patch

diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 2a7279d80460..bb6943c21b7f 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -401,6 +401,10 @@  menuconfig PROCESSOR_SELECT
 	  This lets you choose what x86 vendor support code your kernel
 	  will include.
 
+config X86_BROADCAST_TLB_FLUSH
+	def_bool y
+	depends on CPU_SUP_AMD && 64BIT
+
 config CPU_SUP_INTEL
 	default y
 	bool "Support Intel processors" if PROCESSOR_SELECT
@@ -431,6 +435,7 @@  config CPU_SUP_CYRIX_32
 config CPU_SUP_AMD
 	default y
 	bool "Support AMD processors" if PROCESSOR_SELECT
+	select X86_BROADCAST_TLB_FLUSH
 	help
 	  This enables detection, tunings and quirks for AMD processors
 
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 508c0dad116b..b5c66b7465ba 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -338,6 +338,7 @@ 
 #define X86_FEATURE_CLZERO		(13*32+ 0) /* "clzero" CLZERO instruction */
 #define X86_FEATURE_IRPERF		(13*32+ 1) /* "irperf" Instructions Retired Count */
 #define X86_FEATURE_XSAVEERPTR		(13*32+ 2) /* "xsaveerptr" Always save/restore FP error pointers */
+#define X86_FEATURE_INVLPGB		(13*32+ 3) /* INVLPGB and TLBSYNC instruction supported. */
 #define X86_FEATURE_RDPRU		(13*32+ 4) /* "rdpru" Read processor register at user level */
 #define X86_FEATURE_WBNOINVD		(13*32+ 9) /* "wbnoinvd" WBNOINVD instruction */
 #define X86_FEATURE_AMD_IBPB		(13*32+12) /* Indirect Branch Prediction Barrier */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 3da645139748..09463a2fb05f 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -183,6 +183,9 @@  static inline void cr4_init_shadow(void)
 extern unsigned long mmu_cr4_features;
 extern u32 *trampoline_cr4_features;
 
+/* How many pages can we invalidate with one INVLPGB. */
+extern u16 invlpgb_count_max;
+
 extern void initialize_tlbstate_and_flush(void);
 
 /*
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7cce91b19fb2..742bdb0c4846 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -95,6 +95,8 @@  EXPORT_SYMBOL(__num_cores_per_package);
 unsigned int __num_threads_per_package __ro_after_init = 1;
 EXPORT_SYMBOL(__num_threads_per_package);
 
+u16 invlpgb_count_max __ro_after_init;
+
 static struct ppin_info {
 	int	feature;
 	int	msr_ppin_ctl;
@@ -1030,6 +1032,7 @@  void get_cpu_cap(struct cpuinfo_x86 *c)
 	if (c->extended_cpuid_level >= 0x80000008) {
 		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
 		c->x86_capability[CPUID_8000_0008_EBX] = ebx;
+		invlpgb_count_max = (edx & 0xffff) + 1;
 	}
 
 	if (c->extended_cpuid_level >= 0x8000000a)