mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/1] LoongArch: kexec: avoid overwriting QEMU's machine FDT at 0x100000
@ 2026-05-28 13:58 George Guo
  2026-05-29  4:25 ` Huacai Chen
  0 siblings, 1 reply; 5+ messages in thread
From: George Guo @ 2026-05-28 13:58 UTC (permalink / raw)
  To: chenhuacai; +Cc: kernel, loongarch, linux-kernel, George Guo

From: George Guo <guodongtai@kylinos.cn>

QEMU places its machine FDT at physical address 0x100000 when booting
with '-kernel'.  KEXEC_CONTROL_CODE was defined at the same address, so
machine_kexec_prepare() overwrites the FDT with the relocation trampoline
before jumping to the new kernel.

The kexec'd kernel's fdt_setup() reads the FDT pointer from the EFI
config table (FDTPTR = 0x100000) and finds trampoline code instead of a
valid FDT, so earlycon auto-detection fails and the second kernel boots
silently with no console output.

Move KEXEC_CONTROL_CODE to 0x180000, which is still within the first 2MB
reserved by memblock_init() and does not conflict with the QEMU FDT.

Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
 arch/loongarch/kernel/machine_kexec.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
index d7fafda1d541..44df7dbd3de5 100644
--- a/arch/loongarch/kernel/machine_kexec.c
+++ b/arch/loongarch/kernel/machine_kexec.c
@@ -21,8 +21,13 @@
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 
-/* 0x100000 ~ 0x200000 is safe */
-#define KEXEC_CONTROL_CODE	TO_CACHE(0x100000UL)
+/*
+ * Both addresses are within the first 2MB which is always reserved by
+ * memblock_init().  Avoid 0x100000 because QEMU places its machine FDT
+ * there when using '-kernel'; overwriting it silences earlycon in the
+ * kexec'd kernel.
+ */
+#define KEXEC_CONTROL_CODE	TO_CACHE(0x180000UL)
 #define KEXEC_CMDLINE_ADDR	TO_CACHE(0x108000UL)
 
 static unsigned long reboot_code_buffer;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] LoongArch: kexec: avoid overwriting QEMU's machine FDT at 0x100000
  2026-05-28 13:58 [PATCH 1/1] LoongArch: kexec: avoid overwriting QEMU's machine FDT at 0x100000 George Guo
@ 2026-05-29  4:25 ` Huacai Chen
  2026-05-29  6:19   ` Bibo Mao
  2026-05-29  6:40   ` Bibo Mao
  0 siblings, 2 replies; 5+ messages in thread
From: Huacai Chen @ 2026-05-29  4:25 UTC (permalink / raw)
  To: George Guo; +Cc: kernel, loongarch, linux-kernel, George Guo

Hi, George,

On Thu, May 28, 2026 at 9:58 PM George Guo <dongtai.guo@linux.dev> wrote:
>
> From: George Guo <guodongtai@kylinos.cn>
>
> QEMU places its machine FDT at physical address 0x100000 when booting
> with '-kernel'.  KEXEC_CONTROL_CODE was defined at the same address, so
> machine_kexec_prepare() overwrites the FDT with the relocation trampoline
> before jumping to the new kernel.
>
> The kexec'd kernel's fdt_setup() reads the FDT pointer from the EFI
> config table (FDTPTR = 0x100000) and finds trampoline code instead of a
> valid FDT, so earlycon auto-detection fails and the second kernel boots
> silently with no console output.
>
> Move KEXEC_CONTROL_CODE to 0x180000, which is still within the first 2MB
> reserved by memblock_init() and does not conflict with the QEMU FDT.
Modify QEMU seems better.

