summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-03-28 12:48:33 +0000
committerkib <kib@FreeBSD.org>2011-03-28 12:48:33 +0000
commit7b58e8da9bfe66d81078de87b9034549e63400d0 (patch)
tree1b49b5dbf9ca08f0c44a179fe250906fc4f0a6cc
parent13251e8d3fc14cb1113d0f0d3aaeaf20b49e283b (diff)
downloadFreeBSD-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.c53
-rw-r--r--sys/kern/subr_uio.c49
-rw-r--r--sys/sys/uio.h2
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,
OpenPOWER on IntegriCloud