Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: set %fs to __KERNEL_PERCPU unconditionally for x86_32

Impact: cleanup

%fs is currently set to __KERNEL_DS at boot, and conditionally
switched to __KERNEL_PERCPU for secondary cpus. Instead, initialize
GDT_ENTRY_PERCPU to the same attributes as GDT_ENTRY_KERNEL_DS and
set %fs to __KERNEL_PERCPU unconditionally.

Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>

authored by

Brian Gerst and committed by
Tejun Heo
0dd76d73 299e2699

+4 -4
+1 -1
arch/x86/kernel/cpu/common.c
··· 111 111 [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, 112 112 113 113 [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } }, 114 - [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } }, 114 + [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, 115 115 #endif 116 116 } }; 117 117 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
+3 -3
arch/x86/kernel/head_32.S
··· 429 429 ljmp $(__KERNEL_CS),$1f 430 430 1: movl $(__KERNEL_DS),%eax # reload all the segment registers 431 431 movl %eax,%ss # after changing gdt. 432 - movl %eax,%fs # gets reset once there's real percpu 433 432 434 433 movl $(__USER_DS),%eax # DS/ES contains default USER segment 435 434 movl %eax,%ds 436 435 movl %eax,%es 436 + 437 + movl $(__KERNEL_PERCPU), %eax 438 + movl %eax,%fs # set this cpu's percpu 437 439 438 440 xorl %eax,%eax # Clear GS and LDT 439 441 movl %eax,%gs ··· 448 446 movb $1, ready 449 447 cmpb $0,%cl # the first CPU calls start_kernel 450 448 je 1f 451 - movl $(__KERNEL_PERCPU), %eax 452 - movl %eax,%fs # set this cpu's percpu 453 449 movl (stack_start), %esp 454 450 1: 455 451 #endif /* CONFIG_SMP */