Commit 4d68ca5c authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

x86/parasite: call get_thread_area on 32-bit addr

It's 32-bit syscall and the high-part of address is dropped,
so call it only on 32-bit addr.

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 fa46f917
#ifndef __CR_ASM_COMPAT_H__
#define __CR_ASM_COMPAT_H__
#ifdef CR_NOGLIBC
# include <compel/plugins/std/syscall.h>
# include <compel/plugins/std/syscall-codes.h>
#else
# define sys_mmap mmap
# define sys_munmap munmap
#endif
#include <sys/mman.h>
static inline void *alloc_compat_syscall_stack(void)
{
void *mem = (void*)sys_mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_32BIT | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED)
return 0;
return mem;
}
static inline void free_compat_syscall_stack(void *mem)
{
long int ret = sys_munmap(mem, PAGE_SIZE);
if (ret)
pr_err("munmap of compat addr %p failed with %ld", mem, ret);
}
#ifdef CONFIG_COMPAT
extern unsigned long call32_from_64(void *stack, void *func);
#endif
#ifndef CR_NOGLIBC
# undef sys_mmap
# undef sys_munmap
#endif
#endif
...@@ -3,12 +3,13 @@ ...@@ -3,12 +3,13 @@
#include "asm-generic/string.h" #include "asm-generic/string.h"
#include <compel/plugins/std/syscall-codes.h> #include <compel/plugins/std/syscall-codes.h>
#include "asm/compat.h"
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
# define __parasite_entry __attribute__((regparm(3))) # define __parasite_entry __attribute__((regparm(3)))
#endif #endif
static void arch_get_user_desc(user_desc_t *desc) static int arch_get_user_desc(user_desc_t *desc)
{ {
int ret = __NR32_get_thread_area; int ret = __NR32_get_thread_area;
/* /*
...@@ -46,21 +47,39 @@ static void arch_get_user_desc(user_desc_t *desc) ...@@ -46,21 +47,39 @@ static void arch_get_user_desc(user_desc_t *desc)
if (ret) if (ret)
pr_err("Failed to dump TLS descriptor #%d: %d\n", pr_err("Failed to dump TLS descriptor #%d: %d\n",
desc->entry_number, ret); desc->entry_number, ret);
return ret;
} }
static void arch_get_tls(tls_t *ptls) static void arch_get_tls(tls_t *ptls)
{ {
void *syscall_mem;
int i; int i;
syscall_mem = alloc_compat_syscall_stack();
if (!syscall_mem) {
pr_err("Failed to allocate memory <4Gb for compat syscall\n");
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) {
user_desc_t *d = &ptls->desc[i];
d->seg_not_present = 1;
d->entry_number = GDT_ENTRY_TLS_MIN + i;
}
return;
}
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) for (i = 0; i < GDT_ENTRY_TLS_NUM; i++)
{ {
user_desc_t *d = &ptls->desc[i]; user_desc_t *d = syscall_mem;
builtin_memset(d, 0, sizeof(user_desc_t)); builtin_memset(d, 0, sizeof(user_desc_t));
d->seg_not_present = 1; d->seg_not_present = 1;
d->entry_number = GDT_ENTRY_TLS_MIN + i; d->entry_number = GDT_ENTRY_TLS_MIN + i;
arch_get_user_desc(d); arch_get_user_desc(d);
builtin_memcpy(&ptls->desc[i], d, sizeof(user_desc_t));
} }
free_compat_syscall_stack(syscall_mem);
} }
#endif #endif
...@@ -5,25 +5,18 @@ ...@@ -5,25 +5,18 @@
#include <compel/asm/fpu.h> #include <compel/asm/fpu.h>
#include "images/core.pb-c.h" #include "images/core.pb-c.h"
#include <compel/plugins/std/syscall-codes.h> #include <compel/plugins/std/syscall-codes.h>
#include <compel/asm/sigframe.h> #include <compel/asm/sigframe.h>
#include "asm/compat.h"
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
extern void *alloc_compat_syscall_stack(void);
extern void free_compat_syscall_stack(void *mem);
extern unsigned long call32_from_64(void *stack, void *func);
extern void restore_tls(tls_t *ptls); extern void restore_tls(tls_t *ptls);
extern int arch_compat_rt_sigaction(void *stack32, int sig, extern int arch_compat_rt_sigaction(void *stack32, int sig,
rt_sigaction_t_compat *act); rt_sigaction_t_compat *act);
#else #else /* CONFIG_COMPAT */
static inline void *alloc_compat_syscall_stack(void) { return NULL; }
static inline void free_compat_syscall_stack(void *stack32) { }
static inline void restore_tls(tls_t *ptls) { } static inline void restore_tls(tls_t *ptls) { }
static inline int static inline int
arch_compat_rt_sigaction(void *stack, int sig, void *act) { return -1; } arch_compat_rt_sigaction(void *stack, int sig, void *act) { return -1; }
#endif #endif /* !CONFIG_COMPAT */
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \ #define RUN_CLONE_RESTORE_FN(ret, clone_flags, new_sp, parent_tid, \
thread_args, clone_restore_fn) \ thread_args, clone_restore_fn) \
......
#include "asm/restorer.h" #include "asm/restorer.h"
#include <compel/asm/fpu.h> #include <compel/asm/fpu.h>
#include "asm/string.h" #include "asm/string.h"
#include "asm/compat.h"
#include <sys/mman.h>
#ifdef CR_NOGLIBC #ifdef CR_NOGLIBC
# include <compel/plugins/std/syscall.h> # include <compel/plugins/std/syscall.h>
#else #else
# define sys_mmap mmap
# define sys_munmap munmap
# ifndef __NR32_rt_sigaction # ifndef __NR32_rt_sigaction
# define __NR32_rt_sigaction 174 # define __NR32_rt_sigaction 174
# endif # endif
...@@ -16,21 +13,6 @@ ...@@ -16,21 +13,6 @@
#include "log.h" #include "log.h"
#include "cpu.h" #include "cpu.h"
void *alloc_compat_syscall_stack(void)
{
void *mem = (void*)sys_mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_32BIT | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED)
return 0;
return mem;
}
void free_compat_syscall_stack(void *mem)
{
sys_munmap(mem, PAGE_SIZE);
}
asm ( " .pushsection .text \n" asm ( " .pushsection .text \n"
" .global restore_rt_sigaction \n" " .global restore_rt_sigaction \n"
" .code32 \n" " .code32 \n"
......
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