For kernel, the kexec code is introduced by
4a03b2ac06a5bcae29371866d9d11f5bfd4c9188 ("LoongArch: Add kexec
support") at Oct, 12, 2022.

For QEMU, current FDT is introduced by
6042385149a0fb3f4a51d264fc3dc42775819c79 ("hw/loongarch: Init efi_fdt
table") at April, 26, 2024.
And earlier history is 46b21de238c643ea098f2dcffe493abd135f7d89
("hw/loongarch: Fix loongarch fdt addr confict") which move FDT from
2MB (0x200000) to 1MB(0x100000).
And the earliest QEMU FDT  address is 0x1c400000....

QEMU FDT has changed many times while kexec keep the same always, and
the current FDT address is later than kernel (which means QEMU
conflict with kexec, not kexec conflict with QEMU). So I suggest to
move QEMU FDT to 0x180000.


Huacai

>
> Signed-off-by: George Guo <guodongtai@kylinos.cn>
> ---
>  arch/loongarch/kernel/machine_kexec.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
> index d7fafda1d541..44df7dbd3de5 100644
> --- a/arch/loongarch/kernel/machine_kexec.c
> +++ b/arch/loongarch/kernel/machine_kexec.c
> @@ -21,8 +21,13 @@
>  #include <asm/cacheflush.h>
>  #include <asm/page.h>
>
> -/* 0x100000 ~ 0x200000 is safe */
> -#define KEXEC_CONTROL_CODE     TO_CACHE(0x100000UL)
> +/*
> + * Both addresses are within the first 2MB which is always reserved by
> + * memblock_init().  Avoid 0x100000 because QEMU places its machine FDT
> + * there when using '-kernel'; overwriting it silences earlycon in the
> + * kexec'd kernel.
> + */
> +#define KEXEC_CONTROL_CODE     TO_CACHE(0x180000UL)
>  #define KEXEC_CMDLINE_ADDR     TO_CACHE(0x108000UL)
>
>  static unsigned long reboot_code_buffer;
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] LoongArch: kexec: avoid overwriting QEMU's machine FDT at 0x100000
  2026-05-29  4:25 ` Huacai Chen
@ 2026-05-29  6:19   ` Bibo Mao
  2026-05-29  6:40   ` Bibo Mao
  1 sibling, 0 replies; 5+ messages in thread
From: Bibo Mao @ 2026-05-29  6:19 UTC (permalink / raw)
  To: Huacai Chen, George Guo; +Cc: kernel, loongarch, linux-kernel, George Guo



On 2026/5/29 下午12:25, Huacai Chen wrote:
> Hi, George,
> 
> On Thu, May 28, 2026 at 9:58 PM George Guo <dongtai.guo@linux.dev> wrote:
>>
>> From: George Guo <guodongtai@kylinos.cn>
>>
>> QEMU places its machine FDT at physical address 0x100000 when booting
>> with '-kernel'.  KEXEC_CONTROL_CODE was defined at the same address, so
>> machine_kexec_prepare() overwrites the FDT with the relocation trampoline
>> before jumping to the new kernel.
>>
>> The kexec'd kernel's fdt_setup() reads the FDT pointer from the EFI
>> config table (FDTPTR = 0x100000) and finds trampoline code instead of a
>> valid FDT, so earlycon auto-detection fails and the second kernel boots
>> silently with no console output.
>>
>> Move KEXEC_CONTROL_CODE to 0x180000, which is still within the first 2MB
>> reserved by memblock_init() and does not conflict with the QEMU FDT.
> Modify QEMU seems better.
> 
> For kernel, the kexec code is introduced by
> 4a03b2ac06a5bcae29371866d9d11f5bfd4c9188 ("LoongArch: Add kexec
> support") at Oct, 12, 2022.
> 
> For QEMU, current FDT is introduced by
> 6042385149a0fb3f4a51d264fc3dc42775819c79 ("hw/loongarch: Init efi_fdt
> table") at April, 26, 2024.
> And earlier history is 46b21de238c643ea098f2dcffe493abd135f7d89
> ("hw/loongarch: Fix loongarch fdt addr confict") which move FDT from
> 2MB (0x200000) to 1MB(0x100000).
> And the earliest QEMU FDT  address is 0x1c400000....
> 
> QEMU FDT has changed many times while kexec keep the same always, and
> the current FDT address is later than kernel (which means QEMU
> conflict with kexec, not kexec conflict with QEMU). So I suggest to
> move QEMU FDT to 0x180000.
It is almost impossible to modify the base address of FDT, there will be 
compatible issue with UEFI BIOS. The virt UEFI BIOS searches this fixed 
address for FDT tree parsing.

Regards
Bibo Mao
> 
> 
> Huacai
> 
>>
>> Signed-off-by: George Guo <guodongtai@kylinos.cn>
>> ---
>>   arch/loongarch/kernel/machine_kexec.c | 9 +++++++--
>>   1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
>> index d7fafda1d541..44df7dbd3de5 100644
>> --- a/arch/loongarch/kernel/machine_kexec.c
>> +++ b/arch/loongarch/kernel/machine_kexec.c
>> @@ -21,8 +21,13 @@
>>   #include <asm/cacheflush.h>
>>   #include <asm/page.h>
>>
>> -/* 0x100000 ~ 0x200000 is safe */
>> -#define KEXEC_CONTROL_CODE     TO_CACHE(0x100000UL)
>> +/*
>> + * Both addresses are within the first 2MB which is always reserved by
>> + * memblock_init().  Avoid 0x100000 because QEMU places its machine FDT
>> + * there when using '-kernel'; overwriting it silences earlycon in the
>> + * kexec'd kernel.
>> + */
>> +#define KEXEC_CONTROL_CODE     TO_CACHE(0x180000UL)
>>   #define KEXEC_CMDLINE_ADDR     TO_CACHE(0x108000UL)
>>
>>   static unsigned long reboot_code_buffer;
>> --
>> 2.25.1
>>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] LoongArch: kexec: avoid overwriting QEMU's machine FDT at 0x100000
  2026-05-29  4:25 ` Huacai Chen
  2026-05-29  6:19   ` Bibo Mao
@ 2026-05-29  6:40   ` Bibo Mao
  2026-06-01  3:38     ` [PATCH v2] LoongArch: kexec: drop hardcoded addresses to avoid QEMU FDT conflict George Guo
  1 sibling, 1 reply; 5+ messages in thread
From: Bibo Mao @ 2026-05-29  6:40 UTC (permalink / raw)
  To: Huacai Chen, George Guo; +Cc: kernel, loongarch, linux-kernel, George Guo



On 2026/5/29 下午12:25, Huacai Chen wrote:
> Hi, George,
> 
> On Thu, May 28, 2026 at 9:58 PM George Guo <dongtai.guo@linux.dev> wrote:
>>
>> From: George Guo <guodongtai@kylinos.cn>
>>
>> QEMU places its machine FDT at physical address 0x100000 when booting
>> with '-kernel'.  KEXEC_CONTROL_CODE was defined at the same address, so
>> machine_kexec_prepare() overwrites the FDT with the relocation trampoline
>> before jumping to the new kernel.
>>
>> The kexec'd kernel's fdt_setup() reads the FDT pointer from the EFI
>> config table (FDTPTR = 0x100000) and finds trampoline code instead of a
>> valid FDT, so earlycon auto-detection fails and the second kernel boots
>> silently with no console output.
>>
>> Move KEXEC_CONTROL_CODE to 0x180000, which is still within the first 2MB
>> reserved by memblock_init() and does not conflict with the QEMU FDT.
> Modify QEMU seems better.
> 
> For kernel, the kexec code is introduced by
> 4a03b2ac06a5bcae29371866d9d11f5bfd4c9188 ("LoongArch: Add kexec
> support") at Oct, 12, 2022.
> 
> For QEMU, current FDT is introduced by
> 6042385149a0fb3f4a51d264fc3dc42775819c79 ("hw/loongarch: Init efi_fdt
> table") at April, 26, 2024.
> And earlier history is 46b21de238c643ea098f2dcffe493abd135f7d89
> ("hw/loongarch: Fix loongarch fdt addr confict") which move FDT from
> 2MB (0x200000) to 1MB(0x100000).
> And the earliest QEMU FDT  address is 0x1c400000....
> 
> QEMU FDT has changed many times while kexec keep the same always, and
> the current FDT address is later than kernel (which means QEMU
> conflict with kexec, not kexec conflict with QEMU). So I suggest to
> move QEMU FDT to 0x180000.
what is method on other architectures for kexec control page?

Regards
Bibo Mao
> 
> 
> Huacai
> 
>>
>> Signed-off-by: George Guo <guodongtai@kylinos.cn>
>> ---
>>   arch/loongarch/kernel/machine_kexec.c | 9 +++++++--
>>   1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
>> index d7fafda1d541..44df7dbd3de5 100644
>> --- a/arch/loongarch/kernel/machine_kexec.c
>> +++ b/arch/loongarch/kernel/machine_kexec.c
>> @@ -21,8 +21,13 @@
>>   #include <asm/cacheflush.h>
>>   #include <asm/page.h>
>>
>> -/* 0x100000 ~ 0x200000 is safe */
>> -#define KEXEC_CONTROL_CODE     TO_CACHE(0x100000UL)
>> +/*
>> + * Both addresses are within the first 2MB which is always reserved by
>> + * memblock_init().  Avoid 0x100000 because QEMU places its machine FDT
>> + * there when using '-kernel'; overwriting it silences earlycon in the
>> + * kexec'd kernel.
>> + */
>> +#define KEXEC_CONTROL_CODE     TO_CACHE(0x180000UL)
>>   #define KEXEC_CMDLINE_ADDR     TO_CACHE(0x108000UL)
>>
>>   static unsigned long reboot_code_buffer;
>> --
>> 2.25.1
>>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] LoongArch: kexec: drop hardcoded addresses to avoid QEMU FDT conflict
  2026-05-29  6:40   ` Bibo Mao
@ 2026-06-01  3:38     ` George Guo
  0 siblings, 0 replies; 5+ messages in thread
From: George Guo @ 2026-06-01  3:38 UTC (permalink / raw)
  To: maobibo
  Cc: chenhuacai, dongtai.guo, guodongtai, kernel, linux-kernel, loongarch

From: George Guo <guodongtai@kylinos.cn>

KEXEC_CONTROL_CODE and KEXEC_CMDLINE_ADDR were hardcoded to fixed
physical addresses (0x100000 and 0x108000) in the first 2MB.  QEMU
places its machine FDT at 0x100000 when booting with '-kernel', so
machine_kexec_prepare() was overwriting the FDT with the relocation
trampoline.  The kexec'd kernel's fdt_setup() then found trampoline
code instead of a valid FDT, causing earlycon to fail silently.

Fix this by dropping the hardcoded addresses entirely.  Use the
control_code_page already allocated by the kexec core for the
relocation trampoline, and allocate a separate page via
kimage_alloc_control_pages() for the kernel command line copy.
kimage_alloc_control_pages() registers pages with the kexec core so
the page-copy loop skips them, providing the same safety guarantee
without depending on any specific physical location.

This follows the approach used by arm64 and riscv, which also rely on
the core-allocated control_code_page rather than fixed addresses.

Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
Changes in v2:
- Instead of moving KEXEC_CONTROL_CODE to a different fixed address,
  drop hardcoded addresses entirely.  Use the kexec core's already-
  allocated control_code_page for the trampoline and allocate a
  separate page via kimage_alloc_control_pages() for the command line,
  following the approach used by arm64 and riscv.

 arch/loongarch/kernel/machine_kexec.c | 31 ++++++++++++++++-----------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/arch/loongarch/kernel/machine_kexec.c b/arch/loongarch/kernel/machine_kexec.c
index d7fafda1d541..ad27fef098f1 100644
--- a/arch/loongarch/kernel/machine_kexec.c
+++ b/arch/loongarch/kernel/machine_kexec.c
@@ -21,10 +21,6 @@
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 
-/* 0x100000 ~ 0x200000 is safe */
-#define KEXEC_CONTROL_CODE	TO_CACHE(0x100000UL)
-#define KEXEC_CMDLINE_ADDR	TO_CACHE(0x108000UL)
-
 static unsigned long reboot_code_buffer;
 static cpumask_t cpus_in_crash = CPU_MASK_NONE;
 
@@ -43,19 +39,30 @@ int machine_kexec_prepare(struct kimage *kimage)
 {
 	int i;
 	char *bootloader = "kexec";
-	void *cmdline_ptr = (void *)KEXEC_CMDLINE_ADDR;
+	struct page *cmdline_page;
+	void *cmdline_ptr;
 
 	kimage->arch.efi_boot = fw_arg0;
 	kimage->arch.systable_ptr = fw_arg2;
 
+	/*
+	 * Allocate a separate control page for the kernel command line.
+	 * kimage_alloc_control_pages() ensures the page is not overwritten
+	 * by the kexec page-copy loop.
+	 */
+	cmdline_page = kimage_alloc_control_pages(kimage, 0);
+	if (!cmdline_page)
+		return -ENOMEM;
+	cmdline_ptr = page_to_virt(cmdline_page);
+
 	if (kimage->file_mode == 1) {
 		/*
-		 * kimage->cmdline_buf will be released in kexec_file_load, so copy
-		 * to the KEXEC_CMDLINE_ADDR safe area.
+		 * kimage->cmdline_buf will be released in kexec_file_load, so
+		 * copy it to the control page before it is freed.
 		 */
-		memcpy((void *)KEXEC_CMDLINE_ADDR, (void *)kimage->arch.cmdline_ptr,
-					strlen((char *)kimage->arch.cmdline_ptr) + 1);
-		kimage->arch.cmdline_ptr = (unsigned long)KEXEC_CMDLINE_ADDR;
+		memcpy(cmdline_ptr, (void *)kimage->arch.cmdline_ptr,
+		       strlen((char *)kimage->arch.cmdline_ptr) + 1);
+		kimage->arch.cmdline_ptr = (unsigned long)cmdline_ptr;
 	} else {
 		/* Find the command line */
 		for (i = 0; i < kimage->nr_segments; i++) {
@@ -73,9 +80,7 @@ int machine_kexec_prepare(struct kimage *kimage)
 	}
 
 	/* kexec/kdump need a safe page to save reboot_code_buffer */
-	kimage->control_code_page = virt_to_page((void *)KEXEC_CONTROL_CODE);
-
-	reboot_code_buffer = (unsigned long)page_address(kimage->control_code_page);
+	reboot_code_buffer = (unsigned long)page_to_virt(kimage->control_code_page);
 	memcpy((void *)reboot_code_buffer, relocate_new_kernel, relocate_new_kernel_size);
 
 #ifdef CONFIG_SMP
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-06-01  3:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-28 13:58 [PATCH 1/1] LoongArch: kexec: avoid overwriting QEMU's machine FDT at 0x100000 George Guo
2026-05-29  4:25 ` Huacai Chen
2026-05-29  6:19   ` Bibo Mao
2026-05-29  6:40   ` Bibo Mao
2026-06-01  3:38     ` [PATCH v2] LoongArch: kexec: drop hardcoded addresses to avoid QEMU FDT conflict George Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome