[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 3/4] plat: switch thread-local storage area on context switch
Hi Costin, On 4/16/19 3:22 PM, Costin Lupu wrote: Hi Florian, Please see my comments inline. On 4/15/19 1:03 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/thread.h | 5 +++ include/uk/plat/thread.h | 8 ++-- lib/uksched/thread.c | 5 ++- plat/common/include/sw_ctx.h | 1 + plat/common/include/thread_switch.h | 43 +++++++++++++++++++ plat/common/include/x86/thread_switch.h | 41 ++++++++++++++++++ plat/common/sw_ctx.c | 10 ++++- plat/linuxu/include/linuxu/syscall-x86_64.h | 1 + plat/linuxu/include/linuxu/syscall.h | 7 ++++ plat/linuxu/include/thread_switch.h | 46 +++++++++++++++++++++ 10 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 plat/common/include/thread_switch.h create mode 100644 plat/common/include/x86/thread_switch.h create mode 100644 plat/linuxu/include/thread_switch.h diff --git a/arch/x86/x86_64/include/uk/asm/thread.h b/arch/x86/x86_64/include/uk/asm/thread.h index 6e95848d..f07eb521 100644 --- a/arch/x86/x86_64/include/uk/asm/thread.h +++ b/arch/x86/x86_64/include/uk/asm/thread.h @@ -62,3 +62,8 @@ static inline void tls_copy(void *tls_area) memset(tls_area+tls_data_len, 0, tls_bss_len); *((uintptr_t *)(tls_area+tls_len)) = (uintptr_t)(tls_area+tls_len); } + +static inline void *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 inlinevoid *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 a97fad9e..45f79206 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/thread.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)tls_pointer(tls)); if (thread->ctx == NULL) return -1;diff --git a/plat/common/include/sw_ctx.h b/plat/common/include/sw_ctx.hindex 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/thread_switch.h b/plat/common/include/thread_switch.h new file mode 100644 index 00000000..b04c38c5 --- /dev/null +++ b/plat/common/include/thread_switch.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Florian Schmidt <florian.schmidt@xxxxxxxxx> + * + * 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_THREAD_SWITCH_H__ +#define __PLAT_CMN_THREAD_SWITCH_H__ + +#if defined(__X86_64__) +#include <x86/thread_switch.h> +#else +#error "Add thread_switch.h for current architecture." +#endif + +#endif /* __PLAT_CMN_THREAD_SWITCH_H__ */ diff --git a/plat/common/include/x86/thread_switch.h b/plat/common/include/x86/thread_switch.h new file mode 100644 index 00000000..f8252916 --- /dev/null +++ b/plat/common/include/x86/thread_switch.hFor this file the location is correct, according to my comments for the previous patch. However, I would use the same header for both sets of changes and rename it to tls.h . I'll make it consistent with the file in the previous patch. @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Florian Schmidt <florian.schmidt@xxxxxxxxx> + * + * 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_THREAD_SWITCH_H__ +#define __PLAT_CMN_X86_THREAD_SWITCH_H__ + +#define MSR_FS_BASE 0xc0000100This is a CPU related macro, please move it to plat/common/include/x86/cpu_defs.h where all the CPU related macros are defined. OK, I'll do that (and maybe change the name according to the scheme in that file). + +#define set_tls_pointer(ptr) wrmsrl(MSR_FS_BASE, ptr) + +#endif /* __PLAT_CMN_X86_THREAD_SWITCH_H__ */ diff --git a/plat/common/sw_ctx.c b/plat/common/sw_ctx.c index 06795244..088d1233 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 <thread_switch.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.hindex 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..d5b66698 100644 --- a/plat/linuxu/include/linuxu/syscall.h +++ b/plat/linuxu/include/linuxu/syscall.h @@ -123,6 +123,13 @@ static inline int sys_sigprocmask(int how, sizeof(k_sigset_t)); }+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/thread_switch.h b/plat/linuxu/include/thread_switch.h new file mode 100644 index 00000000..3a0f962f --- /dev/null +++ b/plat/linuxu/include/thread_switch.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Florian Schmidt <florian.schmidt@xxxxxxxxx> + * + * 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_THREAD_SWITCH_H__ +#define __PLAT_THREAD_SWITCH_H__ + +#include <linuxu/syscall.h> + +#define ARCH_SET_FS 0x1002 + +static inline void set_tls_pointer(unsigned long arg) +{ + sys_arch_prctl(ARCH_SET_FS, arg); +} + +#endif /* __PLAT_THREAD_SWITCH_H__ */ -- Dr. Florian Schmidt フローリアン・シュミット Research Scientist, Systems and Machine Learning Group NEC Laboratories Europe Kurfürsten-Anlage 36, D-69115 Heidelberg Tel. +49 (0)6221 4342-265 Fax: +49 (0)6221 4342-155 e-mail: florian.schmidt@xxxxxxxxx ============================================================ Registered at Amtsgericht Mannheim, Germany, HRB728558 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |