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; @@ -357,7 +359,7 @@ kcov_alloc(struct kcov_info *info, size_t entries) { size_t n, pages; - vm_page_t *m; + vm_page_t m; KASSERT(info->kvaddr == 0, ("kcov_alloc: Already have a buffer")); KASSERT(info->state == KCOV_STATE_OPEN, @@ -376,16 +378,14 @@ 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); VM_OBJECT_WLOCK(info->bufobj); for (n = 0; n < pages; n++) { - m[n] = vm_page_grab(info->bufobj, n, + m = vm_page_grab(info->bufobj, n, VM_ALLOC_NOBUSY | VM_ALLOC_ZERO | VM_ALLOC_WIRED); - m[n]->valid = VM_PAGE_BITS_ALL; + m->valid = VM_PAGE_BITS_ALL; + pmap_qenter(info->kvaddr + n * PAGE_SIZE, &m, 1); } VM_OBJECT_WUNLOCK(info->bufobj); - pmap_qenter(info->kvaddr, m, pages); - free(m, M_TEMP); info->entries = entries; @@ -395,14 +395,27 @@ 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); + m = vm_page_lookup(info->bufobj, 0); + for (i = 0; i < info->bufsize / PAGE_SIZE; i++) { + vm_page_lock(m); + vm_page_unwire_noq(m); + vm_page_unlock(m); + + m = vm_page_next(m); + } + VM_OBJECT_WUNLOCK(info->bufobj); vm_object_deallocate(info->bufobj); - free(info, M_KCOV_INFO); + } + free(info, M_KCOV); } static int