Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/linux/arch/amd64 Make the arch_prctl system call ...



details:   https://anonhg.NetBSD.org/src/rev/53049a45aaae
branches:  trunk
changeset: 580918:53049a45aaae
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Sun May 15 21:43:08 2005 +0000

description:
Make the arch_prctl system call use the saved %gs and %fs mechanism.

diffstat:

 sys/compat/linux/arch/amd64/linux_machdep.c |  63 +++++++++++++++++-----------
 1 files changed, 39 insertions(+), 24 deletions(-)

diffs (112 lines):

diff -r 698727f2c9c1 -r 53049a45aaae sys/compat/linux/arch/amd64/linux_machdep.c
--- a/sys/compat/linux/arch/amd64/linux_machdep.c       Sun May 15 21:42:01 2005 +0000
+++ b/sys/compat/linux/arch/amd64/linux_machdep.c       Sun May 15 21:43:08 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_machdep.c,v 1.1 2005/05/03 16:26:30 manu Exp $ */
+/*     $NetBSD: linux_machdep.c,v 1.2 2005/05/15 21:43:08 fvdl Exp $ */
 
 /*-
  * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.1 2005/05/03 16:26:30 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.2 2005/05/15 21:43:08 fvdl Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -49,6 +49,8 @@
 #include <machine/pcb.h>
 #include <machine/fpu.h>
 #include <machine/mcontext.h>
+#include <machine/specialreg.h>
+#include <machine/vmparam.h>
 
 #include <compat/linux/common/linux_signal.h>
 #include <compat/linux/common/linux_errno.h>
@@ -454,41 +456,55 @@
                syscallarg(int) code;
                syscallarg(unsigned long) addr;
        } */ *uap = v;
-       ucontext_t uctx;
+       struct pcb *pcb = &l->l_addr->u_pcb;
+       struct trapframe *tf = l->l_md.md_regs;
        int error;
-
-       getucontext(l, &uctx);
+       uint64_t taddr;
 
        switch(SCARG(uap, code)) {
        case LINUX_ARCH_SET_GS:
-#ifndef tmp_hack
-               return 0; /* XXX */
-#endif
-               uctx.uc_mcontext.__gregs[_REG_GS] = (u_int64_t)SCARG(uap, addr);
-               if ((error = setucontext(l, &uctx)) != 0)
-                       return error;
+               taddr = SCARG(uap, addr);
+               if (taddr >= VM_MAXUSER_ADDRESS)
+                       return EINVAL;
+               pcb->pcb_gs = taddr;
+               pcb->pcb_flags |= PCB_GS64;
+               if (l == curlwp)
+                       wrmsr(MSR_KERNELGSBASE, taddr);
                break;
 
        case LINUX_ARCH_GET_GS:
-               if ((error = copyout(&uctx.uc_mcontext.__gregs[_REG_GS], 
-                   (char *)SCARG(uap, addr), 
-                   sizeof(uctx.uc_mcontext.__gregs[_REG_GS]))) != 0)
+               if (pcb->pcb_flags & PCB_GS64)
+                       taddr = pcb->pcb_gs;
+               else {
+                       error = memseg_baseaddr(l, tf->tf_fs, NULL, 0, &taddr);
+                       if (error != 0)
+                               return error;
+               }
+               error = copyout(&taddr, (char *)SCARG(uap, addr), 8);
+               if (error != 0)
                        return error;
                break;
 
        case LINUX_ARCH_SET_FS:
-#ifndef tmp_hack
-               return 0; /* XXX */
-#endif
-               uctx.uc_mcontext.__gregs[_REG_FS] = (u_int64_t)SCARG(uap, addr);
-               if ((error = setucontext(l, &uctx)) != 0)
-                       return error;
+               taddr = SCARG(uap, addr);
+               if (taddr >= VM_MAXUSER_ADDRESS)
+                       return EINVAL;
+               pcb->pcb_fs = taddr;
+               pcb->pcb_flags |= PCB_FS64;
+               if (l == curlwp)
+                       wrmsr(MSR_FSBASE, taddr);
                break;
 
        case LINUX_ARCH_GET_FS:
-               if ((error = copyout(&uctx.uc_mcontext.__gregs[_REG_FS], 
-                   (char *)SCARG(uap, addr),
-                   sizeof(uctx.uc_mcontext.__gregs[_REG_FS]))) != 0)
+               if (pcb->pcb_flags & PCB_FS64)
+                       taddr = pcb->pcb_fs;
+               else {
+                       error = memseg_baseaddr(l, tf->tf_fs, NULL, 0, &taddr);
+                       if (error != 0)
+                               return error;
+               }
+               error = copyout(&taddr, (char *)SCARG(uap, addr), 8);
+               if (error != 0)
                        return error;
                break;
 
@@ -498,7 +514,6 @@
                    SCARG(uap, code));
 #endif
                return EINVAL;
-               break;
        }
 
        return 0;



Home | Main Index | Thread Index | Old Index