Changeset 1a5eca4 in mainline for kernel/arch/amd64/src/asm.S


Ignore:
Timestamp:
2016-04-27T19:36:56Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af9dd1e
Parents:
d6f9fff
Message:

amd64: Make TLS settable from uspace

The TLS document[1] mandates that %fs[0] is the thread pointer on amd64.
That is good as it allows userspace-only TLS management for fibrils:
fibril_save/restore() simply manipulate the thread pointer in %fs:0 and
don't need to ask the kernel to modify %fs's base. The kernel treats
%fs:0 as another preserved register and preserves it across context
switches. GCC gets in the way a little bit because it by default assumes
that TLS is accessible from negative %fs offsets (which would
necessitate a kernel-assisted solution). Fortunately, there is a GCC
option to suppress this assumption.

  • Introduce the concept of virtual registers, with VREG_TP (thread pointer) being the first of them
  • Preserve VREG_TP in context_save/restore()
  • Stop using sys_tls_set() in favour of using %fs:0 as the thread pointer
  • Make GCC generate code that always goes through %gs:0 to access TLS
  • Introduce kseg: a per-CPU area accessible from GS_KERNEL that holds the kernel stack, kernel FS base and a scratch space for syscall and int handlers to use

[1] Drepper, U.: ELF Handling For Thread-Local Storage

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/asm.S

    rd6f9fff r1a5eca4  
    3131#include <arch/mm/page.h>
    3232#include <arch/istate_struct.h>
     33#include <arch/kseg_struct.h>
     34#include <arch/cpu.h>
    3335
    3436.text
     
    178180                subq $(ISTATE_SOFT_SIZE + 8), %rsp
    179181        .endif
    180        
     182
    181183        /*
    182184         * Save the general purpose registers.
     
    199201
    200202        /*
     203         * Is this trap from the kernel?
     204         */
     205        cmpq $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp)
     206        jz 0f
     207
     208        /*
     209         * Switch to kernel FS base.
     210         */
     211        swapgs
     212        movl $AMD_MSR_FS, %ecx
     213        movl %gs:KSEG_OFFSET_FSBASE, %eax
     214        movl %gs:KSEG_OFFSET_FSBASE+4, %edx
     215        wrmsr
     216        swapgs
     217
     218        /*
    201219         * Imitate a regular stack frame linkage.
    202220         * Stop stack traces here if we came from userspace.
    203221         */
    204         xorl %edx, %edx
    205         cmpq $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp)
     2220:      movl $0x0, %edx
    206223        cmovnzq %rdx, %rbp
    207224
     
    272289        swapgs
    273290       
    274         /*
    275          * %gs:0 Scratch space for this thread's user RSP
    276          * %gs:8 Address to be used as this thread's kernel RSP
    277          */
    278        
    279         movq %rsp, %gs:0  /* save this thread's user RSP */
    280         movq %gs:8, %rsp  /* set this thread's kernel RSP */
    281        
     291        movq %rsp, %gs:KSEG_OFFSET_USTACK_RSP  /* save this thread's user RSP */
     292        movq %gs:KSEG_OFFSET_KSTACK_RSP, %rsp  /* set this thread's kernel RSP */
     293
    282294        /*
    283295         * Note that the space needed for the imitated istate structure has been
     
    308320
    309321        /*
     322         * Switch to kernel FS base.
     323         */
     324        movl $AMD_MSR_FS, %ecx
     325        movl %gs:KSEG_OFFSET_FSBASE, %eax
     326        movl %gs:KSEG_OFFSET_FSBASE+4, %edx
     327        wrmsr
     328        movq ISTATE_OFFSET_RDX(%rsp), %rdx      /* restore 3rd argument */
     329
     330        /*
    310331         * Save the return address and the userspace stack on locations that
    311332         * would normally be taken by them.
    312333         */
    313         movq %gs:0, %rax
     334        movq %gs:KSEG_OFFSET_USTACK_RSP, %rax
    314335        movq %rax, ISTATE_OFFSET_RSP(%rsp)
    315336        movq %rcx, ISTATE_OFFSET_RIP(%rsp)
     
    325346        swapgs
    326347        sti
    327        
     348
    328349        /* Copy the 4th argument where it is expected  */
    329350        movq %r10, %rcx
Note: See TracChangeset for help on using the changeset viewer.