svn commit: r335702 - in head/sys: compat/linux sys vm
Ed Maste
emaste at FreeBSD.org
Wed Jun 27 14:45:15 UTC 2018
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
More information about the svn-src-head
mailing list