Skip to content

Commit

Permalink
kcsan: Save instruction pointer for scoped accesses
Browse files Browse the repository at this point in the history
Save the instruction pointer for scoped accesses, so that it becomes
possible for the reporting code to construct more accurate stack traces
that will show the start of the scope.

Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
  • Loading branch information
Marco Elver authored and Paul E. McKenney committed Sep 13, 2021
1 parent 55a55fe commit f4c87db
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
3 changes: 3 additions & 0 deletions include/linux/kcsan-checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,12 @@ void kcsan_set_access_mask(unsigned long mask);
/* Scoped access information. */
struct kcsan_scoped_access {
struct list_head list;
/* Access information. */
const volatile void *ptr;
size_t size;
int type;
/* Location where scoped access was set up. */
unsigned long ip;
};
/*
* Automatically call kcsan_end_scoped_access() when kcsan_scoped_access goes
Expand Down
12 changes: 9 additions & 3 deletions kernel/kcsan/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ static __always_inline struct kcsan_ctx *get_ctx(void)
return in_task() ? &current->kcsan_ctx : raw_cpu_ptr(&kcsan_cpu_ctx);
}

static __always_inline void
check_access(const volatile void *ptr, size_t size, int type, unsigned long ip);

/* Check scoped accesses; never inline because this is a slow-path! */
static noinline void kcsan_check_scoped_accesses(void)
{
Expand All @@ -210,8 +213,10 @@ static noinline void kcsan_check_scoped_accesses(void)
struct kcsan_scoped_access *scoped_access;

ctx->scoped_accesses.prev = NULL; /* Avoid recursion. */
list_for_each_entry(scoped_access, &ctx->scoped_accesses, list)
__kcsan_check_access(scoped_access->ptr, scoped_access->size, scoped_access->type);
list_for_each_entry(scoped_access, &ctx->scoped_accesses, list) {
check_access(scoped_access->ptr, scoped_access->size,
scoped_access->type, scoped_access->ip);
}
ctx->scoped_accesses.prev = prev_save;
}

Expand Down Expand Up @@ -767,6 +772,7 @@ kcsan_begin_scoped_access(const volatile void *ptr, size_t size, int type,
sa->ptr = ptr;
sa->size = size;
sa->type = type;
sa->ip = _RET_IP_;

if (!ctx->scoped_accesses.prev) /* Lazy initialize list head. */
INIT_LIST_HEAD(&ctx->scoped_accesses);
Expand Down Expand Up @@ -798,7 +804,7 @@ void kcsan_end_scoped_access(struct kcsan_scoped_access *sa)

ctx->disable_count--;

__kcsan_check_access(sa->ptr, sa->size, sa->type);
check_access(sa->ptr, sa->size, sa->type, sa->ip);
}
EXPORT_SYMBOL(kcsan_end_scoped_access);

Expand Down

0 comments on commit f4c87db

Please sign in to comment.