Commit 7c42c9b5 authored by Alexander Kartashov's avatar Alexander Kartashov Committed by Pavel Emelyanov

cr: generalize the type to store the value of the TLS register

Supported machine architectures provide TLS stogares of different sizes:
the size of the TLS storage in x86-64 is 24 bytes, ARM --- 4 bytes
and upcoming AArch64 --- 8 bytes. This means every supported architecture
needs a specific type to store the value of the TLS register.

This patch reworks the insterface of the routines arch_get_tls()
and restore_tls() passing them the TLS storage by pointer
rather than by value to simplify the TLS stub for x86.
Signed-off-by: 's avatarAlexander Kartashov <alekskartashov@parallels.com>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Reviewed-by: 's avatarChristopher Covington <cov@codeaurora.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent c4979e9c
...@@ -6,7 +6,7 @@ extern int arch_alloc_thread_info(CoreEntry *core); ...@@ -6,7 +6,7 @@ extern int arch_alloc_thread_info(CoreEntry *core);
extern void arch_free_thread_info(CoreEntry *core); extern void arch_free_thread_info(CoreEntry *core);
static inline void core_put_tls(CoreEntry *core, u32 tls) static inline void core_put_tls(CoreEntry *core, tls_t tls)
{ {
core->ti_arm->tls = tls; core->ti_arm->tls = tls;
} }
......
#ifndef __ASM_PARASITE_H__ #ifndef __ASM_PARASITE_H__
#define __ASM_PARASITE_H__ #define __ASM_PARASITE_H__
static inline u32 arch_get_tls(void) static inline void arch_get_tls(tls_t *ptls)
{ {
return ((u32 (*)())0xffff0fe0)(); *ptls = ((tls_t (*)())0xffff0fe0)();
} }
#endif #endif
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"r"(task_args) \ "r"(task_args) \
: "sp", "r0", "r1", "memory") : "sp", "r0", "r1", "memory")
static inline void core_get_tls(CoreEntry *pcore, u32 *ptls) static inline void core_get_tls(CoreEntry *pcore, tls_t *ptls)
{ {
*ptls = pcore->ti_arm->tls; *ptls = pcore->ti_arm->tls;
} }
......
...@@ -136,16 +136,16 @@ int restore_nonsigframe_gpregs(UserArmRegsEntry *r); ...@@ -136,16 +136,16 @@ int restore_nonsigframe_gpregs(UserArmRegsEntry *r);
static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state) { return 0; } static inline int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state) { return 0; }
static inline void restore_tls(u32 tls) { static inline void restore_tls(tls_t *ptls) {
asm ( asm (
"mov %%r7, #15 \n" "mov %%r7, #15 \n"
"lsl %%r7, #16 \n" "lsl %%r7, #16 \n"
"mov %%r0, #5 \n" "mov %%r0, #5 \n"
"add %%r7, %%r0 \n" /* r7 = 0xF005 */ "add %%r7, %%r0 \n" /* r7 = 0xF005 */
"mov %%r0, %0 \n" "ldr %%r0, [%0] \n"
"svc #0 \n" "svc #0 \n"
: :
: "r"(tls) : "r"(ptls)
: "r0", "r7" : "r0", "r7"
); );
} }
......
...@@ -110,6 +110,7 @@ typedef UserArmRegsEntry UserRegsEntry; ...@@ -110,6 +110,7 @@ typedef UserArmRegsEntry UserRegsEntry;
#define TI_SP(core) ((core)->ti_arm->gpregs->sp) #define TI_SP(core) ((core)->ti_arm->gpregs->sp)
typedef u32 auxv_t; typedef u32 auxv_t;
typedef u32 tls_t;
static inline void *decode_pointer(u64 v) { return (void*)(u32)v; } static inline void *decode_pointer(u64 v) { return (void*)(u32)v; }
static inline u64 encode_pointer(void *p) { return (u32)p; } static inline u64 encode_pointer(void *p) { return (u32)p; }
......
#ifndef __ASM_PARASITE_H__ #ifndef __ASM_PARASITE_H__
#define __ASM_PARASITE_H__ #define __ASM_PARASITE_H__
static inline u32 arch_get_tls() static inline void arch_get_tls(tls_t *ptls) { (void)ptls; }
{
return 0;
}
#endif #endif
...@@ -143,6 +143,6 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r); ...@@ -143,6 +143,6 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r);
int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state); int sigreturn_prep_fpu_frame(struct rt_sigframe *sigframe, fpu_state_t *fpu_state);
static inline void restore_tls(u32 tls) { } static inline void restore_tls(tls_t *ptls) { (void)ptls; }
#endif #endif
...@@ -112,6 +112,7 @@ typedef struct { ...@@ -112,6 +112,7 @@ typedef struct {
#define TASK_SIZE ((1UL << 47) - PAGE_SIZE) #define TASK_SIZE ((1UL << 47) - PAGE_SIZE)
typedef u64 auxv_t; typedef u64 auxv_t;
typedef u32 tls_t;
#define REG_RES(regs) ((regs).ax) #define REG_RES(regs) ((regs).ax)
#define REG_IP(regs) ((regs).ip) #define REG_IP(regs) ((regs).ip)
......
...@@ -138,7 +138,7 @@ static inline int posix_timers_dump_size(int timer_n) ...@@ -138,7 +138,7 @@ static inline int posix_timers_dump_size(int timer_n)
struct parasite_dump_thread { struct parasite_dump_thread {
unsigned int *tid_addr; unsigned int *tid_addr;
pid_t tid; pid_t tid;
u32 tls; tls_t tls;
stack_t sas; stack_t sas;
}; };
......
...@@ -85,7 +85,7 @@ struct thread_restore_args { ...@@ -85,7 +85,7 @@ struct thread_restore_args {
struct task_restore_args *ta; struct task_restore_args *ta;
u32 tls; tls_t tls;
siginfo_t *siginfo; siginfo_t *siginfo;
unsigned int siginfo_nr; unsigned int siginfo_nr;
......
...@@ -142,7 +142,7 @@ static int dump_thread_common(struct parasite_dump_thread *ti) ...@@ -142,7 +142,7 @@ static int dump_thread_common(struct parasite_dump_thread *ti)
{ {
int ret; int ret;
ti->tls = arch_get_tls(); arch_get_tls(&ti->tls);
ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &ti->tid_addr, 0, 0, 0); ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &ti->tid_addr, 0, 0, 0);
if (ret == 0) if (ret == 0)
ret = sys_sigaltstack(NULL, &ti->sas); ret = sys_sigaltstack(NULL, &ti->sas);
......
...@@ -256,7 +256,7 @@ static int restore_thread_common(struct rt_sigframe *sigframe, ...@@ -256,7 +256,7 @@ static int restore_thread_common(struct rt_sigframe *sigframe,
if (restore_nonsigframe_gpregs(&args->gpregs)) if (restore_nonsigframe_gpregs(&args->gpregs))
return -1; return -1;
restore_tls(args->tls); restore_tls(&args->tls);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment