Message ID | 20250221005345.2156760-5-riel@surriel.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | AMD broadcast TLB invalidation | expand |
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.
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.
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)
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)
On Fri, 21 Feb 2025 12:41:40 -0600 Tom Lendacky <thomas.lendacky@amd.com> wrote: > 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? I think you're right. Good catch. I currently have this in my tree: ---8<--- From 49edabe3a1f338b4386c41ff5d378584a320e3db Mon Sep 17 00:00:00 2001 From: Rik van Riel <riel@surriel.com> Date: Fri, 21 Feb 2025 15:28:39 -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 | 4 ++++ arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/tlbflush.h | 3 +++ arch/x86/kernel/cpu/common.c | 3 +++ 4 files changed, 11 insertions(+) diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 2a7279d80460..981def9cbfac 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 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 --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)