diff options
author | kib <kib@FreeBSD.org> | 2011-03-28 12:48:33 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-03-28 12:48:33 +0000 |
commit | 7b58e8da9bfe66d81078de87b9034549e63400d0 (patch) | |
tree | 1b49b5dbf9ca08f0c44a179fe250906fc4f0a6cc | |
parent | 13251e8d3fc14cb1113d0f0d3aaeaf20b49e283b (diff) | |
download | FreeBSD-src-7b58e8da9bfe66d81078de87b9034549e63400d0.zip FreeBSD-src-7b58e8da9bfe66d81078de87b9034549e63400d0.tar.gz |
Promote ksyms_map() and ksyms_unmap() to general facility
copyout_map() and copyout_unmap() interfaces.
Submitted by: John Wehle <john feith com>, nox
MFC after: 2 weeks
-rw-r--r-- | sys/dev/ksyms/ksyms.c | 53 | ||||
-rw-r--r-- | sys/kern/subr_uio.c | 49 | ||||
-rw-r--r-- | sys/sys/uio.h | 2 |
3 files changed, 54 insertions, 50 deletions
diff --git a/sys/dev/ksyms/ksyms.c b/sys/dev/ksyms/ksyms.c index 3a1adca..38e71a3 100644 --- a/sys/dev/ksyms/ksyms.c +++ b/sys/dev/ksyms/ksyms.c @@ -360,53 +360,6 @@ ksyms_snapshot(struct tsizes *ts, vm_offset_t uaddr, size_t resid) return (error); } -/* - * Map some anonymous memory in user space of size sz, rounded up to the page - * boundary. - */ -static int -ksyms_map(struct thread *td, vm_offset_t *addr, size_t sz) -{ - struct vmspace *vms = td->td_proc->p_vmspace; - int error; - vm_size_t size; - - - /* - * Map somewhere after heap in process memory. - */ - PROC_LOCK(td->td_proc); - *addr = round_page((vm_offset_t)vms->vm_daddr + - lim_max(td->td_proc, RLIMIT_DATA)); - PROC_UNLOCK(td->td_proc); - - /* round size up to page boundry */ - size = (vm_size_t) round_page(sz); - - error = vm_mmap(&vms->vm_map, addr, size, PROT_READ | PROT_WRITE, - VM_PROT_ALL, MAP_PRIVATE | MAP_ANON, OBJT_DEFAULT, NULL, 0); - - return (error); -} - -/* - * Unmap memory in user space. - */ -static int -ksyms_unmap(struct thread *td, vm_offset_t addr, size_t sz) -{ - vm_map_t map; - vm_size_t size; - - map = &td->td_proc->p_vmspace->vm_map; - size = (vm_size_t) round_page(sz); - - if (!vm_map_remove(map, addr, addr + size)) - return (EINVAL); - - return (0); -} - static void ksyms_cdevpriv_dtr(void *data) { @@ -475,7 +428,7 @@ ksyms_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) total_elf_sz = sizeof(struct ksyms_hdr) + ts.ts_symsz + ts.ts_strsz; - error = ksyms_map(td, &(sc->sc_uaddr), + error = copyout_map(td, &(sc->sc_uaddr), (vm_size_t) total_elf_sz); if (error) break; @@ -488,7 +441,7 @@ ksyms_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) } /* Snapshot failed, unmap the memory and try again */ - (void) ksyms_unmap(td, sc->sc_uaddr, sc->sc_usize); + (void) copyout_unmap(td, sc->sc_uaddr, sc->sc_usize); } failed: @@ -624,7 +577,7 @@ ksyms_close(struct cdev *dev, int flags __unused, int fmt __unused, return (error); /* Unmap the buffer from the process address space. */ - error = ksyms_unmap(td, sc->sc_uaddr, sc->sc_usize); + error = copyout_unmap(td, sc->sc_uaddr, sc->sc_usize); devfs_clear_cdevpriv(); diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index 77156f1..8304aea 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -44,13 +44,16 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/limits.h> #include <sys/lock.h> +#include <sys/mman.h> #include <sys/mutex.h> #include <sys/proc.h> +#include <sys/resourcevar.h> #include <sys/sched.h> #include <sys/sysctl.h> #include <sys/vnode.h> #include <vm/vm.h> +#include <vm/vm_extern.h> #include <vm/vm_page.h> #include <vm/vm_map.h> #ifdef ZERO_COPY_SOCKETS @@ -457,3 +460,49 @@ cloneuio(struct uio *uiop) bcopy(uiop->uio_iov, uio->uio_iov, iovlen); return (uio); } + +/* + * Map some anonymous memory in user space of size sz, rounded up to the page + * boundary. + */ +int +copyout_map(struct thread *td, vm_offset_t *addr, size_t sz) +{ + struct vmspace *vms = td->td_proc->p_vmspace; + int error; + vm_size_t size; + + /* + * Map somewhere after heap in process memory. + */ + PROC_LOCK(td->td_proc); + *addr = round_page((vm_offset_t)vms->vm_daddr + + lim_max(td->td_proc, RLIMIT_DATA)); + PROC_UNLOCK(td->td_proc); + + /* round size up to page boundry */ + size = (vm_size_t) round_page(sz); + + error = vm_mmap(&vms->vm_map, addr, size, PROT_READ | PROT_WRITE, + VM_PROT_ALL, MAP_PRIVATE | MAP_ANON, OBJT_DEFAULT, NULL, 0); + + return (error); +} + +/* + * Unmap memory in user space. + */ +int +copyout_unmap(struct thread *td, vm_offset_t addr, size_t sz) +{ + vm_map_t map; + vm_size_t size; + + map = &td->td_proc->p_vmspace->vm_map; + size = (vm_size_t) round_page(sz); + + if (!vm_map_remove(map, addr, addr + size)) + return (EINVAL); + + return (0); +} diff --git a/sys/sys/uio.h b/sys/sys/uio.h index a9aecfa..d7fa124 100644 --- a/sys/sys/uio.h +++ b/sys/sys/uio.h @@ -94,6 +94,8 @@ int copyiniov(struct iovec *iovp, u_int iovcnt, struct iovec **iov, int copyinstrfrom(const void * __restrict src, void * __restrict dst, size_t len, size_t * __restrict copied, int seg); int copyinuio(struct iovec *iovp, u_int iovcnt, struct uio **uiop); +int copyout_map(struct thread *td, vm_offset_t *addr, size_t sz); +int copyout_unmap(struct thread *td, vm_offset_t addr, size_t sz); int uiomove(void *cp, int n, struct uio *uio); int uiomove_frombuf(void *buf, int buflen, struct uio *uio); int uiomove_fromphys(struct vm_page *ma[], vm_offset_t offset, int n, |