git: b4bbe15fe4c7 - stable/15 - amd64: do not restore fsbase/gsbase for 32bit processes

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 25 Jun 2026 00:50:54 UTC
The branch stable/15 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=b4bbe15fe4c7f168af996e1bea62b947f2fc500a

commit b4bbe15fe4c7f168af996e1bea62b947f2fc500a
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-06-16 21:44:00 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-06-25 00:50:23 +0000

    amd64: do not restore fsbase/gsbase for 32bit processes
    
    (cherry picked from commit c7e5802ab6e6230a5782a09c914585d055eb5223)
---
 sys/amd64/amd64/exception.S | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index babfbacf92ef..afdcdeedf0f5 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -1161,12 +1161,15 @@ do_segs:
 	.globl	ld_fs
 ld_fs:
 	movw	%ax,%fs
+	testl	$PCB_32BIT,PCB_FLAGS(%r8)
+	jnz	after_ld_fsbase
 	movl	$MSR_FSBASE,%ecx
 	movl	PCB_FSBASE(%r8),%eax
 	movl	PCB_FSBASE+4(%r8),%edx
 	.globl	ld_fsbase
 ld_fsbase:
 	wrmsr
+after_ld_fsbase:
 	/* Restore %gs and gsbase */
 	movw	TF_GS(%rsp),%si
 	pushfq
@@ -1179,6 +1182,8 @@ ld_fsbase:
 	.globl	ld_gs
 ld_gs:
 	movw	%si,%gs
+	testl	$PCB_32BIT,PCB_FLAGS(%r8)
+	jnz	ld_gsbase_32
 	/* Restore kernel %gs base */
 	movl	%r12d,%eax
 	movl	%r13d,%edx
@@ -1194,6 +1199,8 @@ ld_gs:
 	.globl	ld_gsbase
 ld_gsbase:
 	wrmsr	/* May trap if non-canonical, but only for TLS. */
+
+after_ld_gsbase:
 	.globl	ld_es
 ld_es:
 	movw	TF_ES(%rsp),%es
@@ -1241,6 +1248,30 @@ ld_regs:
 doreti_iret:
 	iretq
 
+	/*
+	 * 32bit gsbase path.
+	 * The KGSBASE is not loaded from the pcb_gsbase, instead we move
+	 * the GSBASE value into KGSBASE right after loading user %gs, then
+	 * restore kernel gsbase.
+	 */
+ld_gsbase_32:
+	/* Read the user gsbase into %r14d:%r15d. */
+	movl	$MSR_GSBASE,%ecx
+	rdmsr
+	movl	%eax,%r14d
+	movl	%edx,%r15d
+	/* Restore kernel %gs base */
+	movl	%r12d,%eax
+	movl	%r13d,%edx
+	wrmsr
+	popfq
+	/* Load the user gsbase into KGSBASE. */
+	movl	$MSR_KGSBASE,%ecx
+	movl	%r14d,%eax
+	movl	%r15d,%edx
+	wrmsr
+	jmp	after_ld_gsbase
+
 set_segs:
 	movw	$KUDSEL,%ax
 	movw	%ax,TF_DS(%rsp)