/* SPDX-License-Identifier: GPL-2.0 */
/*
 * KCSAN watchpoint encoding.
 *
 * Copyright (C) 2019, Google LLC.
 */

#ifndef _KERNEL_KCSAN_ENCODING_H
#define _KERNEL_KCSAN_ENCODING_H

#include <linux/bits.h>
#include <linux/log2.h>
#include <linux/mm.h>

#include "kcsan.h"

#define SLOT_RANGE PAGE_SIZE

#define INVALID_WATCHPOINT  0
#define CONSUMED_WATCHPOINT 1

/*
 * The maximum useful size of accesses for which we set up watchpoints is the
 * max range of slots we check on an access.
 */
#define MAX_ENCODABLE_SIZE (SLOT_RANGE * (1 + KCSAN_CHECK_ADJACENT))

/*
 * Number of bits we use to store size info.
 */
#define WATCHPOINT_SIZE_BITS bits_per(MAX_ENCODABLE_SIZE)
/*
 * This encoding for addresses discards the upper (1 for is-write + SIZE_BITS);
 * however, most 64-bit architectures do not use the full 64-bit address space.
 * Also, in order for a false positive to be observable 2 things need to happen:
 *
 *	1. different addresses but with the same encoded address race;
 *	2. and both map onto the same watchpoint slots;
 *
 * Both these are assumed to be very unlikely. However, in case it still
 * happens, the report logic will filter out the false positive (see report.c).
 */
#define WATCHPOINT_ADDR_BITS (BITS_PER_LONG-1 - WATCHPOINT_SIZE_BITS)

/* Bitmasks for the encoded watchpoint access information. */
#define WATCHPOINT_WRITE_MASK	BIT(BITS_PER_LONG-1)
#define WATCHPOINT_SIZE_MASK	GENMASK(BITS_PER_LONG-2, WATCHPOINT_ADDR_BITS)
#define WATCHPOINT_ADDR_MASK	GENMASK(WATCHPOINT_ADDR_BITS-1, 0)
static_assert(WATCHPOINT_ADDR_MASK == (1UL << WATCHPOINT_ADDR_BITS) - 1);
static_assert((WATCHPOINT_WRITE_MASK ^ WATCHPOINT_SIZE_MASK ^ WATCHPOINT_ADDR_MASK) == ~0UL);

static inline bool check_encodable(unsigned long addr, size_t size)
{
	/*
	 * While we can encode addrs<PAGE_SIZE, avoid crashing with a NULL
	 * pointer deref inside KCSAN.
	 */
	return addr >= PAGE_SIZE && size <= MAX_ENCODABLE_SIZE;
}

static inline long
encode_watchpoint(unsigned long addr, size_t size, bool is_write)
{
	return (long)((is_write ? WATCHPOINT_WRITE_MASK : 0) |
		      (size << WATCHPOINT_ADDR_BITS) |
		      (addr & WATCHPOINT_ADDR_MASK));
}

static __always_inline bool decode_watchpoint(long watchpoint,
					      unsigned long *addr_masked,
					      size_t *size,
					      bool *is_write)
{
	if (watchpoint == INVALID_WATCHPOINT ||
	    watchpoint == CONSUMED_WATCHPOINT)
		return false;

	*addr_masked =    (unsigned long)watchpoint & WATCHPOINT_ADDR_MASK;
	*size	     =   ((unsigned long)watchpoint & WATCHPOINT_SIZE_MASK) >> WATCHPOINT_ADDR_BITS;
	*is_write    = !!((unsigned long)watchpoint & WATCHPOINT_WRITE_MASK);

	return true;
}

/*
 * Return watchpoint slot for an address.
 */
static __always_inline int watchpoint_slot(unsigned long addr)
{
	return (addr / PAGE_SIZE) % CONFIG_KCSAN_NUM_WATCHPOINTS;
}

static __always_inline bool matching_access(unsigned long addr1, size_t size1,
					    unsigned long addr2, size_t size2)
{
	unsigned long end_range1 = addr1 + size1 - 1;
	unsigned long end_range2 = addr2 + size2 - 1;

	return addr1 <= end_range2 && addr2 <= end_range1;
}

#endif /* _KERNEL_KCSAN_ENCODING_H */
