From owner-svn-src-all@freebsd.org Sat Jan 16 07:56:52 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CEC68A83455; Sat, 16 Jan 2016 07:56:52 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A5AF71AD9; Sat, 16 Jan 2016 07:56:52 +0000 (UTC) (envelope-from dchagin@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0G7up3I069634; Sat, 16 Jan 2016 07:56:51 GMT (envelope-from dchagin@FreeBSD.org) Received: (from dchagin@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0G7unjO069616; Sat, 16 Jan 2016 07:56:49 GMT (envelope-from dchagin@FreeBSD.org) Message-Id: <201601160756.u0G7unjO069616@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dchagin set sender to dchagin@FreeBSD.org using -f From: Dmitry Chagin Date: Sat, 16 Jan 2016 07:56:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294136 - in stable/10/sys: amd64/amd64 amd64/linux amd64/linux32 arm/arm compat/ia32 compat/svr4 i386/i386 i386/ibcs2 i386/linux kern mips/mips powerpc/powerpc sparc64/sparc64 sys X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jan 2016 07:56:52 -0000 Author: dchagin Date: Sat Jan 16 07:56:49 2016 New Revision: 294136 URL: https://svnweb.freebsd.org/changeset/base/294136 Log: MFC r293613: Implement vsyscall hack. Prior to 2.13 glibc uses vsyscall instead of vdso. An upcoming linux_base-c6 needs it. Modified: stable/10/sys/amd64/amd64/elf_machdep.c stable/10/sys/amd64/amd64/trap.c stable/10/sys/amd64/linux/linux_sysvec.c stable/10/sys/amd64/linux32/linux32_sysvec.c stable/10/sys/arm/arm/elf_machdep.c stable/10/sys/compat/ia32/ia32_sysvec.c stable/10/sys/compat/svr4/svr4_sysvec.c stable/10/sys/i386/i386/elf_machdep.c stable/10/sys/i386/ibcs2/ibcs2_sysvec.c stable/10/sys/i386/linux/linux_sysvec.c stable/10/sys/kern/imgact_aout.c stable/10/sys/kern/init_main.c stable/10/sys/mips/mips/elf_machdep.c stable/10/sys/mips/mips/freebsd32_machdep.c stable/10/sys/powerpc/powerpc/elf32_machdep.c stable/10/sys/powerpc/powerpc/elf64_machdep.c stable/10/sys/sparc64/sparc64/elf_machdep.c stable/10/sys/sys/sysent.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/amd64/elf_machdep.c ============================================================================== --- stable/10/sys/amd64/amd64/elf_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/amd64/amd64/elf_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -83,6 +83,7 @@ struct sysentvec elf64_freebsd_sysvec = .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); Modified: stable/10/sys/amd64/amd64/trap.c ============================================================================== --- stable/10/sys/amd64/amd64/trap.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/amd64/amd64/trap.c Sat Jan 16 07:56:49 2016 (r294136) @@ -327,6 +327,13 @@ trap(struct trapframe *frame) break; case T_PAGEFLT: /* page fault */ + /* + * Emulator can take care about this trap? + */ + if (*p->p_sysent->sv_trap != NULL && + (*p->p_sysent->sv_trap)(td) == 0) + goto userout; + addr = frame->tf_addr; i = trap_pfault(frame, TRUE); if (i == -1) Modified: stable/10/sys/amd64/linux/linux_sysvec.c ============================================================================== --- stable/10/sys/amd64/linux/linux_sysvec.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/amd64/linux/linux_sysvec.c Sat Jan 16 07:56:49 2016 (r294136) @@ -129,6 +129,7 @@ static void linux_set_syscall_retval(str static int linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa); static void linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack); +static int linux_vsyscall(struct thread *td); /* * Linux syscalls return negative errno's, we do positive and map them @@ -746,6 +747,53 @@ exec_linux_imgact_try(struct image_param return(error); } +#define LINUX_VSYSCALL_START (-10UL << 20) +#define LINUX_VSYSCALL_SZ 1024 + +const unsigned long linux_vsyscall_vector[] = { + LINUX_SYS_gettimeofday, + LINUX_SYS_linux_time, + /* getcpu not implemented */ +}; + +static int +linux_vsyscall(struct thread *td) +{ + struct trapframe *frame; + uint64_t retqaddr; + int code, traced; + int error; + + frame = td->td_frame; + + /* Check %rip for vsyscall area */ + if (__predict_true(frame->tf_rip < LINUX_VSYSCALL_START)) + return (EINVAL); + if ((frame->tf_rip & (LINUX_VSYSCALL_SZ - 1)) != 0) + return (EINVAL); + code = (frame->tf_rip - LINUX_VSYSCALL_START) / LINUX_VSYSCALL_SZ; + if (code >= nitems(linux_vsyscall_vector)) + return (EINVAL); + + /* + * vsyscall called as callq *(%rax), so we must + * use return address from %rsp and also fixup %rsp + */ + error = copyin((void *)frame->tf_rsp, &retqaddr, sizeof(retqaddr)); + if (error) + return (error); + + frame->tf_rip = retqaddr; + frame->tf_rax = linux_vsyscall_vector[code]; + frame->tf_rsp += 8; + + traced = (frame->tf_flags & PSL_T); + + amd64_syscall(td, traced); + + return (0); +} + struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, @@ -781,7 +829,8 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, - .sv_thread_detach = linux_thread_detach + .sv_thread_detach = linux_thread_detach, + .sv_trap = linux_vsyscall, }; static void Modified: stable/10/sys/amd64/linux32/linux32_sysvec.c ============================================================================== --- stable/10/sys/amd64/linux32/linux32_sysvec.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/amd64/linux32/linux32_sysvec.c Sat Jan 16 07:56:49 2016 (r294136) @@ -1043,6 +1043,7 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, + .sv_trap = NULL, }; static void Modified: stable/10/sys/arm/arm/elf_machdep.c ============================================================================== --- stable/10/sys/arm/arm/elf_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/arm/arm/elf_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -80,6 +80,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_syscallnames = syscallnames, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; static Elf32_Brandinfo freebsd_brand_info = { Modified: stable/10/sys/compat/ia32/ia32_sysvec.c ============================================================================== --- stable/10/sys/compat/ia32/ia32_sysvec.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/compat/ia32/ia32_sysvec.c Sat Jan 16 07:56:49 2016 (r294136) @@ -140,6 +140,7 @@ struct sysentvec ia32_freebsd_sysvec = { .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec); Modified: stable/10/sys/compat/svr4/svr4_sysvec.c ============================================================================== --- stable/10/sys/compat/svr4/svr4_sysvec.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/compat/svr4/svr4_sysvec.c Sat Jan 16 07:56:49 2016 (r294136) @@ -197,6 +197,7 @@ struct sysentvec svr4_sysvec = { .sv_syscallnames = NULL, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; const char svr4_emul_path[] = "/compat/svr4"; Modified: stable/10/sys/i386/i386/elf_machdep.c ============================================================================== --- stable/10/sys/i386/i386/elf_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/i386/i386/elf_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -89,6 +89,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); Modified: stable/10/sys/i386/ibcs2/ibcs2_sysvec.c ============================================================================== --- stable/10/sys/i386/ibcs2/ibcs2_sysvec.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/i386/ibcs2/ibcs2_sysvec.c Sat Jan 16 07:56:49 2016 (r294136) @@ -90,6 +90,7 @@ struct sysentvec ibcs2_svr3_sysvec = { .sv_syscallnames = NULL, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; static int Modified: stable/10/sys/i386/linux/linux_sysvec.c ============================================================================== --- stable/10/sys/i386/linux/linux_sysvec.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/i386/linux/linux_sysvec.c Sat Jan 16 07:56:49 2016 (r294136) @@ -988,6 +988,7 @@ struct sysentvec linux_sysvec = { .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, + .sv_trap = NULL, }; INIT_SYSENTVEC(aout_sysvec, &linux_sysvec); @@ -1027,6 +1028,7 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, .sv_thread_detach = linux_thread_detach, + .sv_trap = NULL, }; static void Modified: stable/10/sys/kern/imgact_aout.c ============================================================================== --- stable/10/sys/kern/imgact_aout.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/kern/imgact_aout.c Sat Jan 16 07:56:49 2016 (r294136) @@ -100,6 +100,7 @@ struct sysentvec aout_sysvec = { .sv_syscallnames = syscallnames, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; #elif defined(__amd64__) Modified: stable/10/sys/kern/init_main.c ============================================================================== --- stable/10/sys/kern/init_main.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/kern/init_main.c Sat Jan 16 07:56:49 2016 (r294136) @@ -415,6 +415,7 @@ struct sysentvec null_sysvec = { .sv_syscallnames = NULL, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; /* Modified: stable/10/sys/mips/mips/elf_machdep.c ============================================================================== --- stable/10/sys/mips/mips/elf_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/mips/mips/elf_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -84,6 +84,7 @@ struct sysentvec elf64_freebsd_sysvec = .sv_syscallnames = syscallnames, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; static Elf64_Brandinfo freebsd_brand_info = { @@ -141,6 +142,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_syscallnames = syscallnames, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; static Elf32_Brandinfo freebsd_brand_info = { Modified: stable/10/sys/mips/mips/freebsd32_machdep.c ============================================================================== --- stable/10/sys/mips/mips/freebsd32_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/mips/mips/freebsd32_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -107,6 +107,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_syscallnames = freebsd32_syscallnames, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); Modified: stable/10/sys/powerpc/powerpc/elf32_machdep.c ============================================================================== --- stable/10/sys/powerpc/powerpc/elf32_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/powerpc/powerpc/elf32_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -108,6 +108,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); Modified: stable/10/sys/powerpc/powerpc/elf64_machdep.c ============================================================================== --- stable/10/sys/powerpc/powerpc/elf64_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/powerpc/powerpc/elf64_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -84,6 +84,7 @@ struct sysentvec elf64_freebsd_sysvec = .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); Modified: stable/10/sys/sparc64/sparc64/elf_machdep.c ============================================================================== --- stable/10/sys/sparc64/sparc64/elf_machdep.c Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/sparc64/sparc64/elf_machdep.c Sat Jan 16 07:56:49 2016 (r294136) @@ -88,6 +88,7 @@ static struct sysentvec elf64_freebsd_sy .sv_syscallnames = syscallnames, .sv_schedtail = NULL, .sv_thread_detach = NULL, + .sv_trap = NULL, }; static Elf64_Brandinfo freebsd_brand_info = { Modified: stable/10/sys/sys/sysent.h ============================================================================== --- stable/10/sys/sys/sysent.h Sat Jan 16 07:46:25 2016 (r294135) +++ stable/10/sys/sys/sysent.h Sat Jan 16 07:56:49 2016 (r294136) @@ -131,6 +131,7 @@ struct sysentvec { void *sv_shared_page_obj; void (*sv_schedtail)(struct thread *); void (*sv_thread_detach)(struct thread *); + int (*sv_trap)(struct thread *); }; #define SV_ILP32 0x000100