Following arm64-support to development branch

This includes the following fixes:
* fix build of arch/arm64/kernel/vdso

Change-Id: I73b05034d29f7f8731ac17f9736edbba4fb2c639
This commit is contained in:
Takehiro Shiratori
2019-01-30 16:27:03 +09:00
committed by Dominique Martinet
parent e52d748744
commit d4d78e9c61
66 changed files with 3110 additions and 1209 deletions

View File

@@ -31,8 +31,8 @@ mcctrl-y += sysfs.o sysfs_files.o arch/$(ARCH)/archdeps.o
KBUILD_EXTRA_SYMBOLS = @abs_builddir@/../../../../ihk/linux/core/Module.symvers
ifeq ($(ARCH), arm64)
EXTRA_CFLAGS += $(foreach i, $(shell seq 1 100), $(addprefix -DPOSTK_DEBUG_ARCH_DEP_, $(i)))
EXTRA_CFLAGS += $(foreach i, $(shell seq 1 100), $(addprefix -DPOSTK_DEBUG_TEMP_FIX_, $(i)))
EXTRA_CFLAGS += $(foreach i, $(shell seq 6 120), $(addprefix -DPOSTK_DEBUG_ARCH_DEP_, $(i)))
EXTRA_CFLAGS += $(foreach i, $(shell seq 6 110), $(addprefix -DPOSTK_DEBUG_TEMP_FIX_, $(i)))
endif
.PHONY: clean install modules

View File

@@ -2,6 +2,10 @@
#ifndef __HEADER_MCCTRL_ARM64_ARCHDEPS_H
#define __HEADER_MCCTRL_ARM64_ARCHDEPS_H
#ifdef POSTK_DEBUG_ARCH_DEP_100 /* rus_mmap() setting vm_flags arch depend defined */
#include <linux/mm.h>
#endif /* POSTK_DEBUG_ARCH_DEP_100 */
extern int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep);

View File

@@ -2,6 +2,10 @@
#ifndef __HEADER_MCCTRL_X86_64_ARCHDEPS_H
#define __HEADER_MCCTRL_X86_64_ARCHDEPS_H
#ifdef POSTK_DEBUG_ARCH_DEP_100 /* rus_mmap() setting vm_flags arch depend defined */
#include <linux/mm.h>
#endif /* POSTK_DEBUG_ARCH_DEP_100 */
extern int translate_rva_to_rpa(ihk_os_t os, unsigned long rpt, unsigned long rva,
unsigned long *rpap, unsigned long *pgsizep);

View File

