Hi all,
This series fixed some issues on bootloader - kernel interface.
The first two fixed booting with devicetree, the last two enhanced kernel's tolerance on different bootloader implementation.
Please review.
Thanks
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- Jiaxun Yang (4): LoongArch: Fix built-in DTB detection LoongArch: smp: Add all CPUs enabled by fdt to NUMA node 0 LoongArch: Fix entry point in image header LoongArch: Clear higher address bits in JUMP_VIRT_ADDR
arch/loongarch/include/asm/stackframe.h | 4 +++- arch/loongarch/kernel/head.S | 2 +- arch/loongarch/kernel/setup.c | 6 ++++-- arch/loongarch/kernel/smp.c | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) --- base-commit: 124cfbcd6d185d4f50be02d5f5afe61578916773 change-id: 20240521-loongarch-booting-fixes-366e13e7ca55
Best regards,
fdt_check_header(__dtb_start) will always success because kernel provided a dummy dtb here, thus fdt passed from firmware will never be taken.
Fix by trying to utilise __dtb_start only when CONFIG_BUILTIN_DTB is enabled.
Fixes: 5f346a6e5970 ("LoongArch: Allow device trees be built into the kernel") Cc: stable@vger.kernel.org Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/loongarch/kernel/setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 60e0fe97f61a..ea6d5db6c878 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -275,16 +275,18 @@ static void __init arch_reserve_crashkernel(void) static void __init fdt_setup(void) { #ifdef CONFIG_OF_EARLY_FLATTREE - void *fdt_pointer; + void *fdt_pointer = NULL;
/* ACPI-based systems do not require parsing fdt */ if (acpi_os_get_root_pointer()) return;
+#ifdef CONFIG_BUILTIN_DTB /* Prefer to use built-in dtb, checking its legality first. */ if (!fdt_check_header(__dtb_start)) fdt_pointer = __dtb_start; - else +#endif + if (!fdt_pointer) fdt_pointer = efi_fdt_pointer(); /* Fallback to firmware dtb */
if (!fdt_pointer || fdt_check_header(fdt_pointer))
NUMA enabled kernel on FDT based machine fails to boot because CPUs are all in NUMA_NO_NODE and mm subsystem won't accept that.
Fix by adding them to default NUMA node for now.
Cc: stable@vger.kernel.org Fixes: 88d4d957edc7 ("LoongArch: Add FDT booting support from efi system table") Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/loongarch/kernel/smp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 0dfe2388ef41..866757b76ecb 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -273,7 +273,6 @@ static void __init fdt_smp_setup(void)
if (cpuid == loongson_sysconf.boot_cpu_id) { cpu = 0; - numa_add_cpu(cpu); } else { cpu = cpumask_next_zero(-1, cpu_present_mask); } @@ -283,6 +282,10 @@ static void __init fdt_smp_setup(void) set_cpu_present(cpu, true); __cpu_number_map[cpuid] = cpu; __cpu_logical_map[cpu] = cpuid; + + early_numa_add_cpu(cpu, 0); + set_cpuid_to_node(cpuid, 0); + numa_add_cpu(cpu); }
loongson_sysconf.nr_cpus = num_processors;
Hi Jiaxun,
kernel test robot noticed the following build errors:
[auto build test ERROR on 124cfbcd6d185d4f50be02d5f5afe61578916773]
url: https://github.com/intel-lab-lkp/linux/commits/Jiaxun-Yang/LoongArch-Fix-bui... base: 124cfbcd6d185d4f50be02d5f5afe61578916773 patch link: https://lore.kernel.org/r/20240521-loongarch-booting-fixes-v1-2-659c201c0370... patch subject: [PATCH 2/4] LoongArch: smp: Add all CPUs enabled by fdt to NUMA node 0 config: loongarch-randconfig-001-20240524 (https://download.01.org/0day-ci/archive/20240524/202405240627.5Ey7vV8v-lkp@i...) compiler: loongarch64-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240524/202405240627.5Ey7vV8v-lkp@i...)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202405240627.5Ey7vV8v-lkp@intel.com/
All errors (new ones prefixed by >>):
arch/loongarch/kernel/smp.c: In function 'fdt_smp_setup':
arch/loongarch/kernel/smp.c:287:17: error: implicit declaration of function 'set_cpuid_to_node'; did you mean 'set_cpu_numa_node'? [-Werror=implicit-function-declaration]
287 | set_cpuid_to_node(cpuid, 0); | ^~~~~~~~~~~~~~~~~ | set_cpu_numa_node cc1: some warnings being treated as errors
vim +287 arch/loongarch/kernel/smp.c
259 260 static void __init fdt_smp_setup(void) 261 { 262 #ifdef CONFIG_OF 263 unsigned int cpu, cpuid; 264 struct device_node *node = NULL; 265 266 for_each_of_cpu_node(node) { 267 if (!of_device_is_available(node)) 268 continue; 269 270 cpuid = of_get_cpu_hwid(node, 0); 271 if (cpuid >= nr_cpu_ids) 272 continue; 273 274 if (cpuid == loongson_sysconf.boot_cpu_id) { 275 cpu = 0; 276 } else { 277 cpu = cpumask_next_zero(-1, cpu_present_mask); 278 } 279 280 num_processors++; 281 set_cpu_possible(cpu, true); 282 set_cpu_present(cpu, true); 283 __cpu_number_map[cpuid] = cpu; 284 __cpu_logical_map[cpu] = cpuid; 285 286 early_numa_add_cpu(cpu, 0);
287 set_cpuid_to_node(cpuid, 0);
288 numa_add_cpu(cpu); 289 } 290 291 loongson_sysconf.nr_cpus = num_processors; 292 set_bit(0, loongson_sysconf.cores_io_master); 293 #endif 294 } 295
Currently kernel entry in head.S is in DMW address range, firmware is instructed to jump to this address after loading the image.
However kernel should not make any assumption on firmware's DMW setting, thus the entry point should be a physical address falls into direct translation region.
Fix by applying a calculation to the entry. Note that due to relocation restriction TO_PHYS can't be used, we can only do plus and minus here.
Cc: stable@vger.kernel.org Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/loongarch/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index c4f7de2e2805..1a83564023e1 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -22,7 +22,7 @@ _head: .word MZ_MAGIC /* "MZ", MS-DOS header */ .org 0x8 - .dword kernel_entry /* Kernel entry point */ + .dword PHYS_LINK_KADDR + (kernel_entry - _head) /* Kernel entry point */ .dword _kernel_asize /* Kernel image effective size */ .quad PHYS_LINK_KADDR /* Kernel image load offset from start of RAM */ .org 0x38 /* 0x20 ~ 0x37 reserved */
In JUMP_VIRT_ADDR we are performing an or calculation on address value directly from pcaddi.
This will only work if we are currently running from direct translation addresses or firmware's DMW is configured exactly same as kernel. Still, we should not rely on such assumption.
Fix by clearing higher bits in address comes from pcaddi, so we can get real physcal address before applying or operator.
Cc: stable@vger.kernel.org Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/loongarch/include/asm/stackframe.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h index 45b507a7b06f..a325d20a4503 100644 --- a/arch/loongarch/include/asm/stackframe.h +++ b/arch/loongarch/include/asm/stackframe.h @@ -42,8 +42,10 @@ .macro JUMP_VIRT_ADDR temp1 temp2 li.d \temp1, CACHE_BASE pcaddi \temp2, 0 + PTR_SLL \temp2, \temp2, (BITS_PER_LONG - DMW_PABITS) + PTR_SRL \temp2, \temp2, (BITS_PER_LONG - DMW_PABITS) or \temp1, \temp1, \temp2 - jirl zero, \temp1, 0xc + jirl zero, \temp1, 0x14 .endm
.macro BACKUP_T0T1
linux-stable-mirror@lists.linaro.org