arch/x86/include/asm/cpufeatures.h | 2 +- tools/arch/x86/include/asm/cpufeatures.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
Allow X86_FEATURE_SHST to be disabled through the kernel commandline via
'clearcpuid=shstk' as 'nousershstk' would still enable CR4.CET even if
no CET features are in use.
This, in combination with disabling IBT as well, e.g. via
'clearcpuid=shstk,ibt' allows to fully disable CR4.CET enabling on
capable hardware, which in turn allows debugging CET-related issues
during early boot.
Signed-off-by: Mathias Krause <minipli@grsecurity.net>
---
v3:
- switch to clearcpuid-based approach
v2: https://lore.kernel.org/lkml/20260402173606.1096172-1-minipli@grsecurity.net/
arch/x86/include/asm/cpufeatures.h | 2 +-
tools/arch/x86/include/asm/cpufeatures.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 1d506e5d6f46..75cc39037df6 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -393,7 +393,7 @@
#define X86_FEATURE_OSPKE (16*32+ 4) /* "ospke" OS Protection Keys Enable */
#define X86_FEATURE_WAITPKG (16*32+ 5) /* "waitpkg" UMONITOR/UMWAIT/TPAUSE Instructions */
#define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* "avx512_vbmi2" Additional AVX512 Vector Bit Manipulation Instructions */
-#define X86_FEATURE_SHSTK (16*32+ 7) /* Shadow stack */
+#define X86_FEATURE_SHSTK (16*32+ 7) /* "shstk" CET Shadow Stack */
#define X86_FEATURE_GFNI (16*32+ 8) /* "gfni" Galois Field New Instructions */
#define X86_FEATURE_VAES (16*32+ 9) /* "vaes" Vector AES */
#define X86_FEATURE_VPCLMULQDQ (16*32+10) /* "vpclmulqdq" Carry-Less Multiplication Double Quadword */
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 86d17b195e79..fcbe633e1f76 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -393,7 +393,7 @@
#define X86_FEATURE_OSPKE (16*32+ 4) /* "ospke" OS Protection Keys Enable */
#define X86_FEATURE_WAITPKG (16*32+ 5) /* "waitpkg" UMONITOR/UMWAIT/TPAUSE Instructions */
#define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* "avx512_vbmi2" Additional AVX512 Vector Bit Manipulation Instructions */
-#define X86_FEATURE_SHSTK (16*32+ 7) /* Shadow stack */
+#define X86_FEATURE_SHSTK (16*32+ 7) /* "shstk" CET Shadow Stack */
#define X86_FEATURE_GFNI (16*32+ 8) /* "gfni" Galois Field New Instructions */
#define X86_FEATURE_VAES (16*32+ 9) /* "vaes" Vector AES */
#define X86_FEATURE_VPCLMULQDQ (16*32+10) /* "vpclmulqdq" Carry-Less Multiplication Double Quadword */
--
2.47.3
On Thu, 2026-05-14 at 18:09 +0200, Mathias Krause wrote: > Allow X86_FEATURE_SHST to be disabled through the kernel commandline via > 'clearcpuid=shstk' as 'nousershstk' would still enable CR4.CET even if > no CET features are in use. > > This, in combination with disabling IBT as well, e.g. via > 'clearcpuid=shstk,ibt' allows to fully disable CR4.CET enabling on > capable hardware, which in turn allows debugging CET-related issues > during early boot. > > Signed-off-by: Mathias Krause <minipli@grsecurity.net> > --- > v3: > - switch to clearcpuid-based approach > v2: https://lore.kernel.org/lkml/20260402173606.1096172-1-minipli@grsecurity.net/ > > arch/x86/include/asm/cpufeatures.h | 2 +- To the general approach: Acked-by: Rick Edgecombe <rick.p.edgecombe@intel.com> > tools/arch/x86/include/asm/cpufeatures.h | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h > index 1d506e5d6f46..75cc39037df6 100644 > --- a/arch/x86/include/asm/cpufeatures.h > +++ b/arch/x86/include/asm/cpufeatures.h > @@ -393,7 +393,7 @@ > #define X86_FEATURE_OSPKE (16*32+ 4) /* "ospke" OS Protection Keys Enable */ > #define X86_FEATURE_WAITPKG (16*32+ 5) /* "waitpkg" UMONITOR/UMWAIT/TPAUSE Instructions */ > #define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* "avx512_vbmi2" Additional AVX512 Vector Bit Manipulation Instructions */ > -#define X86_FEATURE_SHSTK (16*32+ 7) /* Shadow stack */ > +#define X86_FEATURE_SHSTK (16*32+ 7) /* "shstk" CET Shadow Stack */ I hate to generate another version but adding CET here is an unnecessary change. IBT doesn't match then. > #define X86_FEATURE_GFNI (16*32+ 8) /* "gfni" Galois Field New Instructions */ > #define X86_FEATURE_VAES (16*32+ 9) /* "vaes" Vector AES */ > #define X86_FEATURE_VPCLMULQDQ (16*32+10) /* "vpclmulqdq" Carry-Less Multiplication Double Quadword */ > diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h > index 86d17b195e79..fcbe633e1f76 100644 > --- a/tools/arch/x86/include/asm/cpufeatures.h > +++ b/tools/arch/x86/include/asm/cpufeatures.h > @@ -393,7 +393,7 @@ > #define X86_FEATURE_OSPKE (16*32+ 4) /* "ospke" OS Protection Keys Enable */ > #define X86_FEATURE_WAITPKG (16*32+ 5) /* "waitpkg" UMONITOR/UMWAIT/TPAUSE Instructions */ > #define X86_FEATURE_AVX512_VBMI2 (16*32+ 6) /* "avx512_vbmi2" Additional AVX512 Vector Bit Manipulation Instructions */ > -#define X86_FEATURE_SHSTK (16*32+ 7) /* Shadow stack */ > +#define X86_FEATURE_SHSTK (16*32+ 7) /* "shstk" CET Shadow Stack */ > #define X86_FEATURE_GFNI (16*32+ 8) /* "gfni" Galois Field New Instructions */ > #define X86_FEATURE_VAES (16*32+ 9) /* "vaes" Vector AES */ > #define X86_FEATURE_VPCLMULQDQ (16*32+10) /* "vpclmulqdq" Carry-Less Multiplication Double Quadword */
On Thu, May 14, 2026 at 06:09:32PM +0200, Mathias Krause wrote:
> Allow X86_FEATURE_SHST to be disabled through the kernel commandline via
> 'clearcpuid=shstk' as 'nousershstk' would still enable CR4.CET even if
> no CET features are in use.
clearcpuid= taints the kernel because that cmdline option is not supposed to
be used except for debugging crap... and alas people are still using it. No
wonder... :-\
Anyway, "nousershstk" should disable the CR4 bit too.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On 5/14/26 18:59, Borislav Petkov wrote: > On Thu, May 14, 2026 at 06:09:32PM +0200, Mathias Krause wrote: >> Allow X86_FEATURE_SHST to be disabled through the kernel commandline via >> 'clearcpuid=shstk' as 'nousershstk' would still enable CR4.CET even if >> no CET features are in use. > > clearcpuid= taints the kernel because that cmdline option is not supposed to > be used except for debugging crap... and alas people are still using it. No > wonder... :-\ Funny to see how x86 maintainer options completely disagree on this, see https://lore.kernel.org/lkml/739e4dd0-84a3-4b37-8cc3-b7ec59737010@intel.com/ > > Anyway, "nousershstk" should disable the CR4 bit too. > No, it should not, as that's only for the user portion (X86_FEATURE_USER_SHSTK != X86_FEATURE_SHSTK). Even though there is (currently) no kernel level shadow stack support, KVM may still want to pass it down to guests for their usage -- even if the host *userland* shouldn't make use of it because of "nousershstk". Thanks, Mathias
On Fri, May 15, 2026 at 06:11:46PM +0200, Mathias Krause wrote:
> Funny to see how x86 maintainer options completely disagree on this, see
> https://lore.kernel.org/lkml/739e4dd0-84a3-4b37-8cc3-b7ec59737010@intel.com/
You mean we should have an internal meeting first to agree on maintainer
policy so that we can have a common, unified messaging to the rest of the
community...?
Or are we allowed to disagree and find the most optimal solution in the
process?
Pfff.
> No, it should not, as that's only for the user portion
> (X86_FEATURE_USER_SHSTK != X86_FEATURE_SHSTK).
>
> Even though there is (currently) no kernel level shadow stack support,
> KVM may still want to pass it down to guests for their usage -- even if
> the host *userland* shouldn't make use of it because of "nousershstk".
So do a global "disable control-flow enforcement" thing which disables all
related features, as Rick points out.
That one should dump a warning saying what also it disables and that it should
be a debugging option. And I'm thinking it probably should taint the kernel
too because we don't want people left'n'right to turn off shadow stacks and
then complain...
Btw, this is my own opinion and just a suggestion - not a x86 maintainer
stance. I'm throwing this out so that someone else can propose a better one
and we arrive at the proper solution eventually. I.e., as we have always done
it on the mailing list...
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On 16.05.26 17:27, Borislav Petkov wrote: > On Fri, May 15, 2026 at 06:11:46PM +0200, Mathias Krause wrote: >> Funny to see how x86 maintainer options completely disagree on this, see >> https://lore.kernel.org/lkml/739e4dd0-84a3-4b37-8cc3-b7ec59737010@intel.com/ > > You mean we should have an internal meeting first to agree on maintainer > policy so that we can have a common, unified messaging to the rest of the > community...? ?!? > > Or are we allowed to disagree and find the most optimal solution in the > process? Of course you are. However, it would be nice to object in time and not make a contributor implement N iterations, each being different, just because the next maintainer didn't like the previous version. Or, at least, other maintainers chiming in and commenting to the direction change from their proposal. Neither happened here. I mean, it's a stupid debugging feature, how perfect does it need to be? > > Pfff. > >> No, it should not, as that's only for the user portion >> (X86_FEATURE_USER_SHSTK != X86_FEATURE_SHSTK). >> >> Even though there is (currently) no kernel level shadow stack support, >> KVM may still want to pass it down to guests for their usage -- even if >> the host *userland* shouldn't make use of it because of "nousershstk". > > So do a global "disable control-flow enforcement" thing which disables all > related features, as Rick points out. Sorry, I can't figure which suggestion of Rick you are referring to but maybe you're mixing it up with that?: https://lore.kernel.org/lkml/bf9738e1-330e-4c87-a294-e8dce100ffc2@grsecurity.net/ > > That one should dump a warning saying what also it disables and that it should > be a debugging option. And I'm thinking it probably should taint the kernel > too because we don't want people left'n'right to turn off shadow stacks and > then complain... This is getting ridiculous. It's a debug feature by nature and it feels like clearcpuid=shstk would almost perfectly match above requirements. > > Btw, this is my own opinion and just a suggestion - not a x86 maintainer > stance. I'm throwing this out so that someone else can propose a better one > and we arrive at the proper solution eventually. I.e., as we have always done > it on the mailing list... > Yeah, I'm out. We just handle this downstream. Thanks, Mathias
On Fri, 2026-05-15 at 18:11 +0200, Mathias Krause wrote: > > > > Anyway, "nousershstk" should disable the CR4 bit too. > > > > No, it should not, as that's only for the user portion > (X86_FEATURE_USER_SHSTK != X86_FEATURE_SHSTK). > > Even though there is (currently) no kernel level shadow stack support, > KVM may still want to pass it down to guests for their usage -- even if > the host *userland* shouldn't make use of it because of "nousershstk". Yea, I was thinking on how we would implement this and wondering along these same lines. We would need to set CR4.CET if we have kernel ibt, user shadow stack or KVM configured (and also with HW support).
On Thu, 2026-05-14 at 18:59 +0200, Borislav Petkov wrote: > On Thu, May 14, 2026 at 06:09:32PM +0200, Mathias Krause wrote: > > Allow X86_FEATURE_SHST to be disabled through the kernel commandline via > > 'clearcpuid=shstk' as 'nousershstk' would still enable CR4.CET even if > > no CET features are in use. > > clearcpuid= taints the kernel because that cmdline option is not supposed to > be used except for debugging crap... and alas people are still using it. No > wonder... :-\ Do we want a non-taint version of this capability? That was Mathias' original approach, but his use was just debugging. So hence, this. Also, have you ever thought about keeping a list of approved clearcpuid values that are supported for normal runtime. People could use it to turn off features without picking up a taint? Like maybe people want to turn off something for performance reasons or something. Then we can have one interface for it all, instead of various nousershstk-like flags. Not sure if it's a good. > > Anyway, "nousershstk" should disable the CR4 bit too. Mathias, I can send a patch for this if you want to be done with this.
On 5/14/26 10:07, Edgecombe, Rick P wrote: > Also, have you ever thought about keeping a list of approved clearcpuid values > that are supported for normal runtime. People could use it to turn off features > without picking up a taint? What's wrong with taint? "I got a bug report from Joe who has a system with feature $FOO and not feature $BAR. I don't have that CPU, so I used clearcpuid=$BAR to help reproduce the bug. Here's the oops I saw..." We're not going to ignore that bug report. We're going to look at it a bit closer and make sure the taint does appear to be from clearcpuid=$BAR. But the taint is *FINE*.
On Thu, 2026-05-14 at 10:30 -0700, Dave Hansen wrote: > On 5/14/26 10:07, Edgecombe, Rick P wrote: > > Also, have you ever thought about keeping a list of approved clearcpuid values > > that are supported for normal runtime. People could use it to turn off features > > without picking up a taint? > > What's wrong with taint? > > "I got a bug report from Joe who has a system with feature $FOO and not > feature $BAR. I don't have that CPU, so I used clearcpuid=$BAR to help > reproduce the bug. Here's the oops I saw..." > > We're not going to ignore that bug report. We're going to look at it a > bit closer and make sure the taint does appear to be from > clearcpuid=$BAR. But the taint is *FINE*. For debugging I don't see a problem with the taint. But I meant instead of nofoo for the cases where there is some other purpose. I just thought the clearcpuid solution was kind of slick compared to nofoo.
On Thu, May 14, 2026 at 05:07:30PM +0000, Edgecombe, Rick P wrote:
> Do we want a non-taint version of this capability? That was Mathias' original
> approach, but his use was just debugging. So hence, this.
No, we don't:
Also note that user programs calling CPUID directly
or using the feature without checking anything
will still see it. This just prevents it from
being used by the kernel or shown in /proc/cpuinfo.
Also note the kernel might malfunction if you disable
some critical bits.
Do you want to debug issues because someone decided to shoot our
representation of a CPUID flag and something is not being detected because of
this and you're scratching your head why TF it happens?
> Also, have you ever thought about keeping a list of approved clearcpuid values
> that are supported for normal runtime. People could use it to turn off features
> without picking up a taint? Like maybe people want to turn off something for
> performance reasons or something. Then we can have one interface for it all,
> instead of various nousershstk-like flags. Not sure if it's a good.
No, we have "no..." cmdline arguments for things where disabling the feature
makes sense. And we support those.
The other "no..." switches we add usually as part of a chicken bit when adding
a new feature. Subsequently, we delete them after it turns out the
implementation is fine and there's no need for any chicken bit anymore.
If "nousershstk" has a good use case like being able to disable CET issues,
then by all means, that justifies supporting it fully.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On Thu, 2026-05-14 at 19:12 +0200, Borislav Petkov wrote: > On Thu, May 14, 2026 at 05:07:30PM +0000, Edgecombe, Rick P wrote: > > Do we want a non-taint version of this capability? That was Mathias' original > > approach, but his use was just debugging. So hence, this. > > No, we don't: > > Also note that user programs calling CPUID directly > or using the feature without checking anything > will still see it. This just prevents it from > being used by the kernel or shown in /proc/cpuinfo. > Also note the kernel might malfunction if you disable > some critical bits. > > Do you want to debug issues because someone decided to shoot our > representation of a CPUID flag and something is not being detected because of > this and you're scratching your head why TF it happens? I didn't mean to support disabling them all. I meant have a thing with the same format as clearcpuid, but only works for features we want to support. So maybe like disable=usershstk. And then have just less code to have to cover all the nofoo cases. It would only support limited bits that were intentionally added. This is not a well thought out idea though. > > > Also, have you ever thought about keeping a list of approved clearcpuid values > > that are supported for normal runtime. People could use it to turn off features > > without picking up a taint? Like maybe people want to turn off something for > > performance reasons or something. Then we can have one interface for it all, > > instead of various nousershstk-like flags. Not sure if it's a good. > > No, we have "no..." cmdline arguments for things where disabling the feature > makes sense. And we support those. > > The other "no..." switches we add usually as part of a chicken bit when adding > a new feature. Subsequently, we delete them after it turns out the > implementation is fine and there's no need for any chicken bit anymore. Oh, I didn't realize they were intended to be short term things. > > If "nousershstk" has a good use case like being able to disable CET issues, > then by all means, that justifies supporting it fully. Fair enough, thanks for the consideration.
On Thu, May 14, 2026 at 06:23:29PM +0000, Edgecombe, Rick P wrote:
> I didn't mean to support disabling them all. I meant have a thing with the same
> format as clearcpuid, but only works for features we want to support. So maybe
> like disable=usershstk. And then have just less code to have to cover all the
> nofoo cases. It would only support limited bits that were intentionally added.
>
> This is not a well thought out idea though.
I can see that...
If you want to disable things, then you need to disable them properly. Like
turn off CR4 bits in this case or disable dependent features in other cases.
Or whatever else is needed.
Whatever you do, it needs to have a use case and be properly done.
clearcpuid= is simply shooting down X86_FEATURE flags. Not really well thought
out but a wholesale quick'n'dirty method of toggling feature bits (yah,
there's the setcpuid= counterpart too). And that's why it should not really
exist but that ship has sailed...
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
On 5/15/26 00:38, Borislav Petkov wrote: > If you want to disable things, then you need to disable them properly. Like > turn off CR4 bits in this case or disable dependent features in other cases. > Or whatever else is needed. > > Whatever you do, it needs to have a use case and be properly done. > > clearcpuid= is simply shooting down X86_FEATURE flags. Not really well thought > out but a wholesale quick'n'dirty method of toggling feature bits (yah, > there's the setcpuid= counterpart too). And that's why it should not really > exist but that ship has sailed... > So a "nocet" for that very use case of disabling CR4.CET, which would simply disable X86_FEATURE_IBT and X86_FEATURE_SHSTK? Thanks, Mathias
I would even want to do that.
Just so that people don't get silly ideas...
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 4d0f545fb3ec..97007f4f69d4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -789,24 +789,6 @@ Kernel parameters
cio_ignore= [S390]
See Documentation/arch/s390/common_io.rst for details.
- clearcpuid=X[,X...] [X86]
- Disable CPUID feature X for the kernel. See
- arch/x86/include/asm/cpufeatures.h for the valid bit
- numbers X. Note the Linux-specific bits are not necessarily
- stable over kernel options, but the vendor-specific
- ones should be.
- X can also be a string as appearing in the flags: line
- in /proc/cpuinfo which does not have the above
- instability issue. However, not all features have names
- in /proc/cpuinfo.
- Note that using this option will taint your kernel.
- Also note that user programs calling CPUID directly
- or using the feature without checking anything
- will still see it. This just prevents it from
- being used by the kernel or shown in /proc/cpuinfo.
- Also note the kernel might malfunction if you disable
- some critical bits.
-
clk_ignore_unused
[CLK]
Prevents the clock framework from automatically gating
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
© 2016 - 2026 Red Hat, Inc.