diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/include/shared/as-layout.h | 2 | ||||
-rw-r--r-- | arch/um/include/shared/skas/stub-data.h | 9 | ||||
-rw-r--r-- | arch/um/kernel/skas/clone.c | 6 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 11 |
5 files changed, 24 insertions, 8 deletions
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index c22f46a757dc..06292fca5a4d 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h @@ -23,7 +23,7 @@ #define STUB_START stub_start #define STUB_CODE STUB_START #define STUB_DATA (STUB_CODE + UM_KERN_PAGE_SIZE) -#define STUB_DATA_PAGES 1 /* must be a power of two */ +#define STUB_DATA_PAGES 2 /* must be a power of two */ #define STUB_END (STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE) #ifndef __ASSEMBLY__ diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h index 5e3ade3fb38b..779d2a3bac5d 100644 --- a/arch/um/include/shared/skas/stub-data.h +++ b/arch/um/include/shared/skas/stub-data.h @@ -8,10 +8,19 @@ #ifndef __STUB_DATA_H #define __STUB_DATA_H +#include <linux/compiler_types.h> +#include <as-layout.h> + struct stub_data { unsigned long offset; int fd; long parent_err, child_err; + + /* 128 leaves enough room for additional fields in the struct */ + unsigned char syscall_data[UM_KERN_PAGE_SIZE - 128] __aligned(16); + + /* Stack for our signal handlers and for calling into . */ + unsigned char sigstack[UM_KERN_PAGE_SIZE] __aligned(UM_KERN_PAGE_SIZE); }; #endif diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 62435187dda4..906f7454887c 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -27,9 +27,11 @@ stub_clone_handler(void) struct stub_data *data = get_stub_data(); long err; + /* syscall data as a temporary stack area (bottom half). */ err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, - (unsigned long)data + - STUB_DATA_PAGES * UM_KERN_PAGE_SIZE / 2); + (unsigned long) data->syscall_data + + sizeof(data->syscall_data) / 2 - + sizeof(void *)); if (err) { data->parent_err = err; goto done; diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index aeed1c2aaf3c..681839cdd795 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -14,6 +14,10 @@ #include <as-layout.h> #include <os.h> #include <skas.h> +#include <stub-data.h> + +/* Ensure the stub_data struct covers the allocated area */ +static_assert(sizeof(struct stub_data) == STUB_DATA_PAGES * UM_KERN_PAGE_SIZE); int init_new_context(struct task_struct *task, struct mm_struct *mm) { diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 45885deb6cae..56403a1b006a 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -474,11 +474,12 @@ static int __init init_thread_regs(void) thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - (unsigned long) __syscall_stub_start; - thread_regs[REGS_SP_INDEX] = STUB_DATA + STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - - sizeof(void *); -#ifdef __SIGNAL_FRAMESIZE - thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; -#endif + + /* syscall data as a temporary stack area (top half). */ + thread_regs[REGS_SP_INDEX] = STUB_DATA + + offsetof(struct stub_data, syscall_data) + + sizeof(((struct stub_data *) 0)->syscall_data) - + sizeof(void *); return 0; } |