Re: [PATCH v6 10/90] x86/cpu: Rescan CPUID table after disabling PSN

From: Ahmed S. Darwish

Date: Wed May 13 2026 - 13:47:38 EST


On Wed, 13 May 2026, Borislav Petkov wrote:
>
> I think you mean whatever has done clear_cpu_cap() which doesn't use the
> cpu_caps_cleared/set arrays.
>

Exactly.

There are almost a 100 call sites which directly do a set_cpu_cap():

git grep 'set_cpu_cap(c, X86' arch/x86/

And none of those goes through the cpu_caps_set[] array, and thus into the
apply_forced_caps() thing. The bit is just directly set through bitops.

So, resetting the CPUID table whole sale will drastically alter the x86
subystem behavior here.

> > I'm sending another patch queue iteration shortly that have a new API
> > function abstracting this min_t() logic in its own parser function, along
> > with better documentation:
> >
> > https://lkml.kernel.org/agSfWTxs9pRPHJxl@lx-t490/
>
> And I don't want to pay attention to which ranges I've parsed and which I
> haven't. That's too fragile. I want to simply rescan the whole thing and
> be up-to-date.

Yes, but AFAIK this changes kernel behavior to (what is at least to me) a
now-unknown behavior.

>
> Also, what guarantees that this thing:
>
> rescan_from = min_t(int, l0->max_std_leaf, c->cpuid_level) + 1;
> cpuid_refresh_range(c, rescan_from, CPUID_BASE_END);
>
> doesn't overwrite some unrelated ranges?
>
> Also, in your example:
>
> * First case:
>
> leaf 0x0
> leaf 0x1
> leaf 0x2 <- Old max CPUID
> leaf 0x3
> leaf 0x4
> leaf 0x5
> leaf 0x6
> leaf 0x7
> leaf 0x9 <- *New* max CPUID
>
> when you rescan and overwrite [2-9], what guarantees that you don't overwrite
> an already set or cleared bit in those new leafs, say in leaf 5?
>
> Neither set_cpu_cap() nor clear_cpu_cap() pay attention to the max base leaf
> value?

Hmmm, that's a valid point.

So, clear_cpu_cap() logs the cleared bits to cpu_caps_cleared[].

Is there a reason why set_cpu_cap(), supposedly its parallel function,
totally ommits cpu_caps_set[]?

If we can track the clear_cpu_cap() bits above, then AFAIK a reliable
solution would be to just re-initialize the whole CPUID table whole sale
and then invoke apply_forced_caps().

Thanks,
Ahmed