svn commit: r219609 - in head/sys: amd64/linux32 i386/linux

Dmitry Chagin dchagin at FreeBSD.org
Sun Mar 13 14:58:02 UTC 2011


Author: dchagin
Date: Sun Mar 13 14:58:02 2011
New Revision: 219609
URL: http://svn.freebsd.org/changeset/base/219609

Log:
  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

Modified:
  head/sys/amd64/linux32/linux.h
  head/sys/amd64/linux32/linux32_sysvec.c
  head/sys/i386/linux/linux.h
  head/sys/i386/linux/linux_sysvec.c

Modified: head/sys/amd64/linux32/linux.h
==============================================================================
--- head/sys/amd64/linux32/linux.h	Sun Mar 13 13:42:43 2011	(r219608)
+++ head/sys/amd64/linux32/linux.h	Sun Mar 13 14:58:02 2011	(r219609)
@@ -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 */

Modified: head/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- head/sys/amd64/linux32/linux32_sysvec.c	Sun Mar 13 13:42:43 2011	(r219608)
+++ head/sys/amd64/linux32/linux32_sysvec.c	Sun Mar 13 14:58:02 2011	(r219609)
@@ -411,8 +411,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo
 	 * 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 
 	 * 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_param
 	 * 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;

Modified: head/sys/i386/linux/linux.h
==============================================================================
--- head/sys/i386/linux/linux.h	Sun Mar 13 13:42:43 2011	(r219608)
+++ head/sys/i386/linux/linux.h	Sun Mar 13 14:58:02 2011	(r219609)
@@ -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)
 

Modified: head/sys/i386/linux/linux_sysvec.c
==============================================================================
--- head/sys/i386/linux/linux_sysvec.c	Sun Mar 13 13:42:43 2011	(r219608)
+++ head/sys/i386/linux/linux_sysvec.c	Sun Mar 13 14:58:02 2011	(r219609)
@@ -90,6 +90,8 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux m
 #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_param
 	 */
 	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
 	 * 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 
 	 * 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;


More information about the svn-src-all mailing list