arch/loongarch/mm/kasan_init.c | 77 ++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 37 deletions(-)
From: Tiezhu Yang <yangtiezhu@loongson.cn>
commit 5ec5ac4ca27e4daa234540ac32f9fc5219377d53 upstream.
"kasan_early_stage = false" indicates that kasan is fully initialized,
so it should be put at end of kasan_init().
Otherwise bringing up the primary CPU failed when CONFIG_KASAN is set
on PTW-enabled systems, here are the call chains:
kernel_entry()
start_kernel()
setup_arch()
kasan_init()
kasan_early_stage = false
The reason is PTW-enabled systems have speculative accesses which means
memory accesses to the shadow memory after kasan_init() may be executed
by hardware before. However, accessing shadow memory is safe only after
kasan fully initialized because kasan_init() uses a temporary PGD table
until we have populated all levels of shadow page tables and writen the
PGD register. Moving "kasan_early_stage = false" later can defer the
occasion of kasan_arch_is_ready(), so as to avoid speculative accesses
on shadow pages.
After moving "kasan_early_stage = false" to the end, kasan_init() can no
longer call kasan_mem_to_shadow() for shadow address conversion because
it will always return kasan_early_shadow_page. On the other hand, we
should keep the current logic of kasan_mem_to_shadow() for both the early
and final stage because there may be instrumentation before kasan_init().
To solve this, we factor out a new mem_to_shadow() function from current
kasan_mem_to_shadow() for the shadow address conversion in kasan_init().
Cc: stable@vger.kernel.org
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
arch/loongarch/mm/kasan_init.c | 77 ++++++++++++++++++----------------
1 file changed, 40 insertions(+), 37 deletions(-)
diff --git a/arch/loongarch/mm/kasan_init.c b/arch/loongarch/mm/kasan_init.c
index d2681272d8f0..9337380a70eb 100644
--- a/arch/loongarch/mm/kasan_init.c
+++ b/arch/loongarch/mm/kasan_init.c
@@ -42,39 +42,43 @@ static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
bool kasan_early_stage = true;
-void *kasan_mem_to_shadow(const void *addr)
+static void *mem_to_shadow(const void *addr)
{
- if (!kasan_arch_is_ready()) {
+ unsigned long offset = 0;
+ unsigned long maddr = (unsigned long)addr;
+ unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff;
+
+ if (maddr >= FIXADDR_START)
return (void *)(kasan_early_shadow_page);
- } else {
- unsigned long maddr = (unsigned long)addr;
- unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff;
- unsigned long offset = 0;
-
- if (maddr >= FIXADDR_START)
- return (void *)(kasan_early_shadow_page);
-
- maddr &= XRANGE_SHADOW_MASK;
- switch (xrange) {
- case XKPRANGE_CC_SEG:
- offset = XKPRANGE_CC_SHADOW_OFFSET;
- break;
- 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;
- default:
- WARN_ON(1);
- return NULL;
- }
- return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset);
+ maddr &= XRANGE_SHADOW_MASK;
+ switch (xrange) {
+ case XKPRANGE_CC_SEG:
+ offset = XKPRANGE_CC_SHADOW_OFFSET;
+ break;
+ 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;
+ default:
+ WARN_ON(1);
+ return NULL;
}
+
+ return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset);
+}
+
+void *kasan_mem_to_shadow(const void *addr)
+{
+ if (kasan_arch_is_ready())
+ return mem_to_shadow(addr);
+ else
+ return (void *)(kasan_early_shadow_page);
}
const void *kasan_shadow_to_mem(const void *shadow_addr)
@@ -295,10 +299,8 @@ void __init kasan_init(void)
/* Maps everything to a single page of zeroes */
kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, true);
- kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_START),
- kasan_mem_to_shadow((void *)KFENCE_AREA_END));
-
- kasan_early_stage = false;
+ kasan_populate_early_shadow(mem_to_shadow((void *)VMALLOC_START),
+ mem_to_shadow((void *)KFENCE_AREA_END));
/* Populate the linear mapping */
for_each_mem_range(i, &pa_start, &pa_end) {
@@ -308,13 +310,13 @@ void __init kasan_init(void)
if (start >= end)
break;
- kasan_map_populate((unsigned long)kasan_mem_to_shadow(start),
- (unsigned long)kasan_mem_to_shadow(end), NUMA_NO_NODE);
+ kasan_map_populate((unsigned long)mem_to_shadow(start),
+ (unsigned long)mem_to_shadow(end), NUMA_NO_NODE);
}
/* Populate modules mapping */
- kasan_map_populate((unsigned long)kasan_mem_to_shadow((void *)MODULES_VADDR),
- (unsigned long)kasan_mem_to_shadow((void *)MODULES_END), NUMA_NO_NODE);
+ kasan_map_populate((unsigned long)mem_to_shadow((void *)MODULES_VADDR),
+ (unsigned long)mem_to_shadow((void *)MODULES_END), NUMA_NO_NODE);
/*
* KAsan may reuse the contents of kasan_early_shadow_pte directly, so we
* should make sure that it maps the zero page read-only.
@@ -329,5 +331,6 @@ void __init kasan_init(void)
/* At this point kasan is fully initialized. Enable error messages */
init_task.kasan_depth = 0;
+ kasan_early_stage = false;
pr_info("KernelAddressSanitizer initialized.\n");
}
--
2.52.0
On Sun, Feb 15, 2026 at 10:09:53PM +0800, Huacai Chen wrote: > From: Tiezhu Yang <yangtiezhu@loongson.cn> > > commit 5ec5ac4ca27e4daa234540ac32f9fc5219377d53 upstream. > > "kasan_early_stage = false" indicates that kasan is fully initialized, > so it should be put at end of kasan_init(). > > Otherwise bringing up the primary CPU failed when CONFIG_KASAN is set > on PTW-enabled systems, here are the call chains: > > kernel_entry() > start_kernel() > setup_arch() > kasan_init() > kasan_early_stage = false > > The reason is PTW-enabled systems have speculative accesses which means > memory accesses to the shadow memory after kasan_init() may be executed > by hardware before. However, accessing shadow memory is safe only after > kasan fully initialized because kasan_init() uses a temporary PGD table > until we have populated all levels of shadow page tables and writen the > PGD register. Moving "kasan_early_stage = false" later can defer the > occasion of kasan_arch_is_ready(), so as to avoid speculative accesses > on shadow pages. > > After moving "kasan_early_stage = false" to the end, kasan_init() can no > longer call kasan_mem_to_shadow() for shadow address conversion because > it will always return kasan_early_shadow_page. On the other hand, we > should keep the current logic of kasan_mem_to_shadow() for both the early > and final stage because there may be instrumentation before kasan_init(). > > To solve this, we factor out a new mem_to_shadow() function from current > kasan_mem_to_shadow() for the shadow address conversion in kasan_init(). The subject line AND the commit text here do not match the upstream commit AND the diff is different and you did not explain what changed or why :( So as-is, I can't take this, sorry. thanks, greg k-h
Hi, Greg, On Mon, Feb 16, 2026 at 5:52 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Sun, Feb 15, 2026 at 10:09:53PM +0800, Huacai Chen wrote: > > From: Tiezhu Yang <yangtiezhu@loongson.cn> > > > > commit 5ec5ac4ca27e4daa234540ac32f9fc5219377d53 upstream. > > > > "kasan_early_stage = false" indicates that kasan is fully initialized, > > so it should be put at end of kasan_init(). > > > > Otherwise bringing up the primary CPU failed when CONFIG_KASAN is set > > on PTW-enabled systems, here are the call chains: > > > > kernel_entry() > > start_kernel() > > setup_arch() > > kasan_init() > > kasan_early_stage = false > > > > The reason is PTW-enabled systems have speculative accesses which means > > memory accesses to the shadow memory after kasan_init() may be executed > > by hardware before. However, accessing shadow memory is safe only after > > kasan fully initialized because kasan_init() uses a temporary PGD table > > until we have populated all levels of shadow page tables and writen the > > PGD register. Moving "kasan_early_stage = false" later can defer the > > occasion of kasan_arch_is_ready(), so as to avoid speculative accesses > > on shadow pages. > > > > After moving "kasan_early_stage = false" to the end, kasan_init() can no > > longer call kasan_mem_to_shadow() for shadow address conversion because > > it will always return kasan_early_shadow_page. On the other hand, we > > should keep the current logic of kasan_mem_to_shadow() for both the early > > and final stage because there may be instrumentation before kasan_init(). > > > > To solve this, we factor out a new mem_to_shadow() function from current > > kasan_mem_to_shadow() for the shadow address conversion in kasan_init(). > > The subject line AND the commit text here do not match the upstream > commit AND the diff is different and you did not explain what changed or > why :( The subject line is exactly the same as the upstream commit (no difference). The changes in the commit message is because the text of the patch has changed (this is why the upstream commit cannot be applied), and I think the commit message should exactly reflect the text. Huacai > > So as-is, I can't take this, sorry. > > thanks, > > greg k-h
On Mon, Feb 16, 2026 at 06:09:31PM +0800, Huacai Chen wrote: > Hi, Greg, > > On Mon, Feb 16, 2026 at 5:52 PM Greg Kroah-Hartman > <gregkh@linuxfoundation.org> wrote: > > > > On Sun, Feb 15, 2026 at 10:09:53PM +0800, Huacai Chen wrote: > > > From: Tiezhu Yang <yangtiezhu@loongson.cn> > > > > > > commit 5ec5ac4ca27e4daa234540ac32f9fc5219377d53 upstream. > > > > > > "kasan_early_stage = false" indicates that kasan is fully initialized, > > > so it should be put at end of kasan_init(). > > > > > > Otherwise bringing up the primary CPU failed when CONFIG_KASAN is set > > > on PTW-enabled systems, here are the call chains: > > > > > > kernel_entry() > > > start_kernel() > > > setup_arch() > > > kasan_init() > > > kasan_early_stage = false > > > > > > The reason is PTW-enabled systems have speculative accesses which means > > > memory accesses to the shadow memory after kasan_init() may be executed > > > by hardware before. However, accessing shadow memory is safe only after > > > kasan fully initialized because kasan_init() uses a temporary PGD table > > > until we have populated all levels of shadow page tables and writen the > > > PGD register. Moving "kasan_early_stage = false" later can defer the > > > occasion of kasan_arch_is_ready(), so as to avoid speculative accesses > > > on shadow pages. > > > > > > After moving "kasan_early_stage = false" to the end, kasan_init() can no > > > longer call kasan_mem_to_shadow() for shadow address conversion because > > > it will always return kasan_early_shadow_page. On the other hand, we > > > should keep the current logic of kasan_mem_to_shadow() for both the early > > > and final stage because there may be instrumentation before kasan_init(). > > > > > > To solve this, we factor out a new mem_to_shadow() function from current > > > kasan_mem_to_shadow() for the shadow address conversion in kasan_init(). > > > > The subject line AND the commit text here do not match the upstream > > commit AND the diff is different and you did not explain what changed or > > why :( > The subject line is exactly the same as the upstream commit (no difference). > > The changes in the commit message is because the text of the patch has > changed (this is why the upstream commit cannot be applied), and I > think the commit message should exactly reflect the text. No, the commit message should match exactly what is merged in Linus's tree and then the comments before your new signed-off-by should describe what is different here from what is in Linus's tree. Don't rework changelog text for stable backports, that only confuses everyone involved and it makes it look like you are doing different things than expected (i.e. attempting to get stuff that is NOT upstream merged.) thanks, greg k-h
On Mon, Feb 16, 2026 at 6:20 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Mon, Feb 16, 2026 at 06:09:31PM +0800, Huacai Chen wrote: > > Hi, Greg, > > > > On Mon, Feb 16, 2026 at 5:52 PM Greg Kroah-Hartman > > <gregkh@linuxfoundation.org> wrote: > > > > > > On Sun, Feb 15, 2026 at 10:09:53PM +0800, Huacai Chen wrote: > > > > From: Tiezhu Yang <yangtiezhu@loongson.cn> > > > > > > > > commit 5ec5ac4ca27e4daa234540ac32f9fc5219377d53 upstream. > > > > > > > > "kasan_early_stage = false" indicates that kasan is fully initialized, > > > > so it should be put at end of kasan_init(). > > > > > > > > Otherwise bringing up the primary CPU failed when CONFIG_KASAN is set > > > > on PTW-enabled systems, here are the call chains: > > > > > > > > kernel_entry() > > > > start_kernel() > > > > setup_arch() > > > > kasan_init() > > > > kasan_early_stage = false > > > > > > > > The reason is PTW-enabled systems have speculative accesses which means > > > > memory accesses to the shadow memory after kasan_init() may be executed > > > > by hardware before. However, accessing shadow memory is safe only after > > > > kasan fully initialized because kasan_init() uses a temporary PGD table > > > > until we have populated all levels of shadow page tables and writen the > > > > PGD register. Moving "kasan_early_stage = false" later can defer the > > > > occasion of kasan_arch_is_ready(), so as to avoid speculative accesses > > > > on shadow pages. > > > > > > > > After moving "kasan_early_stage = false" to the end, kasan_init() can no > > > > longer call kasan_mem_to_shadow() for shadow address conversion because > > > > it will always return kasan_early_shadow_page. On the other hand, we > > > > should keep the current logic of kasan_mem_to_shadow() for both the early > > > > and final stage because there may be instrumentation before kasan_init(). > > > > > > > > To solve this, we factor out a new mem_to_shadow() function from current > > > > kasan_mem_to_shadow() for the shadow address conversion in kasan_init(). > > > > > > The subject line AND the commit text here do not match the upstream > > > commit AND the diff is different and you did not explain what changed or > > > why :( > > The subject line is exactly the same as the upstream commit (no difference). > > > > The changes in the commit message is because the text of the patch has > > changed (this is why the upstream commit cannot be applied), and I > > think the commit message should exactly reflect the text. > > No, the commit message should match exactly what is merged in Linus's > tree and then the comments before your new signed-off-by should describe > what is different here from what is in Linus's tree. Don't rework > changelog text for stable backports, that only confuses everyone > involved and it makes it look like you are doing different things than > expected (i.e. attempting to get stuff that is NOT upstream merged.) OK, let me try a V2. Huacai > > thanks, > > greg k-h
© 2016 - 2026 Red Hat, Inc.