@@ -449,7 +449,8 @@ int mcctrl_add_per_thread_data(struct mcctrl_per_proc_data *ppd, void *data);
void mcctrl_put_per_thread_data_unsafe(struct mcctrl_per_thread_data *ptd);
void mcctrl_put_per_thread_data(struct mcctrl_per_thread_data* ptd);
#ifdef POSTK_DEBUG_ARCH_DEP_56 /* Strange how to use inline declaration fix. */
inline struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(struct mcctrl_per_proc_data *ppd, struct task_struct *task)
static inline struct mcctrl_per_thread_data *mcctrl_get_per_thread_data(struct mcctrl_per_proc_data *ppd,
struct task_struct *task)
{
struct mcctrl_per_thread_data *ptd_iter, *ptd = NULL;
int hash = (((uint64_t)task >> 4) & MCCTRL_PER_THREAD_DATA_HASH_MASK);

View File

@@ -1,4 +1,4 @@
# Makefile.in COPYRIGHT FUJITSU LIMITED 2015-2016
# Makefile.in COPYRIGHT FUJITSU LIMITED 2015-2018
CC=@CC@
MCC=mpicc
BINDIR=@BINDIR@
@@ -35,8 +35,20 @@ ifeq ($(WITH_SYSCALL_INTERCEPT),yes)
endif
ifeq ($(ARCH), arm64)
CFLAGS += $(foreach i, $(shell seq 1 100), $(addprefix -DPOSTK_DEBUG_ARCH_DEP_, $(i)))
CFLAGS += $(foreach i, $(shell seq 1 100), $(addprefix -DPOSTK_DEBUG_TEMP_FIX_, $(i)))
CFLAGS += $(foreach i, $(shell seq 6 120), $(addprefix -DPOSTK_DEBUG_ARCH_DEP_, $(i)))
CFLAGS += $(foreach i, $(shell seq 6 110), $(addprefix -DPOSTK_DEBUG_TEMP_FIX_, $(i)))
# get HOST-kernel memory settings
HOST_DIR=@KDIR@
HOST_CONFIG=$(HOST_DIR)/.config
HOST_KERNEL_64K_PAGES=$(shell grep -E "^CONFIG_ARM64_64K_PAGES=y" $(HOST_CONFIG) | sed 's|CONFIG_ARM64_64K_PAGES=||g')
HOST_KERNEL_VA_BITS=$(shell grep -E "^CONFIG_ARM64_VA_BITS=" $(HOST_CONFIG) | sed 's|CONFIG_ARM64_VA_BITS=||g')
ifeq ($(HOST_KERNEL_64K_PAGES), y)
CFLAGS += -DCONFIG_ARM64_64K_PAGES
endif
CFLAGS += -DCONFIG_ARM64_VA_BITS=$(HOST_KERNEL_VA_BITS)
endif
all: $(TARGET)

View File

@@ -13,8 +13,8 @@ all: $(TARGET)
../../libmcexec.a: archdep.o arch_syscall.o
$(AR) cr ../../libmcexec.a archdep.o arch_syscall.o
archdep.o: archdep.S
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $<
archdep.o: archdep.c archdep.S
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $^
arch_syscall.o: arch_syscall.c
$(CC) -c -I${KDIR} $(CFLAGS) $(EXTRA_CFLAGS) -fPIE -pie -pthread $<

View File

@@ -1,4 +1,4 @@
/* arch-eclair.c COPYRIGHT FUJITSU LIMITED 2016 */
/* arch-eclair.c COPYRIGHT FUJITSU LIMITED 2016-2018 */
#include <stdio.h>
#include <eclair.h>
#include <arch-eclair.h>
@@ -49,3 +49,20 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
return total;
}
#ifdef POSTK_DEBUG_ARCH_DEP_34
uintptr_t virt_to_phys(uintptr_t va)
{
extern uintptr_t kernel_base;
if (va >= MAP_KERNEL) {
return (va - MAP_KERNEL + kernel_base);
}
if (va >= MAP_ST) {
return (va - MAP_ST);
}
return NOPHYS;
} /* virt_to_phys() */
#endif /* POSTK_DEBUG_ARCH_DEP_34 */

View File

