Subject: Re: KASAN debug kernel fails to boot at early stage when CONFIG_SMP=y is set (kernel 6.5-rc5, PowerMac G4 3,6)

From: Erhard Furtner <[email-masked]>
Date: Tue, 12 Sep 2023 17:59:41 +0200

On Tue, 12 Sep 2023 07:47:50 +0000
Christophe Leroy <[email-masked]> wrote:

> I suspect something wrong when we set the BATs.
> 
> Can you try with the following additional traces:
> 
> diff --git a/arch/powerpc/mm/kasan/book3s_32.c 
> b/arch/powerpc/mm/kasan/book3s_32.c
> index 450a67ef0bbe..9954b7a3b7ae 100644
> --- a/arch/powerpc/mm/kasan/book3s_32.c
> +++ b/arch/powerpc/mm/kasan/book3s_32.c
> @@ -15,6 +15,7 @@ int __init kasan_init_region(void *start, size_t size)
>   	phys_addr_t phys;
>   	int ret;
> 
> +	pr_err("%s: %px %x %lx %lx\n", __func__, start, size, k_start, k_end);
>   	while (k_nobat < k_end) {
>   		unsigned int k_size = bat_block_size(k_nobat, k_end);
>   		int idx = find_free_bat();
> @@ -28,6 +29,7 @@ int __init kasan_init_region(void *start, size_t size)
>   		if (!phys)
>   			break;
> 
> +		pr_err("%s: setbat %d %lx %x %x\n", __func__, idx, k_nobat, phys, 
> k_size);
>   		setbat(idx, k_nobat, phys, k_size, PAGE_KERNEL);
>   		k_nobat += k_size;
>   	}
> @@ -47,6 +49,7 @@ int __init kasan_init_region(void *start, size_t size)
> 
>   	kasan_update_early_region(k_start, k_nobat, __pte(0));
> 
> +	pr_err("%s: loop %lx %lx\n", __func__, k_nobat, k_end);
>   	for (k_cur = k_nobat; k_cur < k_end; k_cur += PAGE_SIZE) {
>   		pmd_t *pmd = pmd_off_k(k_cur);
>   		pte_t pte = pfn_pte(PHYS_PFN(phys + k_cur - k_nobat), PAGE_KERNEL);
> 
> 
> You'd then get something like:
> 
> Total memory = 2048MB; using 4096kB for hash table
> Activating Kernel Userspace Access Protection
> Activating Kernel Userspace Execution Prevention
> Linux version 6.6.0-rc1+ ([email-masked]) 
> (powerpc64-linux-gcc (GCC) 12.2.0, GNU ld (GNU Binutils) 2.39) #461 Tue 
> Sep 12 09:37:11 CEST 2023
> kasan_init_region: c0000000 30000000 f8000000 fe000000
> kasan_init_region: setbat 3 f8000000 7c000000 4000000
> kasan_init_region: loop fc000000 fe000000
> KASAN init done

Applied this patch on top of 6.6-rc1, your old pr_info() patch and Michaels patch.

This way booting gets stuck at:
printk: bootconsole [udbg0] enabled
Total memory = 2048MB; using 4096kB for hash table
mapin_ram:125
mmu_mapin_ram:169 0 30000000 1400000 2000000
__mmu_mapin_ram:146 0 1400000
__mmu_mapin_ram:155 1400000
__mmu_mapin_ram:146 1400000 30000000
__mmu_mapin_ram:155 20000000
__mapin_ram_chunk:107 20000000 30000000
__mapin_ram_chunk:117
mapin_ram:134
btext_unmap:129

Having moved btext_unmap() after memblock_set_current_limit(lowmem_end_addr) in init_32.c I get:

printk: bootconsole [udbg0] enabled
Total memory = 2048MB; using 4096kB for hash table
mapin_ram:125
mmu_mapin_ram:169 0 30000000 1400000 2000000
__mmu_mapin_ram:146 0 1400000
__mmu_mapin_ram:155 1400000
__mmu_mapin_ram:146 1400000 30000000
__mmu_mapin_ram:155 20000000
__mapin_ram_chunk:107 20000000 30000000
__mapin_ram_chunk:117
mapin_ram:134
kasan_mmu_init:129
kasan_mmu_init:132 0
kasan_mmu_init:137
btext_unmap:129

Changing the already moved btext_unmap() to btext_map() I get:

printk: bootconsole [udbg0] enabled
Total memory = 2048MB; using 4096kB for hash table
mapin_ram:125
mmu_mapin_ram:169 0 30000000 1400000 2000000
__mmu_mapin_ram:146 0 1400000
__mmu_mapin_ram:155 1400000
__mmu_mapin_ram:146 1400000 30000000
__mmu_mapin_ram:155 20000000
__mapin_ram_chunk:107 20000000 30000000
__mapin_ram_chunk:117
mapin_ram:134
kasan_mmu_init:129
kasan_mmu_init:132 0
kasan_mmu_init:137
ioremap() called early from btext_map+0x64/0xdc. Use early_ioremap() instead
Linux version 6.6.0-rc1-PMacG4-dirty (root@T1000) (gcc (Gentoo 12.3.1_p20230526 p2) 12.3.1 20230526, GNU ld (Gentoo 2.40 p7) 2.40.0) #5 SMP Tue Sep 12 16:50:47 CEST 2023
kasan_init_region: c0000000 30000000 f8000000 fe000000
kasan_init_region: loop f8000000 fe000000

So I get no "kasan_init_region: setbat" line and don't reach "KASAN init done".

Regards,
Erhard