2024-05-22 06:31:14

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 0/4] LoongArch: Bootloader interface fixes

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 <[email protected]>
---
Changes in v2:
- Enhance PATCH 3-4 based on off list discussions with Huacai & co.
- Link to v1: https://lore.kernel.org/r/[email protected]

---
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: Override higher address bits in JUMP_VIRT_ADDR

arch/loongarch/include/asm/stackframe.h | 2 +-
arch/loongarch/kernel/head.S | 2 +-
arch/loongarch/kernel/setup.c | 6 ++++--
arch/loongarch/kernel/smp.c | 5 ++++-
drivers/firmware/efi/libstub/loongarch.c | 2 +-
5 files changed, 11 insertions(+), 6 deletions(-)
---
base-commit: 124cfbcd6d185d4f50be02d5f5afe61578916773
change-id: 20240521-loongarch-booting-fixes-366e13e7ca55

Best regards,
--
Jiaxun Yang <[email protected]>



2024-05-22 06:31:25

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 2/4] LoongArch: smp: Add all CPUs enabled by fdt to NUMA node 0

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: [email protected]
Fixes: 88d4d957edc7 ("LoongArch: Add FDT booting support from efi system table")
Signed-off-by: Jiaxun Yang <[email protected]>
---
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;

--
2.43.0


2024-05-22 06:31:27

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 3/4] LoongArch: Fix entry point in image header

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 and amend entry
calculation logic in libstub accordingly.

Note that due to relocation restriction TO_PHYS can't be used
in assembly, we can only do plus and minus here.

Cc: [email protected]
Signed-off-by: Jiaxun Yang <[email protected]>
---
v2: Fix efistub
---
arch/loongarch/kernel/head.S | 2 +-
drivers/firmware/efi/libstub/loongarch.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

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 */
diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
index 684c9354637c..60c145121393 100644
--- a/drivers/firmware/efi/libstub/loongarch.c
+++ b/drivers/firmware/efi/libstub/loongarch.c
@@ -41,7 +41,7 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
unsigned long __weak kernel_entry_address(unsigned long kernel_addr,
efi_loaded_image_t *image)
{
- return *(unsigned long *)(kernel_addr + 8) - VMLINUX_LOAD_ADDRESS + kernel_addr;
+ return *(unsigned long *)(kernel_addr + 8) - TO_PHYS(VMLINUX_LOAD_ADDRESS) + kernel_addr;
}

efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,

--
2.43.0


2024-05-22 06:31:41

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH v2 4/4] LoongArch: Override higher address bits in JUMP_VIRT_ADDR

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
1:1 mapping addresses or firmware's DMW is configured exactly
same as kernel. Still, we should not rely on such assumption.

Fix by overriding higher bits in address comes from pcaddi,
so we can get rid of or operator.

Cc: [email protected]
Signed-off-by: Jiaxun Yang <[email protected]>
---
v2: Overriding address with bstrins
---
arch/loongarch/include/asm/stackframe.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h
index 45b507a7b06f..51dec8b17d16 100644
--- a/arch/loongarch/include/asm/stackframe.h
+++ b/arch/loongarch/include/asm/stackframe.h
@@ -42,7 +42,7 @@
.macro JUMP_VIRT_ADDR temp1 temp2
li.d \temp1, CACHE_BASE
pcaddi \temp2, 0
- or \temp1, \temp1, \temp2
+ bstrins.d \temp1, \temp2, (DMW_PABITS - 1), 0
jirl zero, \temp1, 0xc
.endm


--
2.43.0


2024-05-22 07:59:39

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH v2 4/4] LoongArch: Override higher address bits in JUMP_VIRT_ADDR

Hi, Jiaxun,

On Wed, May 22, 2024 at 2:30 PM Jiaxun Yang <[email protected]> wrote:
>
> 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
> 1:1 mapping addresses or firmware's DMW is configured exactly
> same as kernel. Still, we should not rely on such assumption.
>
> Fix by overriding higher bits in address comes from pcaddi,
> so we can get rid of or operator.
>
> Cc: [email protected]
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> v2: Overriding address with bstrins
> ---
> arch/loongarch/include/asm/stackframe.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h
> index 45b507a7b06f..51dec8b17d16 100644
> --- a/arch/loongarch/include/asm/stackframe.h
> +++ b/arch/loongarch/include/asm/stackframe.h
> @@ -42,7 +42,7 @@
> .macro JUMP_VIRT_ADDR temp1 temp2
> li.d \temp1, CACHE_BASE
> pcaddi \temp2, 0
> - or \temp1, \temp1, \temp2
> + bstrins.d \temp1, \temp2, (DMW_PABITS - 1), 0
> jirl zero, \temp1, 0xc
> .endm
Can we align the first parameter about the first parameter?

Huacai
>
>
> --
> 2.43.0
>

2024-05-22 08:00:53

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH v2 3/4] LoongArch: Fix entry point in image header

Hi, Jiaxun,

On Wed, May 22, 2024 at 2:30 PM Jiaxun Yang <[email protected]> wrote:
>
> 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 and amend entry
> calculation logic in libstub accordingly.
>
> Note that due to relocation restriction TO_PHYS can't be used
> in assembly, we can only do plus and minus here.
>
> Cc: [email protected]
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> v2: Fix efistub
> ---
> arch/loongarch/kernel/head.S | 2 +-
> drivers/firmware/efi/libstub/loongarch.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> 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 */
It could be better to calculate it in the link script, just as _kernel_asize.

Huacai

> .dword _kernel_asize /* Kernel image effective size */
> .quad PHYS_LINK_KADDR /* Kernel image load offset from start of RAM */
> .org 0x38 /* 0x20 ~ 0x37 reserved */
> diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
> index 684c9354637c..60c145121393 100644
> --- a/drivers/firmware/efi/libstub/loongarch.c
> +++ b/drivers/firmware/efi/libstub/loongarch.c
> @@ -41,7 +41,7 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
> unsigned long __weak kernel_entry_address(unsigned long kernel_addr,
> efi_loaded_image_t *image)
> {
> - return *(unsigned long *)(kernel_addr + 8) - VMLINUX_LOAD_ADDRESS + kernel_addr;
> + return *(unsigned long *)(kernel_addr + 8) - TO_PHYS(VMLINUX_LOAD_ADDRESS) + kernel_addr;
> }
>
> efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
>
> --
> 2.43.0
>
>

2024-05-22 08:08:32

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH v2 2/4] LoongArch: smp: Add all CPUs enabled by fdt to NUMA node 0

Hi, Jiaxun,

On Wed, May 22, 2024 at 2:30 PM Jiaxun Yang <[email protected]> wrote:
>
> 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: [email protected]
> Fixes: 88d4d957edc7 ("LoongArch: Add FDT booting support from efi system table")
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> 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);
What's wrong exactly? Real machine has no problem here, and at least
numa_add_cpu() should not be called for non-zero cpu so early, because
it need per-cpu area be setup. I guess the root cause is that there is
something wrong and "cpuid == loongson_sysconf.boot_cpu_id" is
skipped.

Huacai

> }
>
> loongson_sysconf.nr_cpus = num_processors;
>
> --
> 2.43.0
>