Commit fa2e8f76 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

x86/restorer/tls: simplify restoring of TLS

We can live here without 32-bit CS - this syscall doesn't depend on
descriptor type.
No functional changes expected, cleanup.

travis-ci: success for Rectify 32-bit compatible C/R on x86
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent b7c4ca51
...@@ -33,22 +33,18 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r) ...@@ -33,22 +33,18 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r)
} }
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
asm ( " .pushsection .text \n" /*
" .global restore_set_thread_area \n" * We need here compatible stack, because 32-bit syscalls get
" .code32 \n" * 4-byte pointer and _usally_ restorer is also under 4Gb, but
"restore_set_thread_area: \n" * it can be upper and then pointers are messed up.
" movl $"__stringify(__NR32_set_thread_area)",%eax\n" * (we lose high 4 bytes and... BUNG!)
" int $0x80 \n" * Nothing serious, but syscall will return -EFAULT - or if we're
" ret \n" * lucky and lower 4 bytes points on some writeable VMA - corruption).
" .popsection \n" */
" .code64");
extern char restore_set_thread_area;
static void *stack32; static void *stack32;
static int prepare_stack32(void) static int prepare_stack32(void)
{ {
if (stack32) if (stack32)
return 0; return 0;
...@@ -63,7 +59,7 @@ static int prepare_stack32(void) ...@@ -63,7 +59,7 @@ static int prepare_stack32(void)
void restore_tls(tls_t *ptls) void restore_tls(tls_t *ptls)
{ {
int i; unsigned i;
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) { for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) {
user_desc_t *desc = &ptls->desc[i]; user_desc_t *desc = &ptls->desc[i];
...@@ -76,13 +72,17 @@ void restore_tls(tls_t *ptls) ...@@ -76,13 +72,17 @@ void restore_tls(tls_t *ptls)
return; return;
builtin_memcpy(stack32, desc, sizeof(user_desc_t)); builtin_memcpy(stack32, desc, sizeof(user_desc_t));
asm volatile (
" mov %1,%%eax \n"
" mov %2,%%ebx \n"
" int $0x80 \n"
" mov %%eax,%0 \n"
: "=g"(ret)
: "r"(__NR32_set_thread_area), "r"((uint32_t)(uintptr_t)stack32)
: "eax", "ebx", "memory");
/* user_desc parameter for set_thread_area syscall */
asm volatile ("\t movl %%ebx,%%ebx\n" : :"b"(stack32));
call32_from_64(stack32 + PAGE_SIZE, &restore_set_thread_area);
asm volatile ("\t movl %%eax,%0\n" : "=r"(ret));
if (ret) if (ret)
pr_err("Failed to restore TLS descriptor %d in GDT ret %d\n", pr_err("Failed to restore TLS descriptor %u in GDT: %d\n",
desc->entry_number, ret); desc->entry_number, ret);
} }
......
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