aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2021-03-20 17:15:50 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2021-03-23 21:18:31 +0000
commit610706f5e71a2805688cb3c13e8605675b58802c (patch)
tree31e89dd25fb582a1c8c64c6d6f3e7074a11e78f3
parent961e7887b9bad9dd446a2289f3e5266ad2d122ef (diff)
downloadsrc-610706f5e71a2805688cb3c13e8605675b58802c.tar.gz
src-610706f5e71a2805688cb3c13e8605675b58802c.zip
netmap: fix issues in nm_os_extmem_create()
- Call vm_object_reference() before vm_map_lookup_done(). - Use vm_mmap_to_errno() to convert vm_map_* return values to errno. - Fix memory leak of e->obj. Reported by: markj Reviewed by: markj MFC after: 1 week (cherry picked from commit ee7ffaa2e6e08b63efb4673610875d40964d5058)
-rw-r--r--sys/dev/netmap/netmap_freebsd.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index ea9f4252a562..28f753b06f8c 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -663,6 +663,7 @@ nm_os_vi_detach(struct ifnet *ifp)
#ifdef WITH_EXTMEM
#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
struct nm_os_extmem {
vm_object_t obj;
@@ -725,17 +726,18 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror)
&obj, &index, &prot, &wired);
if (rv != KERN_SUCCESS) {
nm_prerr("address %lx not found", p);
+ error = vm_mmap_to_errno(rv);
goto out_free;
}
+ vm_object_reference(obj);
+
/* check that we are given the whole vm_object ? */
vm_map_lookup_done(map, entry);
- // XXX can we really use obj after releasing the map lock?
e->obj = obj;
- vm_object_reference(obj);
- /* wire the memory and add the vm_object to the kernel map,
- * to make sure that it is not fred even if the processes that
- * are mmap()ing it all exit
+ /* Wire the memory and add the vm_object to the kernel map,
+ * to make sure that it is not freed even if all the processes
+ * that are mmap()ing should munmap() it.
*/
e->kva = vm_map_min(kernel_map);
e->size = obj->size << PAGE_SHIFT;
@@ -744,12 +746,14 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror)
VM_PROT_READ | VM_PROT_WRITE, 0);
if (rv != KERN_SUCCESS) {
nm_prerr("vm_map_find(%zx) failed", (size_t)e->size);
+ error = vm_mmap_to_errno(rv);
goto out_rel;
}
rv = vm_map_wire(kernel_map, e->kva, e->kva + e->size,
VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
if (rv != KERN_SUCCESS) {
nm_prerr("vm_map_wire failed");
+ error = vm_mmap_to_errno(rv);
goto out_rem;
}
@@ -759,9 +763,9 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror)
out_rem:
vm_map_remove(kernel_map, e->kva, e->kva + e->size);
- e->obj = NULL;
out_rel:
vm_object_deallocate(e->obj);
+ e->obj = NULL;
out_free:
nm_os_free(e);
out: