git: ddab534cd6f6 - main - amd64: do not handle fs/gs bases conditionally on the selector

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 28 May 2025 11:11:39 UTC
The branch main has been updated by kib:

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

commit ddab534cd6f6557740c24ff2019642880ad8bef6
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-05-19 01:30:14 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-05-28 11:11:23 +0000

    amd64: do not handle fs/gs bases conditionally on the selector
    
    For machines with RDFSBASE support, we only saved and restored fs and gs
    base registers when corresponding segment register contained the
    predefined value.  This breaks some valid uses of the LDT together with
    WR{F,G}SBASE.
    
    Unconditionally save bases, and restore them on return to usermode.  The
    PCB_FULL_IRET optimization is still in place.
    
    Reviewed by:    markj, olce
    Reported and tested:    Alex S <iwtcex@gmail.com>
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D50414
---
 sys/amd64/amd64/cpu_switch.S    |  6 ------
 sys/amd64/amd64/exception.S     | 29 -----------------------------
 sys/amd64/amd64/machdep.c       |  6 ++----
 sys/amd64/ia32/ia32_exception.S |  3 +--
 4 files changed, 3 insertions(+), 41 deletions(-)

diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index 32d1b91d50b4..a053f6c70af1 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -91,14 +91,8 @@ ENTRY(cpu_switch)
 	jnz	2f
 	testb	$CPUID_STDEXT_FSGSBASE,cpu_stdext_feature(%rip)
 	jz	2f
-	movl	%fs,%eax
-	cmpl	$KUF32SEL,%eax
-	jne	1f
 	rdfsbase %rax
 	movq	%rax,PCB_FSBASE(%r8)
-1:	movl	%gs,%eax
-	cmpl	$KUG32SEL,%eax
-	jne	2f
 	movq	%rdx,%r12
 	movl	$MSR_KGSBASE,%ecx		/* Read user gs base */
 	rdmsr
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index c3d5819378d1..babfbacf92ef 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -479,22 +479,14 @@ prot_addrf:
 	jz	6f			/* already running with kernel GS.base */
 	testb	$CPUID_STDEXT_FSGSBASE,cpu_stdext_feature(%rip)
 	jz	2f
-	cmpw	$KUF32SEL,TF_FS(%rsp)
-	jne	1f
 	rdfsbase %rax
-1:	cmpw	$KUG32SEL,TF_GS(%rsp)
-	jne	2f
 	rdgsbase %rdx
 2:	swapgs
 	lfence
 	movq	PCPU(CURPCB),%rdi
 	testb	$CPUID_STDEXT_FSGSBASE,cpu_stdext_feature(%rip)
 	jz	4f
-	cmpw	$KUF32SEL,TF_FS(%rsp)
-	jne	3f
 	movq	%rax,PCB_FSBASE(%rdi)
-3:	cmpw	$KUG32SEL,TF_GS(%rsp)
-	jne	4f
 	movq	%rdx,PCB_GSBASE(%rdi)
 	orl	$PCB_FULL_IRET,PCB_FLAGS(%rdi)	/* full iret from user #gp */
 4:	call	handle_ibrs_entry
@@ -730,12 +722,8 @@ dbg_fromuserspace:
 	orl	$PCB_FULL_IRET,PCB_FLAGS(%rdi)
 	testb	$CPUID_STDEXT_FSGSBASE,cpu_stdext_feature(%rip)
 	jz	3f
-	cmpw	$KUF32SEL,TF_FS(%rsp)
-	jne	2f
 	rdfsbase %rax
 	movq	%rax,PCB_FSBASE(%rdi)
-2:	cmpw	$KUG32SEL,TF_GS(%rsp)
-	jne	3f
 	movl	$MSR_KGSBASE,%ecx
 	rdmsr
 	shlq	$32,%rdx
@@ -842,12 +830,8 @@ nmi_fromuserspace:
 	orl	$PCB_FULL_IRET,PCB_FLAGS(%rdi)
 	testb	$CPUID_STDEXT_FSGSBASE,cpu_stdext_feature(%rip)
 	jz	3f
