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
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to