From fa2e8f76be90e24082c7b3f93a7db013f89620cb Mon Sep 17 00:00:00 2001 From: Dmitry Safonov Date: Fri, 9 Dec 2016 21:19:44 +0300 Subject: [PATCH] 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: Dmitry Safonov Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- criu/arch/x86/restorer.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/criu/arch/x86/restorer.c b/criu/arch/x86/restorer.c index 050241cca..9cc76fe17 100644 --- a/criu/arch/x86/restorer.c +++ b/criu/arch/x86/restorer.c @@ -33,22 +33,18 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r) } #ifdef CONFIG_COMPAT -asm ( " .pushsection .text \n" - " .global restore_set_thread_area \n" - " .code32 \n" - "restore_set_thread_area: \n" - " movl $"__stringify(__NR32_set_thread_area)",%eax\n" - " int $0x80 \n" - " ret \n" - " .popsection \n" - " .code64"); -extern char restore_set_thread_area; - +/* + * We need here compatible stack, because 32-bit syscalls get + * 4-byte pointer and _usally_ restorer is also under 4Gb, but + * it can be upper and then pointers are messed up. + * (we lose high 4 bytes and... BUNG!) + * Nothing serious, but syscall will return -EFAULT - or if we're + * lucky and lower 4 bytes points on some writeable VMA - corruption). + */ static void *stack32; static int prepare_stack32(void) { - if (stack32) return 0; @@ -63,7 +59,7 @@ static int prepare_stack32(void) void restore_tls(tls_t *ptls) { - int i; + unsigned i; for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) { user_desc_t *desc = &ptls->desc[i]; @@ -76,13 +72,17 @@ void restore_tls(tls_t *ptls) return; 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) - 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); }