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
This commit is contained in:
parent
8c9e45503f
commit
ee7ffaa2e6
@ -664,6 +664,7 @@ nm_os_vi_detach(struct ifnet *ifp)
|
|||||||
|
|
||||||
#ifdef WITH_EXTMEM
|
#ifdef WITH_EXTMEM
|
||||||
#include <vm/vm_map.h>
|
#include <vm/vm_map.h>
|
||||||
|
#include <vm/vm_extern.h>
|
||||||
#include <vm/vm_kern.h>
|
#include <vm/vm_kern.h>
|
||||||
struct nm_os_extmem {
|
struct nm_os_extmem {
|
||||||
vm_object_t obj;
|
vm_object_t obj;
|
||||||
@ -726,17 +727,18 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror)
|
|||||||
&obj, &index, &prot, &wired);
|
&obj, &index, &prot, &wired);
|
||||||
if (rv != KERN_SUCCESS) {
|
if (rv != KERN_SUCCESS) {
|
||||||
nm_prerr("address %lx not found", p);
|
nm_prerr("address %lx not found", p);
|
||||||
|
error = vm_mmap_to_errno(rv);
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
vm_object_reference(obj);
|
||||||
|
|
||||||
/* check that we are given the whole vm_object ? */
|
/* check that we are given the whole vm_object ? */
|
||||||
vm_map_lookup_done(map, entry);
|
vm_map_lookup_done(map, entry);
|
||||||
|
|
||||||
// XXX can we really use obj after releasing the map lock?
|
|
||||||
e->obj = obj;
|
e->obj = obj;
|
||||||
vm_object_reference(obj);
|
/* Wire the memory and add the vm_object to the kernel map,
|
||||||
/* 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
|
||||||
* to make sure that it is not fred even if the processes that
|
* that are mmap()ing should munmap() it.
|
||||||
* are mmap()ing it all exit
|
|
||||||
*/
|
*/
|
||||||
e->kva = vm_map_min(kernel_map);
|
e->kva = vm_map_min(kernel_map);
|
||||||
e->size = obj->size << PAGE_SHIFT;
|
e->size = obj->size << PAGE_SHIFT;
|
||||||
@ -745,12 +747,14 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror)
|
|||||||
VM_PROT_READ | VM_PROT_WRITE, 0);
|
VM_PROT_READ | VM_PROT_WRITE, 0);
|
||||||
if (rv != KERN_SUCCESS) {
|
if (rv != KERN_SUCCESS) {
|
||||||
nm_prerr("vm_map_find(%zx) failed", (size_t)e->size);
|
nm_prerr("vm_map_find(%zx) failed", (size_t)e->size);
|
||||||
|
error = vm_mmap_to_errno(rv);
|
||||||
goto out_rel;
|
goto out_rel;
|
||||||
}
|
}
|
||||||
rv = vm_map_wire(kernel_map, e->kva, e->kva + e->size,
|
rv = vm_map_wire(kernel_map, e->kva, e->kva + e->size,
|
||||||
VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
|
VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
|
||||||
if (rv != KERN_SUCCESS) {
|
if (rv != KERN_SUCCESS) {
|
||||||
nm_prerr("vm_map_wire failed");
|
nm_prerr("vm_map_wire failed");
|
||||||
|
error = vm_mmap_to_errno(rv);
|
||||||
goto out_rem;
|
goto out_rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,9 +764,9 @@ nm_os_extmem_create(unsigned long p, struct nmreq_pools_info *pi, int *perror)
|
|||||||
|
|
||||||
out_rem:
|
out_rem:
|
||||||
vm_map_remove(kernel_map, e->kva, e->kva + e->size);
|
vm_map_remove(kernel_map, e->kva, e->kva + e->size);
|
||||||
e->obj = NULL;
|
|
||||||
out_rel:
|
out_rel:
|
||||||
vm_object_deallocate(e->obj);
|
vm_object_deallocate(e->obj);
|
||||||
|
e->obj = NULL;
|
||||||
out_free:
|
out_free:
|
||||||
nm_os_free(e);
|
nm_os_free(e);
|
||||||
out:
|
out:
|
||||||
|
Loading…
Reference in New Issue
Block a user