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