[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v2 6/6] plat: switch thread-local storage area on context switch
This patch is fine. Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx> On 5/24/19 3:11 PM, Florian Schmidt wrote: > On x86, the standard way is writing to an MSR to switch the fs register, > which is used as the pointer to the TLS area. However, this is a > privileged instruction, so for the linuxu platform, use a system call > provided by Linux that does exactly that instead. > > Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx> > --- > arch/x86/x86_64/include/uk/asm/tls.h | 5 +++ > include/uk/plat/thread.h | 8 ++-- > lib/uksched/thread.c | 5 ++- > plat/common/include/sw_ctx.h | 1 + > plat/common/include/tls.h | 41 ++++++++++++++++++++ > plat/common/include/x86/cpu_defs.h | 5 +++ > plat/common/include/x86/tls.h | 39 +++++++++++++++++++ > plat/common/sw_ctx.c | 10 ++++- > plat/linuxu/include/linuxu/syscall-x86_64.h | 1 + > plat/linuxu/include/linuxu/syscall.h | 8 ++++ > plat/linuxu/include/tls.h | 42 +++++++++++++++++++++ > 11 files changed, 158 insertions(+), 7 deletions(-) > create mode 100644 plat/common/include/tls.h > create mode 100644 plat/common/include/x86/tls.h > create mode 100644 plat/linuxu/include/tls.h > > diff --git a/arch/x86/x86_64/include/uk/asm/tls.h > b/arch/x86/x86_64/include/uk/asm/tls.h > index 70bbc1d1..116d8a1d 100644 > --- a/arch/x86/x86_64/include/uk/asm/tls.h > +++ b/arch/x86/x86_64/include/uk/asm/tls.h > @@ -66,3 +66,8 @@ static inline void ukarch_tls_area_copy(void *tls_area) > /* x86_64 ABI requires that fs:%0 contains the address of itself. */ > *((__uptr *)(tls_area + tls_len)) = (__uptr)(tls_area + tls_len); > } > + > +static inline void *ukarch_tls_pointer(void *tls_area) > +{ > + return tls_area + (_tls_end - _tls_start); > +} > diff --git a/include/uk/plat/thread.h b/include/uk/plat/thread.h > index 69fc5e28..4b349ea7 100644 > --- a/include/uk/plat/thread.h > +++ b/include/uk/plat/thread.h > @@ -51,7 +51,8 @@ enum ukplat_ctx_type { > struct uk_alloc; > > typedef void *(*ukplat_ctx_create_func_t) > - (struct uk_alloc *allocator, unsigned long sp); > + (struct uk_alloc *allocator, unsigned long sp, > + unsigned long tlsp); > typedef void (*ukplat_ctx_start_func_t) > (void *ctx); > typedef void (*ukplat_ctx_switch_func_t) > @@ -72,12 +73,13 @@ int ukplat_ctx_callbacks_init(struct ukplat_ctx_callbacks > *ctx_cbs, > > static inline > void *ukplat_thread_ctx_create(struct ukplat_ctx_callbacks *cbs, > - struct uk_alloc *allocator, unsigned long sp) > + struct uk_alloc *allocator, unsigned long sp, > + unsigned long tlsp) > { > UK_ASSERT(cbs != NULL); > UK_ASSERT(allocator != NULL); > > - return cbs->create_cb(allocator, sp); > + return cbs->create_cb(allocator, sp, tlsp); > } > > void ukplat_thread_ctx_destroy(struct uk_alloc *allocator, void *ctx); > diff --git a/lib/uksched/thread.c b/lib/uksched/thread.c > index 7d7ee016..64b6a2fd 100644 > --- a/lib/uksched/thread.c > +++ b/lib/uksched/thread.c > @@ -39,7 +39,7 @@ > #include <uk/wait.h> > #include <uk/print.h> > #include <uk/assert.h> > - > +#include <uk/arch/tls.h> > > /* Pushes the specified value onto the stack of the specified thread */ > static void stack_push(unsigned long *sp, unsigned long value) > @@ -103,7 +103,8 @@ int uk_thread_init(struct uk_thread *thread, > init_sp(&sp, stack, function, arg); > > /* Call platform specific setup. */ > - thread->ctx = ukplat_thread_ctx_create(cbs, allocator, sp); > + thread->ctx = ukplat_thread_ctx_create(cbs, allocator, sp, > + (uintptr_t)ukarch_tls_pointer(tls)); > if (thread->ctx == NULL) > return -1; > > diff --git a/plat/common/include/sw_ctx.h b/plat/common/include/sw_ctx.h > index d52fe65b..366c6a8f 100644 > --- a/plat/common/include/sw_ctx.h > +++ b/plat/common/include/sw_ctx.h > @@ -41,6 +41,7 @@ > struct sw_ctx { > unsigned long sp; /* Stack pointer */ > unsigned long ip; /* Instruction pointer */ > + unsigned long tlsp; /* thread-local storage pointer */ > uintptr_t extregs; /* Pointer to an area to which extended > * registers are saved on context switch. > */ > diff --git a/plat/common/include/tls.h b/plat/common/include/tls.h > new file mode 100644 > index 00000000..b9176f95 > --- /dev/null > +++ b/plat/common/include/tls.h > @@ -0,0 +1,41 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Copyright (c) 2019, NEC Europe Ltd., NEC Corporation. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + * > + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. > + */ > +#ifndef __PLAT_CMN_TLS_H__ > +#define __PLAT_CMN_TLS_H__ > + > +#if defined(__X86_64__) > +#include <x86/tls.h> > +#else > +#error "For thread-local storage support, add tls.h for current > architecture." > +#endif > + > +#endif /* __PLAT_CMN_TLS_H__ */ > diff --git a/plat/common/include/x86/cpu_defs.h > b/plat/common/include/x86/cpu_defs.h > index e968a832..48baf558 100644 > --- a/plat/common/include/x86/cpu_defs.h > +++ b/plat/common/include/x86/cpu_defs.h > @@ -95,4 +95,9 @@ > #define X86_XCR0_SSE (1 << 1) > #define X86_XCR0_AVX (1 << 2) > > +/* > + * Model-specific register addresses > + */ > +#define X86_MSR_FS_BASE 0xc0000100 > + > #endif /* __PLAT_CMN_X86_CPU_DEFS_H__ */ > diff --git a/plat/common/include/x86/tls.h b/plat/common/include/x86/tls.h > new file mode 100644 > index 00000000..5811bcd7 > --- /dev/null > +++ b/plat/common/include/x86/tls.h > @@ -0,0 +1,39 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Copyright (c) 2019, NEC Europe Ltd., NEC Corporation. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + * > + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. > + */ > +#ifndef __PLAT_CMN_X86_TLS_H__ > +#define __PLAT_CMN_X86_TLS_H__ > + > +#include <x86/cpu_defs.h> > + > +#define set_tls_pointer(ptr) wrmsrl(X86_MSR_FS_BASE, ptr) > + > +#endif /* __PLAT_CMN_X86_TLS_H__ */ > diff --git a/plat/common/sw_ctx.c b/plat/common/sw_ctx.c > index 06795244..88a377f1 100644 > --- a/plat/common/sw_ctx.c > +++ b/plat/common/sw_ctx.c > @@ -39,9 +39,11 @@ > #include <uk/alloc.h> > #include <sw_ctx.h> > #include <uk/assert.h> > +#include <tls.h> > #include <x86/cpu.h> > > -static void *sw_ctx_create(struct uk_alloc *allocator, unsigned long sp); > +static void *sw_ctx_create(struct uk_alloc *allocator, unsigned long sp, > + unsigned long tlsp); > static void sw_ctx_start(void *ctx) __noreturn; > static void sw_ctx_switch(void *prevctx, void *nextctx); > > @@ -51,7 +53,8 @@ static void sw_ctx_switch(void *prevctx, void *nextctx); > */ > extern void asm_thread_starter(void); > > -static void *sw_ctx_create(struct uk_alloc *allocator, unsigned long sp) > +static void *sw_ctx_create(struct uk_alloc *allocator, unsigned long sp, > + unsigned long tlsp) > { > struct sw_ctx *ctx; > size_t sz; > @@ -68,6 +71,7 @@ static void *sw_ctx_create(struct uk_alloc *allocator, > unsigned long sp) > } > > ctx->sp = sp; > + ctx->tlsp = tlsp; > ctx->ip = (unsigned long) asm_thread_starter; > ctx->extregs = ALIGN_UP(((uintptr_t)ctx + sizeof(struct sw_ctx)), > x86_cpu_features.extregs_align); > @@ -86,6 +90,7 @@ static void sw_ctx_start(void *ctx) > > UK_ASSERT(sw_ctx != NULL); > > + set_tls_pointer(sw_ctx->tlsp); > /* Switch stacks and run the thread */ > asm_ctx_start(sw_ctx->sp, sw_ctx->ip); > > @@ -101,6 +106,7 @@ static void sw_ctx_switch(void *prevctx, void *nextctx) > > save_extregs(p); > restore_extregs(n); > + set_tls_pointer(n->tlsp); > asm_sw_ctx_switch(prevctx, nextctx); > } > > diff --git a/plat/linuxu/include/linuxu/syscall-x86_64.h > b/plat/linuxu/include/linuxu/syscall-x86_64.h > index 26820dcd..553f0ba4 100644 > --- a/plat/linuxu/include/linuxu/syscall-x86_64.h > +++ b/plat/linuxu/include/linuxu/syscall-x86_64.h > @@ -48,6 +48,7 @@ > #define __SC_RT_SIGPROCMASK 14 > #define __SC_IOCTL 16 > #define __SC_EXIT 60 > +#define __SC_ARCH_PRCTL 158 > #define __SC_TIMER_CREATE 222 > #define __SC_TIMER_SETTIME 223 > #define __SC_TIMER_GETTIME 224 > diff --git a/plat/linuxu/include/linuxu/syscall.h > b/plat/linuxu/include/linuxu/syscall.h > index d378d265..0dca7c5c 100644 > --- a/plat/linuxu/include/linuxu/syscall.h > +++ b/plat/linuxu/include/linuxu/syscall.h > @@ -123,6 +123,14 @@ static inline int sys_sigprocmask(int how, > sizeof(k_sigset_t)); > } > > +#define ARCH_SET_FS 0x1002 > +static inline int sys_arch_prctl(int code, unsigned long addr) > +{ > + return (int) syscall2(__SC_ARCH_PRCTL, > + (long) code, > + (long) addr); > +} > + > static inline int sys_pselect6(int nfds, > k_fd_set *readfds, k_fd_set *writefds, k_fd_set *exceptfds, > const struct k_timespec *timeout, const void *sigmask) > diff --git a/plat/linuxu/include/tls.h b/plat/linuxu/include/tls.h > new file mode 100644 > index 00000000..97474104 > --- /dev/null > +++ b/plat/linuxu/include/tls.h > @@ -0,0 +1,42 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Copyright (c) 2019, NEC Europe Ltd., NEC Corporation. All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + * > + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. > + */ > +#ifndef __PLAT_LINUXU_TLS_H__ > +#define __PLAT_LINUXU_TLS_H__ > + > +#include <linuxu/syscall.h> > + > +static inline void set_tls_pointer(unsigned long arg) > +{ > + sys_arch_prctl(ARCH_SET_FS, arg); > +} > + > +#endif /* __PLAT_LINUXU_TLS_H__ */ > _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |