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
This commit is contained in:
parent
8eb95e9629
commit
15d1cdd161
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user