diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386 index d6cffb27fff8159b255177a09ac68e1899fd0d01..9876d80d85ddccdba00e5e89cd1e54db6ab8612b 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 @@ -65,20 +65,6 @@ config 3_LEVEL_PGTABLES However, this it experimental on 32-bit architectures, so if unsure say N (on x86-64 it's automatically enabled, instead, as it's safe there). -config STUB_CODE - hex - default 0xbfffe000 if !HOST_VMSPLIT_2G - default 0x7fffe000 if HOST_VMSPLIT_2G - -config STUB_DATA - hex - default 0xbffff000 if !HOST_VMSPLIT_2G - default 0x7ffff000 if HOST_VMSPLIT_2G - -config STUB_START - hex - default STUB_CODE - config ARCH_HAS_SC_SIGNALS bool default y diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64 index f60e9e506424cf91e6b97ff61105a7dfc4b4788d..d632e9a89cc3d671ab69730cb5d0e457457e30d9 100644 --- a/arch/um/Kconfig.x86_64 +++ b/arch/um/Kconfig.x86_64 @@ -17,24 +17,12 @@ config SEMAPHORE_SLEEPERS config TOP_ADDR hex - default 0x80000000 + default 0x7fc0000000 config 3_LEVEL_PGTABLES bool default y -config STUB_CODE - hex - default 0x7fbfffe000 - -config STUB_DATA - hex - default 0x7fbffff000 - -config STUB_START - hex - default STUB_CODE - config ARCH_HAS_SC_SIGNALS bool default n diff --git a/arch/um/defconfig b/arch/um/defconfig index 1cbbe980f10621bfcf0d0f1d595463aa2367c354..f609edede0657fe5cebb1641a8458cb66e9cdd96 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -59,9 +59,6 @@ CONFIG_SEMAPHORE_SLEEPERS=y # CONFIG_HOST_2G_2G is not set CONFIG_TOP_ADDR=0xc0000000 # CONFIG_3_LEVEL_PGTABLES is not set -CONFIG_STUB_CODE=0xbfffe000 -CONFIG_STUB_DATA=0xbffff000 -CONFIG_STUB_START=0xbfffe000 CONFIG_ARCH_HAS_SC_SIGNALS=y CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y CONFIG_GENERIC_HWEIGHT=y diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h index 2f16a1c7d6163e3bed009045137c2df30e244405..a5cdf953e04a964569e9ea6f2912e9a9b9d6369a 100644 --- a/arch/um/include/as-layout.h +++ b/arch/um/include/as-layout.h @@ -6,6 +6,28 @@ #ifndef __START_H__ #define __START_H__ +#include "uml-config.h" +#include "kern_constants.h" + +/* + * Assembly doesn't want any casting, but C does, so define these + * without casts here, and define new symbols with casts inside the C + * section. + */ +#define ASM_STUB_CODE (UML_CONFIG_TOP_ADDR - 2 * UM_KERN_PAGE_SIZE) +#define ASM_STUB_DATA (UML_CONFIG_TOP_ADDR - UM_KERN_PAGE_SIZE) +#define ASM_STUB_START ASM_STUB_CODE + +/* + * This file is included by the assembly stubs, which just want the + * definitions above. + */ +#ifndef __ASSEMBLY__ + +#define STUB_CODE ((unsigned long) ASM_STUB_CODE) +#define STUB_DATA ((unsigned long) ASM_STUB_DATA) +#define STUB_START ((unsigned long) ASM_STUB_START) + #include "sysdep/ptrace.h" struct cpu_task { @@ -32,3 +54,5 @@ extern int linux_main(int argc, char **argv); extern void (*sig_info[])(int, struct uml_pt_regs *); #endif + +#endif diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index 19c85f330fc1602af09cb6ca9f19953bc6a0ba32..8c097b87fca7be4b3ea209feff41aa4fa2adc3d6 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h @@ -9,6 +9,7 @@ #include #include #include +#include "as-layout.h" #include "stub-data.h" #include "kern_constants.h" #include "uml-config.h" @@ -89,12 +90,12 @@ static inline void remap_stack(int fd, unsigned long offset) { __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" "movl %7, %%ebx ; movl %%eax, (%%ebx)" - : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), - "c" (UM_KERN_PAGE_SIZE), + : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), + "c" (UM_KERN_PAGE_SIZE), "d" (PROT_READ | PROT_WRITE), - "S" (MAP_FIXED | MAP_SHARED), "D" (fd), - "a" (offset), - "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) + "S" (MAP_FIXED | MAP_SHARED), "D" (fd), + "a" (offset), + "i" (&((struct stub_data *) STUB_DATA)->err) : "memory"); } diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h index 92e989f81761d64f0616fc5be6aa6da18fd2676e..655f9c2de3ac0b127a6e57729b5d5ab3de7b9540 100644 --- a/arch/um/include/sysdep-x86_64/stub.h +++ b/arch/um/include/sysdep-x86_64/stub.h @@ -9,6 +9,7 @@ #include #include #include +#include "as-layout.h" #include "stub-data.h" #include "kern_constants.h" #include "uml-config.h" @@ -94,13 +95,13 @@ static inline void remap_stack(long fd, unsigned long offset) { __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " - "movq %%rax, (%%rbx)": - : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), - "S" (UM_KERN_PAGE_SIZE), - "d" (PROT_READ | PROT_WRITE), - "g" (MAP_FIXED | MAP_SHARED), "g" (fd), + "movq %%rax, (%%rbx)": + : "a" (STUB_MMAP_NR), "D" (STUB_DATA), + "S" (UM_KERN_PAGE_SIZE), + "d" (PROT_READ | PROT_WRITE), + "g" (MAP_FIXED | MAP_SHARED), "g" (fd), "g" (offset), - "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) + "i" (&((struct stub_data *) STUB_DATA)->err) : __syscall_clobber, "r10", "r8", "r9" ); } diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 7c77adecd9193d899531b3ffe80e4e6497beeebf..8196450451cd6332d6b76eb97bbb3b9ffc93a17f 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -11,6 +11,7 @@ #include "asm/current.h" #include "asm/processor.h" #include "asm/uaccess.h" +#include "as-layout.h" #include "mem_user.h" #include "skas.h" #include "os.h" @@ -18,7 +19,7 @@ void flush_thread(void) { void *data = NULL; - unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; + unsigned long end = proc_mm ? task_size : STUB_START; int ret; arch_flush_thread(¤t->thread.arch); diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index 47b812b3bca88b965b48563de658db9ada72fd81..d119f4f7d8971ee7576e6c7db57c59bd3d4704a5 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -4,6 +4,7 @@ #include #include #include +#include "as-layout.h" #include "ptrace_user.h" #include "skas.h" #include "stub-data.h" @@ -21,12 +22,11 @@ void __attribute__ ((__section__ (".__syscall_stub"))) stub_clone_handler(void) { - struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; + struct stub_data *data = (struct stub_data *) STUB_DATA; long err; err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, - UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE / 2 - - sizeof(void *)); + STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *)); if(err != 0) goto out; diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index ae79888cf5200b76eab111dabf29ca2642c33d67..f859ec306cd5ded54f4239bba0519d58eb52f2e3 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -7,6 +7,7 @@ #include "linux/sched.h" #include "asm/pgalloc.h" #include "asm/pgtable.h" +#include "as-layout.h" #include "os.h" #include "skas.h" @@ -83,12 +84,12 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) */ mm->pgd[USER_PTRS_PER_PGD] = __pgd(0); - ret = init_stub_pte(mm, CONFIG_STUB_CODE, + ret = init_stub_pte(mm, STUB_CODE, (unsigned long) &__syscall_stub_start); if (ret) goto out_free; - ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); + ret = init_stub_pte(mm, STUB_DATA, stack); if (ret) goto out_free; diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 0297e63f9725c1bbbcc121e412a5f07bd7f52940..fce389c2342f3d942cdae4d047edbb1f3a2bab50 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -18,7 +18,7 @@ int new_mm(unsigned long stack) return fd; if (skas_needs_stub) - map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); + map_stub_pages(fd, STUB_CODE, STUB_DATA, stack); return fd; } diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 942f20ea888aa89dde2cfd52a3dbf5826090d77b..f4a0e407eee4d66e9fb8b62db6a3e36110d2854a 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -485,8 +485,8 @@ void __flush_tlb_one(unsigned long addr) static void fix_range(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force) { - if (!proc_mm && (end_addr > CONFIG_STUB_START)) - end_addr = CONFIG_STUB_START; + if (!proc_mm && (end_addr > STUB_START)) + end_addr = STUB_START; fix_range_common(mm, start_addr, end_addr, force); } @@ -510,7 +510,7 @@ void flush_tlb_mm(struct mm_struct *mm) if (atomic_read(&mm->mm_users) == 0) return; - end = proc_mm ? task_size : CONFIG_STUB_START; + end = proc_mm ? task_size : STUB_START; fix_range(mm, 0, end, 0); } diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 1993e5e1225659f43d36e7b3953f1969cb698f23..f1c71393f57810feb8368b256f7dab7bf5111a43 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -242,7 +242,8 @@ static unsigned long set_task_sizes_skas(unsigned long *task_size_out) if (!skas_needs_stub) *task_size_out = host_task_size; - else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; + else + *task_size_out = STUB_START & PGDIR_MASK; return host_task_size; } diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index d58d11179bb7ce1bde906e89d1b1079b9e03afe9..484e68f9f7ae7362a0e36b87505ed9048f7302f2 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -10,6 +10,7 @@ #include #include "init.h" #include "kern_constants.h" +#include "as-layout.h" #include "mm_id.h" #include "os.h" #include "proc_mm.h" @@ -40,7 +41,7 @@ static unsigned long syscall_regs[MAX_REG_NR]; static int __init init_syscall_regs(void) { get_safe_registers(syscall_regs); - syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + syscall_regs[REGS_IP_INDEX] = STUB_CODE + ((unsigned long) &batch_syscall_stub - (unsigned long) &__syscall_stub_start); return 0; @@ -93,8 +94,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) ret = *((unsigned long *) mm_idp->stack); offset = *((unsigned long *) mm_idp->stack + 1); if (offset) { - data = (unsigned long *)(mm_idp->stack + - offset - UML_CONFIG_STUB_DATA); + data = (unsigned long *)(mm_idp->stack + offset - STUB_DATA); printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, " "data = %p\n", ret, offset, data); syscall = (unsigned long *)((unsigned long)data + data[0]); @@ -182,7 +182,7 @@ long syscall_stub_data(struct mm_id * mm_idp, memcpy(stack + 1, data, data_count * sizeof(long)); *stub_addr = (void *)(((unsigned long)(stack + 1) & - ~UM_KERN_PAGE_MASK) + UML_CONFIG_STUB_DATA); + ~UM_KERN_PAGE_MASK) + STUB_DATA); return 0; } diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 8548f126d6287c0af594469644dd4109cce9069e..e60d6e6c5a58a913c0abbce0f0d8b78c01857afb 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -191,22 +191,23 @@ static int userspace_tramp(void *stack) int fd; unsigned long long offset; fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); - addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, + addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE, PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); if (addr == MAP_FAILED) { - printk(UM_KERN_ERR "mapping mmap stub failed, " - "errno = %d\n", errno); + printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, " + "errno = %d\n", STUB_CODE, errno); exit(1); } if (stack != NULL) { fd = phys_mapping(to_phys(stack), &offset); - addr = mmap((void *) UML_CONFIG_STUB_DATA, + addr = mmap((void *) STUB_DATA, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, offset); if (addr == MAP_FAILED) { printk(UM_KERN_ERR "mapping segfault stack " - "failed, errno = %d\n", errno); + "at 0x%lx failed, errno = %d\n", + STUB_DATA, errno); exit(1); } } @@ -214,11 +215,11 @@ static int userspace_tramp(void *stack) if (!ptrace_faultinfo && (stack != NULL)) { struct sigaction sa; - unsigned long v = UML_CONFIG_STUB_CODE + + unsigned long v = STUB_CODE + (unsigned long) stub_segv_handler - (unsigned long) &__syscall_stub_start; - set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); + set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGWINCH); @@ -382,10 +383,10 @@ static int __init init_thread_regs(void) { get_safe_registers(thread_regs); /* Set parent's instruction pointer to start of clone-stub */ - thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + thread_regs[REGS_IP_INDEX] = STUB_CODE + (unsigned long) stub_clone_handler - (unsigned long) &__syscall_stub_start; - thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE - + thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE - sizeof(void *); #ifdef __SIGNAL_FRAMESIZE thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; @@ -443,7 +444,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) * child's stack and check it. */ wait_stub_done(pid); - if (child_data->err != UML_CONFIG_STUB_DATA) + if (child_data->err != STUB_DATA) panic("copy_context_skas0 - stub-child reports error %ld\n", child_data->err); diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S index 6a70d9ab5c2905177429ba9b0f3ae2c1fc084fad..e730772c401b53206810ceb387aa56b9f4f06cf9 100644 --- a/arch/um/sys-i386/stub.S +++ b/arch/um/sys-i386/stub.S @@ -1,4 +1,5 @@ #include "uml-config.h" +#include "as-layout.h" .globl syscall_stub .section .__syscall_stub, "x" @@ -6,7 +7,7 @@ .globl batch_syscall_stub batch_syscall_stub: /* load pointer to first operation */ - mov $(UML_CONFIG_STUB_DATA+8), %esp + mov $(ASM_STUB_DATA+8), %esp again: /* load length of additional data */ @@ -14,12 +15,12 @@ again: /* if(length == 0) : end of list */ /* write possible 0 to header */ - mov %eax, UML_CONFIG_STUB_DATA+4 + mov %eax, ASM_STUB_DATA+4 cmpl $0, %eax jz done /* save current pointer */ - mov %esp, UML_CONFIG_STUB_DATA+4 + mov %esp, ASM_STUB_DATA+4 /* skip additional data */ add %eax, %esp @@ -45,7 +46,7 @@ again: done: /* save return value */ - mov %eax, UML_CONFIG_STUB_DATA + mov %eax, ASM_STUB_DATA /* stop */ int3 diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index 2355dc19c46c544db5627b4e6f678903a23a5a0c..b3999cb76bfd2eb004ba5f8be32fec82e38beeeb 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c @@ -6,6 +6,7 @@ #include #include /* The only way I can see to get sigset_t */ #include +#include "as-layout.h" #include "uml-config.h" #include "sysdep/stub.h" #include "sysdep/sigcontext.h" @@ -17,8 +18,7 @@ stub_segv_handler(int sig) struct sigcontext *sc = (struct sigcontext *) (&sig + 1); int pid; - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), - sc); + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); pid = stub_syscall0(__NR_getpid); stub_syscall2(__NR_kill, pid, SIGUSR1); diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S index 03c2797357842f2ad8cc4d61651c1e110d88ddb5..4afe204a6af7acea809aa768facf1c6c11c3eb51 100644 --- a/arch/um/sys-x86_64/stub.S +++ b/arch/um/sys-x86_64/stub.S @@ -1,4 +1,5 @@ #include "uml-config.h" +#include "as-layout.h" .globl syscall_stub .section .__syscall_stub, "x" @@ -7,18 +8,18 @@ syscall_stub: /* We don't have 64-bit constants, so this constructs the address * we need. */ - movq $(UML_CONFIG_STUB_DATA >> 32), %rbx + movq $(ASM_STUB_DATA >> 32), %rbx salq $32, %rbx - movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx + movq $(ASM_STUB_DATA & 0xffffffff), %rcx or %rcx, %rbx movq %rax, (%rbx) int3 .globl batch_syscall_stub batch_syscall_stub: - mov $(UML_CONFIG_STUB_DATA >> 32), %rbx + mov $(ASM_STUB_DATA >> 32), %rbx sal $32, %rbx - mov $(UML_CONFIG_STUB_DATA & 0xffffffff), %rax + mov $(ASM_STUB_DATA & 0xffffffff), %rax or %rax, %rbx /* load pointer to first operation */ mov %rbx, %rsp diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index 652fa34c2cd3d3f0a3f7a8074cfb4ca890e56488..3afb590f007212e2da4e90bad9c8447017b46dd4 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c @@ -6,6 +6,7 @@ #include #include #include +#include "as-layout.h" #include "uml-config.h" #include "sysdep/sigcontext.h" #include "sysdep/faultinfo.h" @@ -33,7 +34,7 @@ stub_segv_handler(int sig) int pid; __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); - GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), + GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), &uc->uc_mcontext); pid = stub_syscall0(__NR_getpid);