@@ -4,123 +4,300 @@
#include <asm/ptrace.h>
typedef struct user_pt_regs syscall_args;
#ifndef NT_ARM_SYSTEM_CALL
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
#endif /* !NT_ARM_SYSTEM_CALL */
typedef struct {
struct user_pt_regs regs;
unsigned long orig_x0;
unsigned long ret_value;
pid_t target_pid;
int bypass;
} syscall_args;
enum ptrace_syscall_dir {
PTRACE_SYSCALL_ENTER = 0,
PTRACE_SYSCALL_EXIT,
};
static inline int
syscall_enter(syscall_args *args)
{
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return -1;
}
switch (args->regs.regs[7]) {
case PTRACE_SYSCALL_ENTER:
return 1;
case PTRACE_SYSCALL_EXIT:
return 0;
default:
printf("%s: x7 is neither SYSCALL_ENTER nor SYSCALL_EXIT.\n",
__func__);
return -1;
}
}
static inline int
get_syscall_args(int pid, syscall_args *args)
{
/* TODO: skeleton for UTI */
return -1;
struct iovec iov;
long ret = -1;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return -1;
}
args->target_pid = pid;
args->bypass = 0;
memset(&iov, 0, sizeof(iov));
iov.iov_base = &args->regs;
iov.iov_len = sizeof(args->regs);
ret = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
if (!ret) {
if (syscall_enter(args)) {
args->orig_x0 = args->regs.regs[0];
args->ret_value = 0;
}
else {
/* orig_x0 is saved */
args->ret_value = args->regs.regs[0];
}
}
return ret;
}
static inline int
set_syscall_args(int pid, syscall_args *args)
{
/* TODO: skeleton for UTI */
return -1;
struct iovec iov;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return -1;
}
memset(&iov, 0, sizeof(iov));
iov.iov_base = &args->regs;
iov.iov_len = sizeof(args->regs);
return ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov);
}
static inline unsigned long
get_syscall_number(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
}
int sysno = -1;
long ret = -1;
struct iovec iov;
static inline unsigned long
get_syscall_return(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return -1;
}
memset(&iov, 0, sizeof(iov));
iov.iov_base = &sysno;
iov.iov_len = sizeof(sysno);
ret = ptrace(PTRACE_GETREGSET, args->target_pid, NT_ARM_SYSTEM_CALL,
&iov);
if (ret) {
printf("%s: ptrace(PTRACE_GETREGSET) failed. (%d)",
__func__, errno);
}
return sysno;
}
static inline unsigned long
get_syscall_arg1(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return 0;
}
return args->orig_x0;
}
static inline unsigned long
get_syscall_arg2(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return 0;
}
return args->regs.regs[1];
}
static inline unsigned long
get_syscall_arg3(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return 0;
}
return args->regs.regs[2];
}
static inline unsigned long
get_syscall_arg4(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return 0;
}
return args->regs.regs[3];
}
static inline unsigned long
get_syscall_arg5(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return 0;
}
return args->regs.regs[4];
}
static inline unsigned long
get_syscall_arg6(syscall_args *args)
{
/* TODO: skeleton for UTI */
return 0;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return 0;
}
return args->regs.regs[5];
}
static inline void
set_syscall_number(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
int sysno = (int)value;
long ret = -1;
struct iovec iov;
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
memset(&iov, 0, sizeof(iov));
iov.iov_base = &sysno;
iov.iov_len = sizeof(sysno);
ret = ptrace(PTRACE_SETREGSET, args->target_pid, NT_ARM_SYSTEM_CALL,
&iov);
if (ret) {
printf("%s: ptrace(PTRACE_GETREGSET) failed. (%d)",
__func__, errno);
}
else {
if (value == (unsigned long)-1) {
args->bypass = 1;
}
}
}
static inline void
set_syscall_ret_or_arg1(syscall_args *args, unsigned long value, int ret_flag)
{
/* called by set_syscall_return() */
if (ret_flag == 1) {
/* stopped syscall-enter */
if (syscall_enter(args) == 1) {
/* syscall no bypass */
if (args->bypass != 1) {
/* no effect */
goto out;
}
}
}
/* called by set_syscall_arg1() */
else if (ret_flag == 0) {
/* stopped syscall-return */
if (syscall_enter(args) == 0) {
/* no effect */
goto out;
}
/* set original arg1 */
args->orig_x0 = value;
}
/* illegal ret_flag */
else {
/* no effect */
goto out;
}
/* set value */
args->regs.regs[0] = value;
out:
return;
}
static inline void
set_syscall_return(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
set_syscall_ret_or_arg1(args, value, 1);
}
static inline void
set_syscall_arg1(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
set_syscall_ret_or_arg1(args, value, 0);
}
static inline void
set_syscall_arg2(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
args->regs.regs[1] = value;
}
static inline void
set_syscall_arg3(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
args->regs.regs[2] = value;
}
static inline void
set_syscall_arg4(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
args->regs.regs[3] = value;
}
static inline void
set_syscall_arg5(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
args->regs.regs[4] = value;
}
static inline void
set_syscall_arg6(syscall_args *args, unsigned long value)
{
/* TODO: skeleton for UTI */
if (!args) {
printf("%s: input args is NULL.\n", __func__);
return;
}
args->regs.regs[5] = value;
}
#endif /* !ARCH_ARGS_H */

View File

@@ -1,16 +1,39 @@
/* archdep.S COPYRIGHT FUJITSU LIMITED 2017-2018 */
/* TODO: skeleton for UTI */
#include <sys/syscall.h>
/*
* int switch_ctx(int fd, unsigned long cmd, void **param, void *lctx,
* void *rctx);
* <register> : <argument>
* x0 : int fd
* x1 : unsigned long cmd
* x2 : void **param
* x3 : void *lctx
* x4 : void *rctx
*/
.global switch_ctx
switch_ctx:
/* send ioctl(fd, cmd, param) */
mov w8, #__NR_ioctl
svc #0x0
/* if (syscall_ret < 0 && -4095(-MAX_ERRNO) <= syscall_ret) goto 1f; */
cmp x0, #0xfffffffffffff000
b.hi 1f
/* if (syscall_ret != 0) goto 2f; */
cmp x0, #0x0
b.ne 2f
/* function_ret = 0 */
mov x0, #0x0
ret
/* TODO: skeleton for UTI */
.global compare_and_swap
compare_and_swap:
ret
/* TODO: skeleton for UTI */
.global compare_and_swap_int
compare_and_swap_int:
/* error case */
1:
/* function_ret = -1 */
mov x0, #0xffffffffffffffff
2:
ret

View File

