mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-02 23:35:21 +00:00
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: Dmitry Safonov <dsafonov@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
committed by
Andrei Vagin
parent
fa46f91739
commit
4d68ca5c94
41
criu/arch/x86/include/asm/compat.h
Normal file
41
criu/arch/x86/include/asm/compat.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#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 @@
|
|||||||
|
|
||||||
#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)
|
|||||||
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 @@
|
|||||||
#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) \
|
||||||
|
@@ -1,14 +1,11 @@
|
|||||||
#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 @@
|
|||||||
#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"
|
||||||
|
Reference in New Issue
Block a user