Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Apr 2019 14:30:26 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r346841 - stable/12/sys/amd64/linux
Message-ID:  <201904281430.x3SEUQcW050512@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Sun Apr 28 14:30:25 2019
New Revision: 346841
URL: https://svnweb.freebsd.org/changeset/base/346841

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

Modified:
  stable/12/sys/amd64/linux/linux_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/amd64/linux/linux_machdep.c
==============================================================================
--- stable/12/sys/amd64/linux/linux_machdep.c	Sun Apr 28 14:20:29 2019	(r346840)
+++ stable/12/sys/amd64/linux/linux_machdep.c	Sun Apr 28 14:30:25 2019	(r346841)
@@ -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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904281430.x3SEUQcW050512>