diff options
author | dchagin <dchagin@FreeBSD.org> | 2011-03-13 14:58:02 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2011-03-13 14:58:02 +0000 |
commit | 15d1cdd161986839d5cebb42a4e2295aa11bbaca (patch) | |
tree | 2cdc92ede096878311ecd5f49a49943453092d6e | |
parent | 8eb95e96298f4997fb6abe947fea52b360e32704 (diff) | |
download | FreeBSD-src-15d1cdd161986839d5cebb42a4e2295aa11bbaca.zip FreeBSD-src-15d1cdd161986839d5cebb42a4e2295aa11bbaca.tar.gz |
Enable shared page use for amd64/linux32 and i386/linux binaries.
Move signal trampoline code from the top of the stack to the shared page.
MFC after: 2 Weeks
-rw-r--r-- | sys/amd64/linux32/linux.h | 5 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_sysvec.c | 26 | ||||
-rw-r--r-- | sys/i386/linux/linux.h | 3 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 36 |
4 files changed, 36 insertions, 34 deletions
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 555a912..4a5ec01 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -47,7 +47,10 @@ extern u_char linux_debug_map[]; MALLOC_DECLARE(M_LINUX); #endif -#define LINUX32_USRSTACK ((1ul << 32) - PAGE_SIZE) +#define LINUX32_MAXUSER ((1ul << 32) - PAGE_SIZE) +#define LINUX32_SHAREDPAGE (LINUX32_MAXUSER - PAGE_SIZE) +#define LINUX32_USRSTACK LINUX32_SHAREDPAGE + /* XXX 16 = sizeof(linux32_ps_strings) */ #define LINUX32_PS_STRINGS (LINUX32_USRSTACK - 16) #define LINUX32_MAXDSIZ (512 * 1024 * 1024) /* 512MB */ diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 12153ee..c42f4d4 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -411,8 +411,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); - regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode) + - linux_sznonrtsigcode; + regs->tf_rip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; @@ -535,7 +534,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); - regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode); + regs->tf_rip = p->p_sysent->sv_sigcode_base; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; @@ -890,21 +889,15 @@ linux_copyout_strings(struct image_params *imgp) * Also deal with signal trampoline code for this exec type. */ arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS; - destp = (caddr_t)arginfo - linux_szsigcode - SPARE_USRSPACE - - linux_szplatform - roundup((ARG_MAX - imgp->args->stringspace), + destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform - + roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); /* - * install sigcode - */ - copyout(imgp->proc->p_sysent->sv_sigcode, - ((caddr_t)arginfo - linux_szsigcode), linux_szsigcode); - - /* * Install LINUX_PLATFORM */ - copyout(linux_platform, ((caddr_t)arginfo - linux_szsigcode - - linux_szplatform), linux_szplatform); + copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform), + linux_szplatform); /* * If we have a valid auxargs ptr, prepare some room @@ -1050,7 +1043,7 @@ struct sysentvec elf_linux_sysvec = { .sv_minsigstksz = LINUX_MINSIGSTKSZ, .sv_pagesize = PAGE_SIZE, .sv_minuser = VM_MIN_ADDRESS, - .sv_maxuser = LINUX32_USRSTACK, + .sv_maxuser = LINUX32_MAXUSER, .sv_usrstack = LINUX32_USRSTACK, .sv_psstrings = LINUX32_PS_STRINGS, .sv_stackprot = VM_PROT_ALL, @@ -1058,12 +1051,15 @@ struct sysentvec elf_linux_sysvec = { .sv_setregs = exec_linux_setregs, .sv_fixlimit = linux32_fixlimit, .sv_maxssiz = &linux32_maxssiz, - .sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32, + .sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP, .sv_set_syscall_retval = cpu_set_syscall_retval, .sv_fetch_syscall_args = linux32_fetch_syscall_args, .sv_syscallnames = NULL, + .sv_shared_page_base = LINUX32_SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, }; +INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); static char GNU_ABI_VENDOR[] = "GNU"; static int GNULINUX_ABI_DESC = 0; diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index 78958db..d02614b 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -47,6 +47,9 @@ extern u_char linux_debug_map[]; MALLOC_DECLARE(M_LINUX); #endif +#define LINUX_SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE) +#define LINUX_USRSTACK LINUX_SHAREDPAGE + #define PTRIN(v) (void *)(v) #define PTROUT(v) (l_uintptr_t)(v) diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 62901d4..f803d7c 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -90,6 +90,8 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); #define LINUX_SYS_linux_rt_sendsig 0 #define LINUX_SYS_linux_sendsig 0 +#define LINUX_PS_STRINGS (LINUX_USRSTACK - sizeof(struct ps_strings)) + extern char linux_sigcode[]; extern int linux_szsigcode; @@ -308,21 +310,14 @@ linux_copyout_strings(struct image_params *imgp) */ p = imgp->proc; arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; - destp = (caddr_t)arginfo - linux_szsigcode - SPARE_USRSPACE - - linux_szplatform - roundup((ARG_MAX - imgp->args->stringspace), - sizeof(char *)); - - /* - * install sigcode - */ - copyout(p->p_sysent->sv_sigcode, ((caddr_t)arginfo - - linux_szsigcode), linux_szsigcode); + destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform - + roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); /* * install LINUX_PLATFORM */ - copyout(linux_platform, ((caddr_t)arginfo - linux_szsigcode - - linux_szplatform), linux_szplatform); + copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform), + linux_szplatform); /* * If we have a valid auxargs ptr, prepare some room @@ -520,8 +515,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_esp = (int)fp; - regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) + - linux_sznonrtsigcode; + regs->tf_eip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode; regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; @@ -640,7 +634,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) * Build context to run handler in. */ regs->tf_esp = (int)fp; - regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); + regs->tf_eip = p->p_sysent->sv_sigcode_base; regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; @@ -986,7 +980,7 @@ struct sysentvec linux_sysvec = { .sv_pagesize = PAGE_SIZE, .sv_minuser = VM_MIN_ADDRESS, .sv_maxuser = VM_MAXUSER_ADDRESS, - .sv_usrstack = USRSTACK, + .sv_usrstack = LINUX_USRSTACK, .sv_psstrings = PS_STRINGS, .sv_stackprot = VM_PROT_ALL, .sv_copyout_strings = exec_copyout_strings, @@ -997,8 +991,11 @@ struct sysentvec linux_sysvec = { .sv_set_syscall_retval = cpu_set_syscall_retval, .sv_fetch_syscall_args = linux_fetch_syscall_args, .sv_syscallnames = NULL, + .sv_shared_page_base = LINUX_SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, }; +INIT_SYSENTVEC(aout_sysvec, &linux_sysvec); struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, @@ -1021,19 +1018,22 @@ struct sysentvec elf_linux_sysvec = { .sv_pagesize = PAGE_SIZE, .sv_minuser = VM_MIN_ADDRESS, .sv_maxuser = VM_MAXUSER_ADDRESS, - .sv_usrstack = USRSTACK, - .sv_psstrings = PS_STRINGS, + .sv_usrstack = LINUX_USRSTACK, + .sv_psstrings = LINUX_PS_STRINGS, .sv_stackprot = VM_PROT_ALL, .sv_copyout_strings = linux_copyout_strings, .sv_setregs = exec_linux_setregs, .sv_fixlimit = NULL, .sv_maxssiz = NULL, - .sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32, + .sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP, .sv_set_syscall_retval = cpu_set_syscall_retval, .sv_fetch_syscall_args = linux_fetch_syscall_args, .sv_syscallnames = NULL, + .sv_shared_page_base = LINUX_SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, }; +INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); static char GNU_ABI_VENDOR[] = "GNU"; static int GNULINUX_ABI_DESC = 0; |