[CRIU] [PATCHv2 18/22] x86/restorer/tls: simplify restoring of TLS

Dmitry Safonov dsafonov at virtuozzo.com
Wed Dec 7 09:56:33 PST 2016


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

Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 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 050241cca8a2..9cc76fe17c50 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);
 	}
 
-- 
2.10.2



More information about the CRIU mailing list