162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_KASAN_H
362306a36Sopenharmony_ci#define __ASM_KASAN_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifndef __ASSEMBLY__
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/linkage.h>
862306a36Sopenharmony_ci#include <linux/mmzone.h>
962306a36Sopenharmony_ci#include <asm/addrspace.h>
1062306a36Sopenharmony_ci#include <asm/io.h>
1162306a36Sopenharmony_ci#include <asm/pgtable.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define KASAN_SHADOW_SCALE_SHIFT 3
1462306a36Sopenharmony_ci#define KASAN_SHADOW_OFFSET	_AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define XRANGE_SHIFT (48)
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* Valid address length */
1962306a36Sopenharmony_ci#define XRANGE_SHADOW_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
2062306a36Sopenharmony_ci/* Used for taking out the valid address */
2162306a36Sopenharmony_ci#define XRANGE_SHADOW_MASK	GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0)
2262306a36Sopenharmony_ci/* One segment whole address space size */
2362306a36Sopenharmony_ci#define XRANGE_SIZE		(XRANGE_SHADOW_MASK + 1)
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* 64-bit segment value. */
2662306a36Sopenharmony_ci#define XKPRANGE_UC_SEG		(0x8000)
2762306a36Sopenharmony_ci#define XKPRANGE_CC_SEG		(0x9000)
2862306a36Sopenharmony_ci#define XKVRANGE_VC_SEG		(0xffff)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/* Cached */
3162306a36Sopenharmony_ci#define XKPRANGE_CC_START		CACHE_BASE
3262306a36Sopenharmony_ci#define XKPRANGE_CC_SIZE		XRANGE_SIZE
3362306a36Sopenharmony_ci#define XKPRANGE_CC_KASAN_OFFSET	(0)
3462306a36Sopenharmony_ci#define XKPRANGE_CC_SHADOW_SIZE		(XKPRANGE_CC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
3562306a36Sopenharmony_ci#define XKPRANGE_CC_SHADOW_END		(XKPRANGE_CC_KASAN_OFFSET + XKPRANGE_CC_SHADOW_SIZE)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/* UnCached */
3862306a36Sopenharmony_ci#define XKPRANGE_UC_START		UNCACHE_BASE
3962306a36Sopenharmony_ci#define XKPRANGE_UC_SIZE		XRANGE_SIZE
4062306a36Sopenharmony_ci#define XKPRANGE_UC_KASAN_OFFSET	XKPRANGE_CC_SHADOW_END
4162306a36Sopenharmony_ci#define XKPRANGE_UC_SHADOW_SIZE		(XKPRANGE_UC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
4262306a36Sopenharmony_ci#define XKPRANGE_UC_SHADOW_END		(XKPRANGE_UC_KASAN_OFFSET + XKPRANGE_UC_SHADOW_SIZE)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* VMALLOC (Cached or UnCached)  */
4562306a36Sopenharmony_ci#define XKVRANGE_VC_START		MODULES_VADDR
4662306a36Sopenharmony_ci#define XKVRANGE_VC_SIZE		round_up(KFENCE_AREA_END - MODULES_VADDR + 1, PGDIR_SIZE)
4762306a36Sopenharmony_ci#define XKVRANGE_VC_KASAN_OFFSET	XKPRANGE_UC_SHADOW_END
4862306a36Sopenharmony_ci#define XKVRANGE_VC_SHADOW_SIZE		(XKVRANGE_VC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
4962306a36Sopenharmony_ci#define XKVRANGE_VC_SHADOW_END		(XKVRANGE_VC_KASAN_OFFSET + XKVRANGE_VC_SHADOW_SIZE)
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* KAsan shadow memory start right after vmalloc. */
5262306a36Sopenharmony_ci#define KASAN_SHADOW_START		round_up(KFENCE_AREA_END, PGDIR_SIZE)
5362306a36Sopenharmony_ci#define KASAN_SHADOW_SIZE		(XKVRANGE_VC_SHADOW_END - XKPRANGE_CC_KASAN_OFFSET)
5462306a36Sopenharmony_ci#define KASAN_SHADOW_END		round_up(KASAN_SHADOW_START + KASAN_SHADOW_SIZE, PGDIR_SIZE)
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define XKPRANGE_CC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_CC_KASAN_OFFSET)
5762306a36Sopenharmony_ci#define XKPRANGE_UC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_UC_KASAN_OFFSET)
5862306a36Sopenharmony_ci#define XKVRANGE_VC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKVRANGE_VC_KASAN_OFFSET)
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ciextern bool kasan_early_stage;
6162306a36Sopenharmony_ciextern unsigned char kasan_early_shadow_page[PAGE_SIZE];
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#define kasan_mem_to_shadow kasan_mem_to_shadow
6462306a36Sopenharmony_civoid *kasan_mem_to_shadow(const void *addr);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#define kasan_shadow_to_mem kasan_shadow_to_mem
6762306a36Sopenharmony_ciconst void *kasan_shadow_to_mem(const void *shadow_addr);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#define kasan_arch_is_ready kasan_arch_is_ready
7062306a36Sopenharmony_cistatic __always_inline bool kasan_arch_is_ready(void)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	return !kasan_early_stage;
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#define addr_has_metadata addr_has_metadata
7662306a36Sopenharmony_cistatic __always_inline bool addr_has_metadata(const void *addr)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	return (kasan_mem_to_shadow((void *)addr) != NULL);
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_civoid kasan_init(void);
8262306a36Sopenharmony_ciasmlinkage void kasan_early_init(void);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#endif
8562306a36Sopenharmony_ci#endif
86