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
 
 
 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
 
 # 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
 
 #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 {
 extern void (*sig_info[])(int, struct uml_pt_regs *);
 
 #endif
+
+#endif
 
 #include <sys/mman.h>
 #include <asm/ptrace.h>
 #include <asm/unistd.h>
+#include "as-layout.h"
 #include "stub-data.h"
 #include "kern_constants.h"
 #include "uml-config.h"
 {
        __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");
 }
 
 
 #include <sys/mman.h>
 #include <asm/unistd.h>
 #include <sysdep/ptrace_user.h>
+#include "as-layout.h"
 #include "stub-data.h"
 #include "kern_constants.h"
 #include "uml-config.h"
 {
        __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" );
 }
 
 
 #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"
 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);
 
 #include <sys/time.h>
 #include <asm/unistd.h>
 #include <asm/page.h>
+#include "as-layout.h"
 #include "ptrace_user.h"
 #include "skas.h"
 #include "stub-data.h"
 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;
 
 
 #include "linux/sched.h"
 #include "asm/pgalloc.h"
 #include "asm/pgtable.h"
+#include "as-layout.h"
 #include "os.h"
 #include "skas.h"
 
                 */
                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;
 
 
                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;
 }
 
 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);
 }
        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);
 }
 
 
 
        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;
 }
 
 #include <sys/mman.h>
 #include "init.h"
 #include "kern_constants.h"
+#include "as-layout.h"
 #include "mm_id.h"
 #include "os.h"
 #include "proc_mm.h"
 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;
        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]);
        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;
 }
 
                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);
                        }
                }
        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);
 {
        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;
         * 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);
 
 
 #include "uml-config.h"
+#include "as-layout.h"
 
        .globl syscall_stub
 .section .__syscall_stub, "x"
        .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 */
 
        /* 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
 
 done:
        /* save return value */
-       mov     %eax, UML_CONFIG_STUB_DATA
+       mov     %eax, ASM_STUB_DATA
 
        /* stop */
        int3
 
 #include <signal.h>
 #include <sys/select.h> /* The only way I can see to get sigset_t */
 #include <asm/unistd.h>
+#include "as-layout.h"
 #include "uml-config.h"
 #include "sysdep/stub.h"
 #include "sysdep/sigcontext.h"
        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);
 
 #include "uml-config.h"
+#include "as-layout.h"
 
        .globl syscall_stub
 .section .__syscall_stub, "x"
        /* 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
 
 #include <stddef.h>
 #include <signal.h>
 #include <asm/unistd.h>
+#include "as-layout.h"
 #include "uml-config.h"
 #include "sysdep/sigcontext.h"
 #include "sysdep/faultinfo.h"
         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);