@@ -0,0 +1,49 @@
/* archdep.c COPYRIGHT FUJITSU LIMITED 2017 */
#include <asm/ptrace.h>
/* @ref.impl arch/arm64/include/asm/atomic_ll_sc.h::__ll_sc___cmpxchg_case_mb_8() */
unsigned long compare_and_swap(unsigned long *addr,
unsigned long old, unsigned long new)
{
unsigned long tmp, oldval;
asm volatile(
" prfm pstl1strm, %2\n"
"1: ldxr %1, %2\n"
" eor %0, %1, %3\n"
" cbnz %0, 2f\n"
" stlxr %w0, %4, %2\n"
" cbnz %w0, 1b\n"
" dmb ish\n"
" mov %1, %3\n"
"2:"
: "=&r"(tmp), "=&r"(oldval), "+Q"(*addr)
: "Lr"(old), "r"(new)
: "memory");
return oldval;
}
/* @ref.impl arch/arm64/include/asm/atomic_ll_sc.h::__ll_sc___cmpxchg_case_mb_4() */
unsigned int compare_and_swap_int(unsigned int *addr,
unsigned int old, unsigned int new)
{
unsigned long tmp, oldval;
asm volatile(
" prfm pstl1strm, %2\n"
"1: ldxr %w1, %2\n"
" eor %w0, %w1, %w3\n"
" cbnz %w0, 2f\n"
" stlxr %w0, %w4, %2\n"
" cbnz %w0, 1b\n"
" dmb ish\n"
" mov %w1, %w3\n"
"2:"
: "=&r"(tmp), "=&r"(oldval), "+Q"(*addr)
: "Lr"(old), "r"(new)
: "memory");
return oldval;
}

View File

@@ -1,11 +1,48 @@
/* arch-eclair.h COPYRIGHT FUJITSU LIMITED 2016 */
/* arch-eclair.h COPYRIGHT FUJITSU LIMITED 2016-2018 */
#ifndef HEADER_USER_ARM64_ECLAIR_H
#define HEADER_USER_ARM64_ECLAIR_H
/* VA_BITS=48, 4K_PAGE address */
#define MAP_KERNEL 0xffffffffff800000
#define MAP_ST 0xffff800000000000
#define MAP_KERNEL_TEXT "0xffffffffff800000"
#ifdef CONFIG_ARM64_64K_PAGES
#
# if (CONFIG_ARM64_VA_BITS == 42)
# /* VA_BITS=42, 64K_PAGE address */
# define MAP_KERNEL 0xffffffffe0000000
# define MAP_ST 0xfffffe0000000000
# define MAP_KERNEL_TEXT "0xffffffffe0000000"
#
# elif (CONFIG_ARM64_VA_BITS == 48)
# /* VA_BITS=48, 64K_PAGE address */
# define MAP_KERNEL 0xffffffffe0000000
# define MAP_ST 0xffff800000000000
# define MAP_KERNEL_TEXT "0xffffffffe0000000"
#
# else
#
# error "No support VA_BITS and PAGE_SIZE"
#
# endif
#
#else /* CONFIG_ARM64_64K_PAGES */
#
# if (CONFIG_ARM64_VA_BITS == 39)
# /* VA_BITS=39, 4K_PAGE address */
# define MAP_KERNEL 0xffffffffff800000
# define MAP_ST 0xffffffc000000000
# define MAP_KERNEL_TEXT "0xffffffffff800000"
#
# elif (CONFIG_ARM64_VA_BITS == 48)
# /* VA_BITS=48, 4K_PAGE address */
# define MAP_KERNEL 0xffffffffff800000
# define MAP_ST 0xffff800000000000
# define MAP_KERNEL_TEXT "0xffffffffff800000"
#
# else
#
# error "No support VA_BITS and PAGE_SIZE"
#
# endif
#
#endif /* CONFIG_ARM64_64K_PAGES */
#define ARCH_CLV_SPAN "arm64_cpu_local_variables_span"
@@ -13,7 +50,7 @@
#define ARCH_REGS 34
#define PANIC_REGS_OFFSET 144
#define PANIC_REGS_OFFSET 160
struct arch_kregs {
unsigned long x19, x20, x21, x22, x23;
@@ -21,4 +58,8 @@ struct arch_kregs {
unsigned long fp, sp, pc;
};
#ifdef POSTK_DEBUG_ARCH_DEP_34
uintptr_t virt_to_phys(uintptr_t va);
#endif /* POSTK_DEBUG_ARCH_DEP_34 */
#endif /* HEADER_USER_ARM64_ECLAIR_H */

View File

@@ -99,3 +99,26 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
return total;
}
#ifdef POSTK_DEBUG_ARCH_DEP_34
static uintptr_t virt_to_phys(uintptr_t va)
{
extern uintptr_t kernel_base;
if (va >= MAP_KERNEL_START) {
return va - MAP_KERNEL_START + kernel_base;
}
else if (va >= LINUX_PAGE_OFFSET) {
return va - LINUX_PAGE_OFFSET;
}
else if (va >= MAP_FIXED_START) {
return va - MAP_FIXED_START;
}
else if (va >= MAP_ST_START) {
return va - MAP_ST_START;
}
return NOPHYS;
} /* virt_to_phys() */
#endif /* POSTK_DEBUG_ARCH_DEP_34 */

