Index: sys/kern/subr_kcov.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_kcov.c,v retrieving revision 1.3 diff -u -r1.3 subr_kcov.c --- sys/kern/subr_kcov.c 23 Feb 2019 12:07:40 -0000 1.3 +++ sys/kern/subr_kcov.c 24 Feb 2019 10:48:48 -0000 @@ -65,10 +65,10 @@ kcov_int_t *buf; size_t bufnent; size_t bufsize; + bool in_use; TAILQ_ENTRY(kcov_desc) entry; } kcov_t; -static specificdata_key_t kcov_proc_key; static specificdata_key_t kcov_lwp_key; static void @@ -92,7 +92,7 @@ kd->refcnt++; KASSERT(kd->refcnt == 2); - lwp_setspecific(kcov_lwp_key, kd); + kd->in_use = true; } static void @@ -101,7 +101,7 @@ KASSERT(kd->refcnt == 2); kd->refcnt--; - lwp_setspecific(kcov_lwp_key, NULL); + kd->in_use = false; } static inline bool @@ -164,17 +164,16 @@ static int kcov_open(dev_t dev, int flag, int mode, struct lwp *l) { - struct proc *p = l->l_proc; kcov_t *kd; - kd = proc_getspecific(p, kcov_proc_key); + kd = lwp_getspecific(kcov_lwp_key); if (kd != NULL) return EBUSY; kd = kmem_zalloc(sizeof(*kd), KM_SLEEP); mutex_init(&kd->lock, MUTEX_DEFAULT, IPL_NONE); kd->refcnt = 1; - proc_setspecific(p, kcov_proc_key, kd); + lwp_setspecific(kcov_lwp_key, kd); return 0; } @@ -182,6 +181,13 @@ static int kcov_close(dev_t dev, int flag, int mode, struct lwp *l) { + kcov_t *kd; + + kd = lwp_getspecific(kcov_lwp_key); + + kcov_free(kd); + + lwp_setspecific(kcov_lwp_key, NULL); return 0; } @@ -189,11 +195,10 @@ static int kcov_ioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { - struct proc *p = l->l_proc; int error = 0; kcov_t *kd; - kd = proc_getspecific(p, kcov_proc_key); + kd = lwp_getspecific(kcov_lwp_key); if (kd == NULL) return ENXIO; kcov_lock(kd); @@ -219,7 +224,7 @@ kcov_lwp_take(kd); break; case KCOV_IOC_DISABLE: - if (lwp_getspecific(kcov_lwp_key) == NULL) { + if (!kd->in_use) { error = ENOENT; break; } @@ -241,8 +246,10 @@ paddr_t pa; vaddr_t va; - kd = proc_getspecific(curproc, kcov_proc_key); - KASSERT(kd != NULL); + kd = lwp_getspecific(kcov_lwp_key); + if (kd == NULL) { + return (paddr_t)-1; + } if ((offset < 0) || (offset >= kd->bufnent * KCOV_ENTRY_SIZE)) { return (paddr_t)-1; @@ -289,10 +296,16 @@ return; } - idx = kd->buf[0]; + if (!kd->in_use) { + /* Tracing not enabled */ + return; + } + + idx = KCOV_LOAD(kd->buf[0]); if (idx < kd->bufnent) { - kd->buf[idx+1] = (intptr_t)__builtin_return_address(0); - kd->buf[0]++; + KCOV_STORE(kd->buf[idx+1], + (intptr_t)__builtin_return_address(0)); + KCOV_STORE(kd->buf[0], idx + 1); } } @@ -319,7 +332,6 @@ kcov_init(void) { - proc_specific_key_create(&kcov_proc_key, kcov_free); lwp_specific_key_create(&kcov_lwp_key, kcov_free); }