git: ddab534cd6f6 - main - amd64: do not handle fs/gs bases conditionally on the selector
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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)