Author: dchagin
Date: Sun Mar 24 14:02:57 2019
New Revision: 345468
URL: https://svnweb.freebsd.org/changeset/base/345468

Log:
  Revert r313993.
  AMD64_SET_**BASE expects a pointer to a pointer, we just passing in the 
pointer value itself.
  
  Set PCB_FULL_IRET for doreti to restore %fs, %gs and its correspondig base.
  
  PR:           225105
  Reported by:  trasz@
  MFC after:    1 month

Modified:
  head/sys/amd64/linux/linux_machdep.c

Modified: head/sys/amd64/linux/linux_machdep.c
==============================================================================
--- head/sys/amd64/linux/linux_machdep.c        Sun Mar 24 12:13:05 2019        
(r345467)
+++ head/sys/amd64/linux/linux_machdep.c        Sun Mar 24 14:02:57 2019        
(r345468)
@@ -228,35 +228,38 @@ linux_sigaltstack(struct thread *td, struct linux_siga
 int
 linux_arch_prctl(struct thread *td, struct linux_arch_prctl_args *args)
 {
+       struct pcb *pcb;
        int error;
-       struct sysarch_args bsd_args;
 
+       pcb = td->td_pcb;
        LINUX_CTR2(arch_prctl, "0x%x, %p", args->code, args->addr);
 
        switch (args->code) {
        case LINUX_ARCH_SET_GS:
-               bsd_args.op = AMD64_SET_GSBASE;
-               bsd_args.parms = (void *)args->addr;
-               error = sysarch(td, &bsd_args);
-               if (error == EINVAL)
+               if (args->addr < VM_MAXUSER_ADDRESS) {
+                       set_pcb_flags(pcb, PCB_FULL_IRET);
+                       pcb->pcb_gsbase = args->addr;
+                       td->td_frame->tf_gs = _ugssel;
+                       error = 0;
+               } else
                        error = EPERM;
                break;
        case LINUX_ARCH_SET_FS:
-               bsd_args.op = AMD64_SET_FSBASE;
-               bsd_args.parms = (void *)args->addr;
-               error = sysarch(td, &bsd_args);
-               if (error == EINVAL)
+               if (args->addr < VM_MAXUSER_ADDRESS) {
+                       set_pcb_flags(pcb, PCB_FULL_IRET);
+                       pcb->pcb_fsbase = args->addr;
+                       td->td_frame->tf_fs = _ufssel;
+                       error = 0;
+               } else
                        error = EPERM;
                break;
        case LINUX_ARCH_GET_FS:
-               bsd_args.op = AMD64_GET_FSBASE;
-               bsd_args.parms = (void *)args->addr;
-               error = sysarch(td, &bsd_args);
+               error = copyout(&pcb->pcb_fsbase, PTRIN(args->addr),
+                   sizeof(args->addr));
                break;
        case LINUX_ARCH_GET_GS:
-               bsd_args.op = AMD64_GET_GSBASE;
-               bsd_args.parms = (void *)args->addr;
-               error = sysarch(td, &bsd_args);
+               error = copyout(&pcb->pcb_gsbase, PTRIN(args->addr),
+                   sizeof(args->addr));
                break;
        default:
                error = EINVAL;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to