Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jun 2018 14:45:14 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335702 - in head/sys: compat/linux sys vm
Message-ID:  <201806271445.w5REjEjM005161@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Wed Jun 27 14:45:13 2018
New Revision: 335702
URL: https://svnweb.freebsd.org/changeset/base/335702

Log:
  Split kern_break from sys_break and use it in linuxulator
  
  Previously the linuxulator's linux_brk invoked the FreeBSD sys_break
  syscall implementation directly.  Instead, move the bulk of the existing
  implementation to kern_break, and call that from both sys_break and
  linux_brk.
  
  This also addresses a minor bug in linux_brk in that we now return the
  actual (rounded up) break address, rather than the requested value.
  
  Reviewed by:	brooks (earlier version)
  Sponsored by:	Turing Robotic Industries
  Differential Revision:	https://reviews.freebsd.org/D16019

Modified:
  head/sys/compat/linux/linux_misc.c
  head/sys/sys/syscallsubr.h
  head/sys/vm/vm_unix.c

Modified: head/sys/compat/linux/linux_misc.c
==============================================================================
--- head/sys/compat/linux/linux_misc.c	Wed Jun 27 14:29:13 2018	(r335701)
+++ head/sys/compat/linux/linux_misc.c	Wed Jun 27 14:45:13 2018	(r335702)
@@ -232,22 +232,18 @@ int
 linux_brk(struct thread *td, struct linux_brk_args *args)
 {
 	struct vmspace *vm = td->td_proc->p_vmspace;
-	vm_offset_t new, old;
-	struct break_args /* {
-		char * nsize;
-	} */ tmp;
+	uintptr_t new, old;
 
 #ifdef DEBUG
 	if (ldebug(brk))
 		printf(ARGS(brk, "%p"), (void *)(uintptr_t)args->dsend);
 #endif
-	old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize);
-	new = (vm_offset_t)args->dsend;
-	tmp.nsize = (char *)new;
-	if (((caddr_t)new > vm->vm_daddr) && !sys_break(td, &tmp))
-		td->td_retval[0] = (long)new;
+	old = (uintptr_t)vm->vm_daddr + ctob(vm->vm_dsize);
+	new = (uintptr_t)args->dsend;
+	if ((caddr_t)new > vm->vm_daddr && !kern_break(td, &new))
+		td->td_retval[0] = (register_t)new;
 	else
-		td->td_retval[0] = (long)old;
+		td->td_retval[0] = (register_t)old;
 
 	return (0);
 }

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h	Wed Jun 27 14:29:13 2018	(r335701)
+++ head/sys/sys/syscallsubr.h	Wed Jun 27 14:45:13 2018	(r335702)
@@ -76,6 +76,7 @@ int	kern_adjtime(struct thread *td, struct timeval *de
 int	kern_alternate_path(struct thread *td, const char *prefix, const char *path,
 	    enum uio_seg pathseg, char **pathbuf, int create, int dirfd);
 int	kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa);
+int	kern_break(struct thread *td, uintptr_t *addr);
 int	kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds,
 	    size_t ncmds);
 int	kern_cap_rights_limit(struct thread *td, int fd, cap_rights_t *rights);

Modified: head/sys/vm/vm_unix.c
==============================================================================
--- head/sys/vm/vm_unix.c	Wed Jun 27 14:29:13 2018	(r335701)
+++ head/sys/vm/vm_unix.c	Wed Jun 27 14:45:13 2018	(r335702)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/racct.h>
 #include <sys/resourcevar.h>
+#include <sys/syscallsubr.h>
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/systm.h>
@@ -69,6 +70,22 @@ int
 sys_break(struct thread *td, struct break_args *uap)
 {
 #if !defined(__aarch64__) && !defined(__riscv__)
+	uintptr_t addr;
+	int error;
+
+	addr = (uintptr_t)uap->nsize;
+	error = kern_break(td, &addr);
+	if (error == 0)
+		td->td_retval[0] = addr;
+	return (error);
+#else /* defined(__aarch64__) || defined(__riscv__) */
+	return (ENOSYS);
+#endif /* defined(__aarch64__) || defined(__riscv__) */
+}
+
+int
+kern_break(struct thread *td, uintptr_t *addr)
+{
 	struct vmspace *vm = td->td_proc->p_vmspace;
 	vm_map_t map = &vm->vm_map;
 	vm_offset_t new, old, base;
@@ -82,7 +99,7 @@ sys_break(struct thread *td, struct break_args *uap)
 	vmemlim = lim_cur(td, RLIMIT_VMEM);
 
 	do_map_wirefuture = FALSE;
-	new = round_page((vm_offset_t)uap->nsize);
+	new = round_page(*addr);
 	vm_map_lock(map);
 
 	base = round_page((vm_offset_t) vm->vm_daddr);
@@ -226,12 +243,9 @@ done:
 		    VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES);
 
 	if (error == 0)
-		td->td_retval[0] = new;
+		*addr = new;
 
 	return (error);
-#else /* defined(__aarch64__) || defined(__riscv__) */
-	return (ENOSYS);
-#endif /* defined(__aarch64__) || defined(__riscv__) */
 }
 
 #ifdef COMPAT_FREEBSD11



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