LoongArch: Add WriteCombine shadow mapping in KASAN
authorKanglong Wang <wangkanglong@loongson.cn>
Tue, 12 Nov 2024 08:35:39 +0000 (16:35 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Tue, 12 Nov 2024 08:35:39 +0000 (16:35 +0800)
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: 8e02c3b782ec ("LoongArch: Add writecombine support for DMW-based ioremap()")
Signed-off-by: Kanglong Wang <wangkanglong@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/kasan.h
arch/loongarch/mm/kasan_init.c

index cb74a47..7f52bd3 100644 (file)
@@ -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 */
 #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;
index 7277b75..d268127 100644 (file)
@@ -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)