-	cmpw	$KUF32SEL,TF_FS(%rsp)
-	jne	2f
 	rdfsbase %rax
 	movq	%rax,PCB_FSBASE(%rdi)
-2:	cmpw	$KUG32SEL,TF_GS(%rsp)
-	jne	3f
 	movl	$MSR_KGSBASE,%ecx
 	rdmsr
 	shlq	$32,%rdx
@@ -1177,15 +1161,12 @@ do_segs:
 	.globl	ld_fs
 ld_fs:
 	movw	%ax,%fs
-	cmpw	$KUF32SEL,%ax
-	jne	1f
 	movl	$MSR_FSBASE,%ecx
 	movl	PCB_FSBASE(%r8),%eax
 	movl	PCB_FSBASE+4(%r8),%edx
 	.globl	ld_fsbase
 ld_fsbase:
 	wrmsr
-1:
 	/* Restore %gs and gsbase */
 	movw	TF_GS(%rsp),%si
 	pushfq
@@ -1198,10 +1179,6 @@ ld_fsbase:
 	.globl	ld_gs
 ld_gs:
 	movw	%si,%gs
-	/* Save user %gs base into %r14d:%r15d */
-	rdmsr
-	movl	%eax,%r14d
-	movl	%edx,%r15d
 	/* Restore kernel %gs base */
 	movl	%r12d,%eax
 	movl	%r13d,%edx
@@ -1212,14 +1189,8 @@ ld_gs:
 	 * from the previously saved msr read.
 	 */
 	movl	$MSR_KGSBASE,%ecx
-	cmpw	$KUG32SEL,%si
-	jne	1f
 	movl	PCB_GSBASE(%r8),%eax
 	movl	PCB_GSBASE+4(%r8),%edx
-	jmp	ld_gsbase
-1:
-	movl	%r14d,%eax
-	movl	%r15d,%edx
 	.globl	ld_gsbase
 ld_gsbase:
 	wrmsr	/* May trap if non-canonical, but only for TLS. */
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 6d9bc8b7c573..032a134bbd4b 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1789,10 +1789,8 @@ set_pcb_flags_fsgsbase(struct pcb *pcb, const u_int flags)
 	    (pcb->pcb_flags & PCB_FULL_IRET) == 0) {
 		r = intr_disable();
 		if ((pcb->pcb_flags & PCB_FULL_IRET) == 0) {
-			if (rfs() == _ufssel)
-				pcb->pcb_fsbase = rdfsbase();
-			if (rgs() == _ugssel)
-				pcb->pcb_gsbase = rdmsr(MSR_KGSBASE);
+			pcb->pcb_fsbase = rdfsbase();
+			pcb->pcb_gsbase = rdmsr(MSR_KGSBASE);
 		}
 		set_pcb_flags_raw(pcb, flags);
 		intr_restore(r);
diff --git a/sys/amd64/ia32/ia32_exception.S b/sys/amd64/ia32/ia32_exception.S
index 42d0ff6c638b..ef1a2c59a0af 100644
--- a/sys/amd64/ia32/ia32_exception.S
+++ b/sys/amd64/ia32/ia32_exception.S
@@ -54,10 +54,10 @@ int0x80_syscall_common:
 	movq	%rax,TF_RAX(%rsp)
 	movq	%rdx,TF_RDX(%rsp)
 	movq	%rcx,TF_RCX(%rsp)
+	movq	%r15,TF_R15(%rsp)
 	call	handle_ibrs_entry
 	sti
 	movq	%rsi,TF_RSI(%rsp)
-	movq	%r8,TF_R8(%rsp)
 	movq	%r9,TF_R9(%rsp)
 	movq	%rbx,TF_RBX(%rsp)
 	movq	%rbp,TF_RBP(%rsp)
@@ -66,7 +66,6 @@ int0x80_syscall_common:
 	movq	%r12,TF_R12(%rsp)
 	movq	%r13,TF_R13(%rsp)
 	movq	%r14,TF_R14(%rsp)
-	movq	%r15,TF_R15(%rsp)
 	movl	$TF_HASSEGS,TF_FLAGS(%rsp)
 	pushfq
 	andq	$~(PSL_D | PSL_AC),(%rsp)