kcov
struct kcov *kcov;
struct kcov *kcov;
kcov = t->kcov;
spin_lock(&kcov->lock);
if (sequence == kcov->sequence && kcov->remote)
kcov_move_area(kcov->mode, kcov->area, kcov->size, area);
spin_unlock(&kcov->lock);
kcov_put(kcov);
static struct kcov_remote *kcov_remote_add(struct kcov *kcov, u64 handle)
remote->kcov = kcov;
static void kcov_start(struct task_struct *t, struct kcov *kcov,
t->kcov = kcov;
t->kcov = NULL;
static void kcov_reset(struct kcov *kcov)
__must_hold(&kcov->lock)
kcov->t = NULL;
kcov->mode = KCOV_MODE_INIT;
kcov->remote = false;
kcov->remote_size = 0;
kcov->sequence++;
static void kcov_remote_reset(struct kcov *kcov)
__must_hold(&kcov->lock)
if (remote->kcov != kcov)
kcov_reset(kcov);
static void kcov_disable(struct task_struct *t, struct kcov *kcov)
__must_hold(&kcov->lock)
if (kcov->remote)
kcov_remote_reset(kcov);
kcov_reset(kcov);
static void kcov_get(struct kcov *kcov)
refcount_inc(&kcov->refcount);
static void kcov_put(struct kcov *kcov)
if (refcount_dec_and_test(&kcov->refcount)) {
kcov_remote_reset(kcov);
vfree(kcov->area);
kfree(kcov);
struct kcov *kcov;
kcov = t->kcov;
if (kcov == NULL)
spin_lock_irqsave(&kcov->lock, flags);
kcov_debug("t = %px, kcov->t = %px\n", t, kcov->t);
if (WARN_ON(kcov->t != t)) {
spin_unlock_irqrestore(&kcov->lock, flags);
kcov_disable(t, kcov);
spin_unlock_irqrestore(&kcov->lock, flags);
kcov_put(kcov);
struct kcov *kcov = vma->vm_file->private_data;
spin_lock_irqsave(&kcov->lock, flags);
size = kcov->size * sizeof(unsigned long);
if (kcov->area == NULL || vma->vm_pgoff != 0 ||
area = kcov->area;
spin_unlock_irqrestore(&kcov->lock, flags);
spin_unlock_irqrestore(&kcov->lock, flags);
struct kcov *kcov;
kcov = kzalloc_obj(*kcov);
if (!kcov)
guard(spinlock_init)(&kcov->lock);
kcov->mode = KCOV_MODE_DISABLED;
kcov->sequence = 1;
refcount_set(&kcov->refcount, 1);
filep->private_data = kcov;
static void kcov_fault_in_area(struct kcov *kcov)
__must_hold(&kcov->lock)
unsigned long *area = kcov->area;
for (offset = 0; offset < kcov->size; offset += stride)
static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
__must_hold(&kcov->lock)
if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
if (kcov->t != NULL || t->kcov != NULL)
kcov_fault_in_area(kcov);
kcov->mode = mode;
kcov_start(t, kcov, kcov->size, kcov->area, kcov->mode,
kcov->sequence);
kcov->t = t;
kcov_get(kcov);
if (unused != 0 || current->kcov != kcov)
if (WARN_ON(kcov->t != t))
kcov_disable(t, kcov);
kcov_put(kcov);
if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
if (kcov->t != NULL || t->kcov != NULL)
kcov->mode = mode;
t->kcov = kcov;
kcov->t = t;
kcov->remote = true;
kcov->remote_size = remote_arg->area_size;
kcov_disable(t, kcov);
remote = kcov_remote_add(kcov, remote_arg->handles[i]);
kcov_disable(t, kcov);
kcov_disable(t, kcov);
remote = kcov_remote_add(kcov,
kcov_disable(t, kcov);
kcov_get(kcov);
struct kcov *kcov;
kcov = filep->private_data;
spin_lock_irqsave(&kcov->lock, flags);
if (kcov->mode != KCOV_MODE_DISABLED) {
spin_unlock_irqrestore(&kcov->lock, flags);
kcov->area = area;
kcov->size = size;
kcov->mode = KCOV_MODE_INIT;
spin_unlock_irqrestore(&kcov->lock, flags);
spin_lock_irqsave(&kcov->lock, flags);
res = kcov_ioctl_locked(kcov, cmd, arg);
spin_unlock_irqrestore(&kcov->lock, flags);
struct kcov *kcov;
data->saved_kcov = t->kcov;
struct kcov *kcov;
kcov = remote->kcov;
kcov_get(kcov);
mode = context_unsafe(kcov->mode);
sequence = kcov->sequence;
size = kcov->remote_size;
kcov_put(kcov);
kcov_start(t, kcov, size, area, mode, sequence);
struct kcov *saved_kcov;