Changeset d6f9fff in mainline for kernel/arch/ia32/src/asm.S


Ignore:
Timestamp:
2016-04-27T12:39:14Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1a5eca4
Parents:
8a36bc1e
Message:

ia32: Make TLS settable from uspace

The TLS document[1] mandates that %gs[0] is the thread pointer on ia32.
That is good as it allows userspace-only TLS management for fibrils:
fibril_save/restore() simply manipulate the thread pointer in %gs:0 and
don't need to ask the kernel to modify %gs's base. The kernel treats
%gs: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 %gs 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 %gs:0 as the thread pointer
  • Make GCC generate code that always goes through %gs:0 to access TLS

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

File:
1 edited

Legend:

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

    r8a36bc1e rd6f9fff  
    183183
    184184        /*
    185          * Save TLS.
    186          */
    187         movl %gs, %edx
    188         movl %edx, ISTATE_OFFSET_GS(%esp)
    189 
    190         /*
    191185         * Switch to kernel selectors.
    192186         */
    193         movw $(GDT_SELECTOR(KDATA_DES)), %ax
    194         movw %ax, %ds
    195         movw %ax, %es
     187        movl $(GDT_SELECTOR(KDATA_DES)), %eax
     188        movl %eax, %ds
     189        movl %eax, %es
     190        movl $(GDT_SELECTOR(VREG_DES)), %eax
     191        movl %eax, %gs
    196192       
    197193        /*
     
    213209       
    214210        /*
    215          * Restore TLS.
    216          */
    217         movl ISTATE_OFFSET_GS(%esp), %edx
    218         movl %edx, %gs
    219        
    220         /*
    221211         * Prepare return address and userspace stack for SYSEXIT.
    222212         */
     
    252242
    253243        /*
    254          * Save the selector registers.
     244         * Save the segment registers.
    255245         */
    256246        movl %gs, %ecx
     
    272262        movl %eax, %ds
    273263        movl %eax, %es
     264        movl $(GDT_SELECTOR(VREG_DES)), %eax
     265        movl %eax, %gs
    274266               
    275267        movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)
     
    284276                       
    285277        /*
    286          * Restore the selector registers.
     278         * Restore the segment registers.
    287279         */
    288280        movl ISTATE_OFFSET_GS(%esp), %ecx
     
    354346       
    355347        /*
    356          * Save the selector registers.
     348         * Save the segment registers.
    357349         */
    358350        movl %gs, %ecx
     
    374366        movl %eax, %ds
    375367        movl %eax, %es
     368        movl $(GDT_SELECTOR(VREG_DES)), %eax
     369        movl %eax, %gs
    376370       
    377371        /*
Note: See TracChangeset for help on using the changeset viewer.