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>