Commit 139d42ca authored by Kanglong Wang's avatar Kanglong Wang Committed by Huacai Chen
Browse files

LoongArch: Add WriteCombine shadow mapping in KASAN



Currently, the kernel couldn't boot when ARCH_IOREMAP, ARCH_WRITECOMBINE
and KASAN are enabled together. Because DMW2 is used by kernel now which
is configured as 0xa000000000000000 for WriteCombine, but KASAN has no
segment mapping for it. This patch fix this issue.

Solution: Add the relevant definitions for WriteCombine (DMW2) in KASAN.

Cc: stable@vger.kernel.org
Fixes: 8e02c3b7 ("LoongArch: Add writecombine support for DMW-based ioremap()")
Signed-off-by: default avatarKanglong Wang <wangkanglong@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 227ca9f6
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
/* 64-bit segment value. */
#define XKPRANGE_UC_SEG		(0x8000)
#define XKPRANGE_CC_SEG		(0x9000)
#define XKPRANGE_WC_SEG		(0xa000)
#define XKVRANGE_VC_SEG		(0xffff)

/* Cached */
@@ -41,10 +42,17 @@
#define XKPRANGE_UC_SHADOW_SIZE		(XKPRANGE_UC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
#define XKPRANGE_UC_SHADOW_END		(XKPRANGE_UC_KASAN_OFFSET + XKPRANGE_UC_SHADOW_SIZE)

/* WriteCombine */
#define XKPRANGE_WC_START		WRITECOMBINE_BASE
#define XKPRANGE_WC_SIZE		XRANGE_SIZE
#define XKPRANGE_WC_KASAN_OFFSET	XKPRANGE_UC_SHADOW_END
#define XKPRANGE_WC_SHADOW_SIZE		(XKPRANGE_WC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
#define XKPRANGE_WC_SHADOW_END		(XKPRANGE_WC_KASAN_OFFSET + XKPRANGE_WC_SHADOW_SIZE)

/* VMALLOC (Cached or UnCached)  */
#define XKVRANGE_VC_START		MODULES_VADDR
#define XKVRANGE_VC_SIZE		round_up(KFENCE_AREA_END - MODULES_VADDR + 1, PGDIR_SIZE)
#define XKVRANGE_VC_KASAN_OFFSET	XKPRANGE_UC_SHADOW_END
#define XKVRANGE_VC_KASAN_OFFSET	XKPRANGE_WC_SHADOW_END
#define XKVRANGE_VC_SHADOW_SIZE		(XKVRANGE_VC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
#define XKVRANGE_VC_SHADOW_END		(XKVRANGE_VC_KASAN_OFFSET + XKVRANGE_VC_SHADOW_SIZE)

@@ -55,6 +63,7 @@

#define XKPRANGE_CC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_CC_KASAN_OFFSET)
#define XKPRANGE_UC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_UC_KASAN_OFFSET)
#define XKPRANGE_WC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_WC_KASAN_OFFSET)
#define XKVRANGE_VC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKVRANGE_VC_KASAN_OFFSET)

extern bool kasan_early_stage;
+5 −0
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ void *kasan_mem_to_shadow(const void *addr)
		case XKPRANGE_UC_SEG:
			offset = XKPRANGE_UC_SHADOW_OFFSET;
			break;
		case XKPRANGE_WC_SEG:
			offset = XKPRANGE_WC_SHADOW_OFFSET;
			break;
		case XKVRANGE_VC_SEG:
			offset = XKVRANGE_VC_SHADOW_OFFSET;
			break;
@@ -86,6 +89,8 @@ const void *kasan_shadow_to_mem(const void *shadow_addr)

	if (addr >= XKVRANGE_VC_SHADOW_OFFSET)
		return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START);
	else if (addr >= XKPRANGE_WC_SHADOW_OFFSET)
		return (void *)(((addr - XKPRANGE_WC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_WC_START);
	else if (addr >= XKPRANGE_UC_SHADOW_OFFSET)
		return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START);
	else if (addr >= XKPRANGE_CC_SHADOW_OFFSET)