Commit 39b2e763 authored by Mark Rutland's avatar Mark Rutland Committed by Paul E. McKenney
Browse files

kcsan: Refactor access_info initialization



In subsequent patches we'll want to split kcsan_report() into distinct
handlers for each report type. The largest bit of common work is
initializing the `access_info`, so let's factor this out into a helper,
and have the kcsan_report_*() functions pass the `aaccess_info` as a
parameter to kcsan_report().

There should be no functional change as a result of this patch.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarMarco Elver <elver@google.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 97aa6139
Loading
Loading
Loading
Loading
+25 −17
Original line number Diff line number Diff line
@@ -596,18 +596,10 @@ static noinline bool prepare_report(unsigned long *flags,
	}
}

static void kcsan_report(const volatile void *ptr, size_t size, int access_type,
			 enum kcsan_value_change value_change,
static void kcsan_report(const struct access_info *ai, enum kcsan_value_change value_change,
			 enum kcsan_report_type type, struct other_info *other_info)
{
	unsigned long flags = 0;
	const struct access_info ai = {
		.ptr		= ptr,
		.size		= size,
		.access_type	= access_type,
		.task_pid	= in_task() ? task_pid_nr(current) : -1,
		.cpu_id		= raw_smp_processor_id()
	};

	kcsan_disable_current();

@@ -620,14 +612,14 @@ static void kcsan_report(const volatile void *ptr, size_t size, int access_type,
	 */
	lockdep_off();

	if (prepare_report(&flags, type, &ai, other_info)) {
	if (prepare_report(&flags, type, ai, other_info)) {
		/*
		 * Never report if value_change is FALSE, only if we it is
		 * either TRUE or MAYBE. In case of MAYBE, further filtering may
		 * be done once we know the full stack trace in print_report().
		 */
		if (value_change != KCSAN_VALUE_CHANGE_FALSE)
			print_report(value_change, type, &ai, other_info);
			print_report(value_change, type, ai, other_info);

		release_report(&flags, other_info);
	}
@@ -636,22 +628,38 @@ static void kcsan_report(const volatile void *ptr, size_t size, int access_type,
	kcsan_enable_current();
}

static struct access_info prepare_access_info(const volatile void *ptr, size_t size,
					      int access_type)
{
	return (struct access_info) {
		.ptr		= ptr,
		.size		= size,
		.access_type	= access_type,
		.task_pid	= in_task() ? task_pid_nr(current) : -1,
		.cpu_id		= raw_smp_processor_id()
	};
}

void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_type,
			   int watchpoint_idx)
{
	kcsan_report(ptr, size, access_type, KCSAN_VALUE_CHANGE_MAYBE,
		     KCSAN_REPORT_CONSUMED_WATCHPOINT, &other_infos[watchpoint_idx]);
	const struct access_info ai = prepare_access_info(ptr, size, access_type);

	kcsan_report(&ai, KCSAN_VALUE_CHANGE_MAYBE, KCSAN_REPORT_CONSUMED_WATCHPOINT,
		     &other_infos[watchpoint_idx]);
}

void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type,
			       enum kcsan_value_change value_change, int watchpoint_idx)
{
	kcsan_report(ptr, size, access_type, value_change,
		     KCSAN_REPORT_RACE_SIGNAL, &other_infos[watchpoint_idx]);
	const struct access_info ai = prepare_access_info(ptr, size, access_type);

	kcsan_report(&ai, value_change, KCSAN_REPORT_RACE_SIGNAL, &other_infos[watchpoint_idx]);
}

void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type)
{
	kcsan_report(ptr, size, access_type, KCSAN_VALUE_CHANGE_TRUE,
		     KCSAN_REPORT_RACE_UNKNOWN_ORIGIN, NULL);
	const struct access_info ai = prepare_access_info(ptr, size, access_type);

	kcsan_report(&ai, KCSAN_VALUE_CHANGE_TRUE, KCSAN_REPORT_RACE_UNKNOWN_ORIGIN, NULL);
}