View File

@@ -25,11 +25,13 @@ get_syscall_number(syscall_args *args)
return args->orig_rax;
}
#ifndef POSTK_DEBUG_ARCH_DEP_90 /* syscall_enter check is arch depend. */
static inline unsigned long
get_syscall_return(syscall_args *args)
{
return args->rax;
}
#endif /* !POSTK_DEBUG_ARCH_DEP_90 */
static inline unsigned long
get_syscall_arg1(syscall_args *args)
@@ -120,4 +122,8 @@ set_syscall_arg6(syscall_args *args, unsigned long value)
{
args->r9 = value;
}
#ifdef POSTK_DEBUG_ARCH_DEP_90 /* syscall_enter check is arch depend. */
#define syscall_enter(argsp) (get_syscall_return(argsp) == -ENOSYS)
#endif /* POSTK_DEBUG_ARCH_DEP_90 */
#endif

View File

@@ -31,4 +31,8 @@ struct arch_kregs {
uintptr_t r15, rflags, rsp0;
};
#ifdef POSTK_DEBUG_ARCH_DEP_34
uintptr_t virt_to_phys(uintptr_t va);
#endif /* POSTK_DEBUG_ARCH_DEP_34 */
#endif /* HEADER_USER_x86_ECLAIR_H */

View File

@@ -73,7 +73,11 @@ static dump_mem_chunks_t *mem_chunks;
static int num_processors = -1;
static asymbol **symtab = NULL;
static ssize_t nsyms;
#ifdef POSTK_DEBUG_ARCH_DEP_34
uintptr_t kernel_base;
#else /* POSTK_DEBUG_ARCH_DEP_34 */
static uintptr_t kernel_base;
#endif /* POSTK_DEBUG_ARCH_DEP_34 */
static struct thread_info *tihead = NULL;
static struct thread_info **titailp = &tihead;
static struct thread_info *curr_thread = NULL;
@@ -93,6 +97,7 @@ uintptr_t lookup_symbol(char *name) {
return NOSYMBOL;
} /* lookup_symbol() */
#ifndef POSTK_DEBUG_ARCH_DEP_34
#define NOPHYS ((uintptr_t)-1)
static uintptr_t virt_to_phys(uintptr_t va) {
@@ -111,6 +116,7 @@ static uintptr_t virt_to_phys(uintptr_t va) {
return NOPHYS;
} /* virt_to_phys() */
#endif /* !POSTK_DEBUG_ARCH_DEP_34 */
static int read_physmem(uintptr_t pa, void *buf, size_t size) {
off_t off;

View File

@@ -15,4 +15,8 @@ ssize_t print_bin(char *buf, size_t buf_size, void *data, size_t size);
/* arch depend */
int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs);
#ifdef POSTK_DEBUG_ARCH_DEP_34
#define NOPHYS ((uintptr_t)-1)
#endif /* POSTK_DEBUG_ARCH_DEP_34 */
#endif /* HEADER_USER_COMMON_ECLAIR_H */

View File

@@ -244,7 +244,11 @@ void cmd_ldump2mcdump(void)
bfd_init();
#ifdef POSTK_DEBUG_ARCH_DEP_34 /* use bfd_open target is NULL(automatic) */
abfd = bfd_fopen(fname, NULL, "w", -1);
#else /* POSTK_DEBUG_ARCH_DEP_34 */
abfd = bfd_fopen(fname, "elf64-x86-64", "w", -1);
#endif /* POSTK_DEBUG_ARCH_DEP_34 */
if (!abfd) {
bfd_perror("bfd_fopen");
return;