|
[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 |