| 360 | } |
| 361 | |
| 362 | static int |
| 363 | kcov_alloc(struct kcov_info *info, size_t entries) |
| 364 | { |
| 365 | size_t n, pages; |
| 366 | vm_page_t m; |
| 367 | |
| 368 | KASSERT(info->kvaddr == 0, ("kcov_alloc: Already have a buffer")); |
| 369 | KASSERT(info->state == KCOV_STATE_OPEN, |
| 370 | ("kcov_alloc: Not in open state (%x)", info->state)); |
| 371 | |
| 372 | if (entries < 2 || entries > kcov_max_entries) |
| 373 | return (EINVAL); |
| 374 | |
| 375 | /* Align to page size so mmap can't access other kernel memory */ |
| 376 | info->bufsize = roundup2(entries * KCOV_ELEMENT_SIZE, PAGE_SIZE); |
| 377 | pages = info->bufsize / PAGE_SIZE; |
| 378 | |
| 379 | if ((info->kvaddr = kva_alloc(info->bufsize)) == 0) |
| 380 | return (ENOMEM); |
| 381 | |
| 382 | info->bufobj = vm_pager_allocate(OBJT_PHYS, 0, info->bufsize, |
| 383 | PROT_READ | PROT_WRITE, 0, curthread->td_ucred); |
| 384 | |
| 385 | VM_OBJECT_WLOCK(info->bufobj); |
| 386 | for (n = 0; n < pages; n++) { |
| 387 | m = vm_page_grab(info->bufobj, n, |
| 388 | VM_ALLOC_ZERO | VM_ALLOC_WIRED); |
| 389 | vm_page_valid(m); |
| 390 | vm_page_xunbusy(m); |
| 391 | pmap_qenter(info->kvaddr + n * PAGE_SIZE, &m, 1); |
| 392 | } |
| 393 | VM_OBJECT_WUNLOCK(info->bufobj); |
| 394 | |
| 395 | info->entries = entries; |
| 396 | |
| 397 | return (0); |
| 398 | } |
| 399 | |
| 400 | static void |
| 401 | kcov_free(struct kcov_info *info) |
no test coverage detected