Commit 12305abe authored by Marco Elver's avatar Marco Elver Committed by Paul E. McKenney
Browse files

kcsan: Refactor reading of instrumented memory



Factor out the switch statement reading instrumented memory into a
helper read_instrumented_memory().

No functional change.

Signed-off-by: default avatarMarco Elver <elver@google.com>
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent fa55b7dc
Loading
Loading
Loading
Loading
+17 −34
Original line number Diff line number Diff line
@@ -325,6 +325,21 @@ static void delay_access(int type)
	udelay(delay);
}

/*
 * Reads the instrumented memory for value change detection; value change
 * detection is currently done for accesses up to a size of 8 bytes.
 */
static __always_inline u64 read_instrumented_memory(const volatile void *ptr, size_t size)
{
	switch (size) {
	case 1:  return READ_ONCE(*(const u8 *)ptr);
	case 2:  return READ_ONCE(*(const u16 *)ptr);
	case 4:  return READ_ONCE(*(const u32 *)ptr);
	case 8:  return READ_ONCE(*(const u64 *)ptr);
	default: return 0; /* Ignore; we do not diff the values. */
	}
}

void kcsan_save_irqtrace(struct task_struct *task)
{
#ifdef CONFIG_TRACE_IRQFLAGS
@@ -482,23 +497,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type, unsigned
	 * Read the current value, to later check and infer a race if the data
	 * was modified via a non-instrumented access, e.g. from a device.
	 */
	old = 0;
	switch (size) {
	case 1:
		old = READ_ONCE(*(const u8 *)ptr);
		break;
	case 2:
		old = READ_ONCE(*(const u16 *)ptr);
		break;
	case 4:
		old = READ_ONCE(*(const u32 *)ptr);
		break;
	case 8:
		old = READ_ONCE(*(const u64 *)ptr);
		break;
	default:
		break; /* ignore; we do not diff the values */
	}
	old = read_instrumented_memory(ptr, size);

	/*
	 * Delay this thread, to increase probability of observing a racy
@@ -511,23 +510,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type, unsigned
	 * racy access.
	 */
	access_mask = ctx->access_mask;
	new = 0;
	switch (size) {
	case 1:
		new = READ_ONCE(*(const u8 *)ptr);
		break;
	case 2:
		new = READ_ONCE(*(const u16 *)ptr);
		break;
	case 4:
		new = READ_ONCE(*(const u32 *)ptr);
		break;
	case 8:
		new = READ_ONCE(*(const u64 *)ptr);
		break;
	default:
		break; /* ignore; we do not diff the values */
	}
	new = read_instrumented_memory(ptr, size);

	diff = old ^ new;
	if (access_mask)