Index: sys/kern/kern_kcov.c =================================================================== --- sys/kern/kern_kcov.c +++ sys/kern/kern_kcov.c @@ -58,8 +58,9 @@ #include #include #include +#include -MALLOC_DEFINE(M_KCOV_INFO, "kcovinfo", "KCOV info type"); +MALLOC_DEFINE(M_KCOV, "kcov", "kcov memory"); #define KCOV_ELEMENT_SIZE sizeof(uint64_t) @@ -298,7 +299,7 @@ struct kcov_info *info; int error; - info = malloc(sizeof(struct kcov_info), M_KCOV_INFO, M_ZERO | M_WAITOK); + info = malloc(sizeof(struct kcov_info), M_KCOV, M_ZERO | M_WAITOK); info->state = KCOV_STATE_OPEN; info->thread = NULL; info->mode = -1; @@ -347,6 +348,7 @@ info->mmap != false) return (EINVAL); + vm_object_reference(info->bufobj); info->mmap = true; *offset = 0; *object = info->bufobj; @@ -376,7 +378,7 @@ info->bufobj = vm_pager_allocate(OBJT_PHYS, 0, info->bufsize, PROT_READ | PROT_WRITE, 0, curthread->td_ucred); - m = malloc(sizeof(*m) * pages, M_TEMP, M_WAITOK); + m = malloc(sizeof(*m) * pages, M_KCOV, M_WAITOK); VM_OBJECT_WLOCK(info->bufobj); for (n = 0; n < pages; n++) { m[n] = vm_page_grab(info->bufobj, n, @@ -385,7 +387,7 @@ } VM_OBJECT_WUNLOCK(info->bufobj); pmap_qenter(info->kvaddr, m, pages); - free(m, M_TEMP); + free(m, M_KCOV); info->entries = entries; @@ -395,14 +397,25 @@ static void kcov_free(struct kcov_info *info) { + vm_page_t m; + size_t i; if (info->kvaddr != 0) { pmap_qremove(info->kvaddr, info->bufsize / PAGE_SIZE); kva_free(info->kvaddr, info->bufsize); } - if (info->bufobj != NULL && !info->mmap) + if (info->bufobj != NULL) { + VM_OBJECT_WLOCK(info->bufobj); + for (i = 0; i < info->bufsize / PAGE_SIZE; i++) { + m = vm_page_lookup(info->bufobj, i); + vm_page_lock(m); + vm_page_unwire_noq(m); + vm_page_unlock(m); + } + VM_OBJECT_WUNLOCK(info->bufobj); vm_object_deallocate(info->bufobj); - free(info, M_KCOV_INFO); + } + free(info, M_KCOV); } static int