Re: Save a WRMSR GS.base?

From: Borislav Petkov

Date: Thu Jun 04 2026 - 22:29:24 EST


On Thu, Jun 04, 2026 at 10:17:57AM +0100, Andrew Cooper wrote:
> Yes, but it took me writing a "no" email to spot it.

Oh, I know those situations.

> If the LKGS (in load seg) was called unconditionally, then yes it would
> be safe to drop the __wrgsbase_inactive(), but it's not.
>
> Consider a prev and next which both have the same ->gsindex (so skips
> loadseg()), but have different ->gsbase (still need to update KERN_GS_BASE).

Gah, ofc.

So we'll have to do something like this which is ugly as hell:

---

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b85e715ebb30..248c39da9ba0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -391,16 +391,23 @@ static __always_inline void x86_pkru_load(struct thread_struct *prev,
static __always_inline void x86_fsgsbase_load(struct thread_struct *prev,
struct thread_struct *next)
{
+ bool loaded_gs = false;
+
if (static_cpu_has(X86_FEATURE_FSGSBASE)) {
/* Update the FS and GS selectors if they could have changed. */
if (unlikely(prev->fsindex || next->fsindex))
loadseg(FS, next->fsindex);
- if (unlikely(prev->gsindex || next->gsindex))
+
+ if (unlikely(prev->gsindex || next->gsindex)) {
loadseg(GS, next->gsindex);
+ loaded_gs = true;
+ }

/* Update the bases. */
wrfsbase(next->fsbase);
- __wrgsbase_inactive(next->gsbase);
+
+ if (!(cpu_feature_enabled(X86_FEATURE_LKGS) && loaded_gs))
+ __wrgsbase_inactive(next->gsbase);
} else {
load_seg_legacy(prev->fsindex, prev->fsbase,
next->fsindex, next->fsbase, FS);


Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette