* [PATCH -tip 0/1] x86_32/segment: Always return correctly zero-extended values from savesegment_*()
@ 2026-04-14 7:44 Uros Bizjak
2026-04-14 7:44 ` [PATCH -tip 1/1] " Uros Bizjak
0 siblings, 1 reply; 2+ messages in thread
From: Uros Bizjak @ 2026-04-14 7:44 UTC (permalink / raw)
To: x86, linux-kernel
Cc: Uros Bizjak, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin
On 32-bit x86, reading segment registers into a 32-bit type can expose
undefined upper bits on older processors (e.g. Intel Quark X1000,
Pentium, and earlier), where bits 31:16 are not defined.
As a result, undefined upper bits may be stored in variables
(e.g. saved_fs and saved_gs in apm_32.c), structures (e.g. thread_struct.gs)
and arrays (e.g. elf_gregset_t[]). Some of these are later used, for
example in process_32.c::__switch_to():
if (prev->gs | next->gs)
loadsegment(gs, next->gs);
which results in unneccessary reloads.
Introduce __seg_return_t as an intermediate type for __savesegment_*():
u16 on CONFIG_X86_32 and unsigned long otherwise.
This ensures that __savesegment_*() returns correctly zero-extended
values in all cases, avoiding propagation of undefined high bits on
32-bit systems while preserving existing behavior on 64-bit.
A follow-up patch can remove the majority of zero-extensions by addressing
a long-standing XXX comment in thread_struct and reusing gsindex instead of
gs for 32-bit x86 targets as well.
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Uros Bizjak (1):
x86_32/segment: Always return correctly zero-extended values from
savesegment_*()
arch/x86/include/asm/segment.h | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--
2.53.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH -tip 1/1] x86_32/segment: Always return correctly zero-extended values from savesegment_*()
2026-04-14 7:44 [PATCH -tip 0/1] x86_32/segment: Always return correctly zero-extended values from savesegment_*() Uros Bizjak
@ 2026-04-14 7:44 ` Uros Bizjak
0 siblings, 0 replies; 2+ messages in thread
From: Uros Bizjak @ 2026-04-14 7:44 UTC (permalink / raw)
To: x86, linux-kernel
Cc: Uros Bizjak, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin
On 32-bit x86, reading segment registers into a 32-bit type can expose
undefined upper bits on older processors (e.g. Intel Quark X1000,
Pentium, and earlier), where bits 31:16 are not defined.
Introduce __seg_return_t as an intermediate type for __savesegment_*():
u16 on CONFIG_X86_32 and unsigned long otherwise.
As a result, __savesegment_*() now returns correctly zero-extended
value in all cases, avoiding propagation of undefined high bits on
32-bit systems while preserving existing behavior on 64-bit.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
---
arch/x86/include/asm/segment.h | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
index dbd90fede5e7..070ed87063e0 100644
--- a/arch/x86/include/asm/segment.h
+++ b/arch/x86/include/asm/segment.h
@@ -341,13 +341,23 @@ static inline void __loadsegment_fs(u16 value)
#define loadsegment(seg, val) __loadsegment_##seg(val)
+#ifdef CONFIG_X86_32
+/*
+ * Bits 31:16 are undefined for Intel Quark X1000 processors,
+ * Pentium, and earlier processors.
+ */
+typedef u16 __seg_return_t;
+#else
+typedef unsigned long __seg_return_t;
+#endif
+
/*
* Save a segment register away:
*/
#define SAVE_SEGMENT(seg) \
static inline unsigned long __savesegment_##seg(void) \
{ \
- unsigned long v; \
+ __seg_return_t v; \
asm volatile("movl %%" #seg ",%k0" : "=r" (v)); \
return v; \
}
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-04-14 7:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-14 7:44 [PATCH -tip 0/1] x86_32/segment: Always return correctly zero-extended values from savesegment_*() Uros Bizjak
2026-04-14 7:44 ` [PATCH -tip 1/1] " Uros Bizjak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox