LoongArch: add KHO support and selftests
Subsystems (7)
v4 cover LoongArch: add KHO support and selftests
This series enables Kexec Handover (KHO) on LoongArch, making it the third architecture (after x86 and arm64) to set ARCH_SUPPORTS_KEXEC_HANDOVER. That is the only remaining gate for Live Update (LUO) to run on LoongArch.
The hard part is the transport: how the first kernel hands the KHO state (the KHO FDT and the scratch region) to the second kernel across kexec.
Why not the command line or an FDT
----------------------------------
LoongArch boots from EFI, but unlike arm64 and riscv its efistub does not build a boot FDT. It passes the EFI system table and the command line straight to the core kernel [1]. There is no /chosen node to carry the blob, so the arm64 path (drivers/of/kexec.c:kho_add_chosen() writes linux,kho-fdt and linux,kho-scratch; drivers/of/fdt.c:early_init_dt_check_kho() reads them) does not apply.
Two earlier transports were tried and rejected:
* v1 put the handover addresses on the kernel command line. Pratyush found that odd and asked for a DT-based alternative.
* v2/v3 synthesized an FDT and rewrote the DEVICE_TREE_GUID entry in the EFI config table so the generic FDT reader would find it. Pratyush called that "even more hacky" than the command line [2].
The v4 transport
----------------
v4 follows the x86 setup_data idea, in EFI terms. The first kernel packs the KHO state into a small struct (linux_efi_kho_data: fdt addr/size and scratch addr/size), appends a pointer to it under a dedicated LINUX_EFI_KHO_TABLE_GUID entry in a new EFI config table, loads both as kexec segments, and switches st->tables before jumping. The second kernel scans the config table for that GUID in setup_arch() and calls kho_populate() directly. This is the approach proposed in [3].
It addresses both objections: nothing is exposed on the command line, and no FDT is synthesized. It also meets Huacai's constraint: it reuses the EFI system table LoongArch already has, with no dependency on a boot FDT the efistub never creates.
Patch layout
------------
Patches 1-2 implement the transport. Patch 1 adds the EFI config table GUID and the handover struct to include/linux/efi.h. It is split out so the EFI maintainers can review it on its own. Patch 2 wires up the LoongArch side: ARCH_SUPPORTS_KEXEC_HANDOVER, the write side in machine_kexec_file.c, the st->tables switch in machine_kexec(), and the reader in setup_arch().
Patch 3 is a build fix for kernel/liveupdate/luo_session.c that the series depends on under CONFIG_KFENCE=y on LoongArch. It was sent standalone as v2 and acked by Mike. It is folded in here at his request to send it along with this series [4].
Patch 4 adds LoongArch vmtest support to the KHO selftests and folds in the two points Mike raised on v3 (use "VM" instead of the ad-hoc "virt machine"; run every architecture under timeout(1), not only LoongArch).
Patch 1 is aimed at the EFI tree. Patches 2-4 are aimed at the LoongArch and KHO trees. I expect the whole series to go through the KHO tree with Ard's and Huacai's acks.
Changes since v3
----------------
* Rework the transport: drop the synthesized FDT and the DEVICE_TREE_GUID rewrite. Pass the KHO state through a dedicated EFI configuration table GUID and call kho_populate() directly (patches 1, 2).
* Fold in the luo_session build fix (previously standalone v2, acked by Mike) as patch 3, at his request.
* selftests: address Mike's v3 review (use "VM"; always run under
timeout(1)).
* Rebase onto v7.2-rc6.
[1] Huacai Chen: https://lore.kernel.org/r/CAAhV-H5B6Mj2-AffkstJ4f8EEmvvPOGXoDy2QNudKD2kSz2XkA@mail.gmail.com/
[2] Pratyush Yadav: https://lore.kernel.org/r/[email protected]/
[3] https://lore.kernel.org/r/[email protected]/
[4] Mike Rapoport: https://lore.kernel.org/r/[email protected]/
George Guo (4):
efi: add a KHO configuration table GUID
LoongArch: kexec: add KHO support
liveupdate: luo_session: include linux/mm.h for virt/phys translation selftests/kho: add LoongArch vmtest support
arch/loongarch/Kconfig | 3 + arch/loongarch/include/asm/kexec.h | 7 ++ arch/loongarch/kernel/machine_kexec.c | 16 +++ arch/loongarch/kernel/machine_kexec_file.c | 131 +++++++++++++++++++++ arch/loongarch/kernel/setup.c | 41 +++++++ include/linux/efi.h | 24 ++++ kernel/liveupdate/luo_session.c | 1 + tools/testing/selftests/kho/loongarch.conf | 11 ++ tools/testing/selftests/kho/vmtest.sh | 22 ++-- 9 files changed, 249 insertions(+), 7 deletions(-) create mode 100644 tools/testing/selftests/kho/loongarch.conf
Signature · 1 line
2.53.0
PATCH v4 1/4 efi: add a KHO configuration table GUID
From: George Guo <[email protected]>
Kexec Handover (KHO) passes the address of its state FDT and of its scratch area from the current kernel to the next one. On architectures that boot with a device tree, the current kernel writes the linux,kho-fdt and linux,kho-scratch properties into /chosen, and the next kernel reads them back in early_init_dt_check_kho().
Architectures that boot through EFI without a device tree have no such channel. LoongArch is one of them: its efistub passes the EFI system table and the command line to the core kernel directly and never creates an FDT. x86 has the same problem and carries the state out of band instead, in a struct kho_data in the setup_data chain of its boot protocol.
Add an out-of-band channel for EFI: a LINUX_EFI_KHO_TABLE_GUID configuration table entry, under a randomly generated GUID, pointing at a struct linux_efi_kho_data. The
current kernel loads the structure and an extended configuration table as kexec segments, then switches the EFI system table to the new table before jumping. The next kernel finds the entry by GUID and calls kho_populate().
The structure carries no version field. An incompatible change to the layout must use a new GUID, which is the usual rule for EFI configuration tables. The handover payload itself is versioned separately, by the compatible string of the KHO state FDT that kho_populate() checks.
This patch adds the definitions only. LoongArch is the first user; any other EFI architecture without a boot FDT can use the same channel.
--- include/linux/efi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
include/linux/efi.h +24 -0
@@ -422,6 +422,7 @@ void efi_native_runtime_setup(void);#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17)#define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf)
@@ -1271,6 +1272,29 @@ struct linux_efi_memreserve {void __init efi_arch_mem_reserve (phys_addr_t addr,u64 size); +/* +* The LINUX_EFI_KHO_TABLE_GUID config table points to this structure. It +* carries the kexec handover (KHO) state from the current kernel to the next +* one: the addresses of the KHO state FDT and of the scratch area. +* +* This is the handover channel for architectures that boot through EFI without +* a device tree, where the /chosen linux,kho-fdt and linux,kho-scratch +* properties read by early_init_dt_check_kho() are not available. The current +* kernel loads the structure and an extended configuration table as kexec +* segments; the next kernel finds it by GUID and calls kho_populate(). +* +* The layout is an ABI between the two kernels and is fixed. It carries no +* version field: an incompatible change must use a new GUID, and the handover +* payload itself is versioned separately by the compatible string of the KHO +* state FDT, which kho_populate() checks. +*/ +struct linux_efi_kho_data { +u64 fdt_addr; +u64 fdt_size; +u64 scratch_addr; +u64 scratch_size; +} __packed; +/* * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided * to the kernel by an EFI boot loader. The table contains a packed
Signature · 1 line
2.53.0
Huacai Chen
maintainerRe: [PATCH v4 1/4] efi: add a KHO configuration table GUID
Hi, George,
Quoted 42 lines · George Guo
From: George Guo <[email protected]>
Kexec Handover (KHO) passes the address of its state FDT and of its scratch area from the current kernel to the next one. On architectures that boot with a device tree, the current kernel writes the linux,kho-fdt and linux,kho-scratch properties into /chosen, and the next kernel reads them back in
early_init_dt_check_kho().Architectures that boot through EFI without a device tree have no such channel. LoongArch is one of them: its efistub passes the EFI system table and the command line to the core kernel directly and never creates an FDT. x86 has the same problem and carries the state out of band instead, in a struct
kho_datain thesetup_datachain of its boot protocol.Add an out-of-band channel for EFI: a
LINUX_EFI_KHO_TABLE_GUIDconfiguration table entry, under a randomly generated GUID, pointing at a structlinux_efi_kho_data. The
current kernel loads the structure and an extended configuration table as kexec segments, then switches the EFI system table to the new table before jumping. The next kernel finds the entry by GUID and callskho_populate().The structure carries no version field. An incompatible change to the layout must use a new GUID, which is the usual rule for EFI configuration tables. The handover payload itself is versioned separately, by the compatible string of the KHO state FDT that
kho_populate()checks.This patch adds the definitions only. LoongArch is the first user; any other EFI architecture without a boot FDT can use the same channel.
Signed-off-by George Guo <[email protected]>--- include/linux/efi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)include/linux/efi.h +0
-0
include/linux/efi.h void efi_native_runtime_setup(void); · line 425
Quoted 4 lines
include/linux/efi.h +1
-0@@ -422,6 +422,7 @@ void efi_native_runtime_setup(void);#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17)
I don't know whether it is allowed to define a new TABLE ID while doesn't touch the UEFI SPEC.
Huacai
Quoted 36 lines
include/linux/efi.h +23
-1#define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf)@@ -1271,6 +1272,29 @@ struct linux_efi_memreserve {void __init efi_arch_mem_reserve (phys_addr_t addr,u64 size); +/* +* The LINUX_EFI_KHO_TABLE_GUID config table points to this structure. It +* carries the kexec handover (KHO) state from the current kernel to the next +* one: the addresses of the KHO state FDT and of the scratch area. +* +* This is the handover channel for architectures that boot through EFI without +* a device tree, where the /chosen linux,kho-fdt and linux,kho-scratch +* properties read by early_init_dt_check_kho() are not available. The current +* kernel loads the structure and an extended configuration table as kexec +* segments; the next kernel finds it by GUID and calls kho_populate(). +* +* The layout is an ABI between the two kernels and is fixed. It carries no +* version field: an incompatible change must use a new GUID, and the handover +* payload itself is versioned separately by the compatible string of the KHO +* state FDT, which kho_populate() checks. +*/ +struct linux_efi_kho_data { +u64 fdt_addr; +u64 fdt_size; +u64 scratch_addr; +u64 scratch_size; +} __packed; +/* * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided * to the kernel by an EFI boot loader. The table contains a packed -- 2.53.0
Ard Biesheuvel
maintainerRe: [PATCH v4 1/4] efi: add a KHO configuration table GUID
Quoted 40 lines · Huacai Chen
Hi, George,
Quoted 37 lines · George Guo
From: George Guo <[email protected]>
Kexec Handover (KHO) passes the address of its state FDT and of its scratch area from the current kernel to the next one. On architectures that boot with a device tree, the current kernel writes the linux,kho-fdt and linux,kho-scratch properties into /chosen, and the next kernel reads them back in
early_init_dt_check_kho().Architectures that boot through EFI without a device tree have no such channel. LoongArch is one of them: its efistub passes the EFI system table and the command line to the core kernel directly and never creates an FDT. x86 has the same problem and carries the state out of band instead, in a struct
kho_datain thesetup_datachain of its boot protocol.Add an out-of-band channel for EFI: a
LINUX_EFI_KHO_TABLE_GUIDconfiguration table entry, under a randomly generated GUID, pointing at a structlinux_efi_kho_data. The
current kernel loads the structure and an extended configuration table as kexec segments, then switches the EFI system table to the new table before jumping. The next kernel finds the entry by GUID and callskho_populate().The structure carries no version field. An incompatible change to the layout must use a new GUID, which is the usual rule for EFI configuration tables. The handover payload itself is versioned separately, by the compatible string of the KHO state FDT that
kho_populate()checks.This patch adds the definitions only. LoongArch is the first user; any other EFI architecture without a boot FDT can use the same channel.
Signed-off-by George Guo <[email protected]>--- include/linux/efi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
Quoted 12 lines
include/linux/efi.h void efi_native_runtime_setup(void); · line 425
Quoted 9 lines
include/linux/efi.h +1
-0@@ -422,6 +422,7 @@ void efi_native_runtime_setup(void);#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17)I don't know whether it is allowed to define a new TABLE ID while doesn't touch the UEFI SPEC.
That is fine in principle: the whole reason for using GUIDs as identifiers in UEFI is that everyone can invent their own, and the risk of conflicts is negligible.
All LINUX_EFI_* GUIDs are Linux inventions, and are not mentioned in the UEFI spec at all.
Huacai Chen
maintainerRe: [PATCH v4 1/4] efi: add a KHO configuration table GUID
Quoted 57 lines · Ard Biesheuvel
Quoted 40 lines · Huacai Chen
Hi, George,
Quoted 37 lines · George Guo
From: George Guo <[email protected]>
Kexec Handover (KHO) passes the address of its state FDT and of its scratch area from the current kernel to the next one. On architectures that boot with a device tree, the current kernel writes the linux,kho-fdt and linux,kho-scratch properties into /chosen, and the next kernel reads them back in
early_init_dt_check_kho().Architectures that boot through EFI without a device tree have no such channel. LoongArch is one of them: its efistub passes the EFI system table and the command line to the core kernel directly and never creates an FDT. x86 has the same problem and carries the state out of band instead, in a struct
kho_datain thesetup_datachain of its boot protocol.Add an out-of-band channel for EFI: a
LINUX_EFI_KHO_TABLE_GUIDconfiguration table entry, under a randomly generated GUID, pointing at a structlinux_efi_kho_data. The
current kernel loads the structure and an extended configuration table as kexec segments, then switches the EFI system table to the new table before jumping. The next kernel finds the entry by GUID and callskho_populate().The structure carries no version field. An incompatible change to the layout must use a new GUID, which is the usual rule for EFI configuration tables. The handover payload itself is versioned separately, by the compatible string of the KHO state FDT that
kho_populate()checks.This patch adds the definitions only. LoongArch is the first user; any other EFI architecture without a boot FDT can use the same channel.
Signed-off-by George Guo <[email protected]>--- include/linux/efi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)Quoted 12 lines
include/linux/efi.h void efi_native_runtime_setup(void); · line 425
Quoted 9 lines
include/linux/efi.h +1
-0@@ -422,6 +422,7 @@ void efi_native_runtime_setup(void);#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17)I don't know whether it is allowed to define a new TABLE ID while doesn't touch the UEFI SPEC.
Quoted 6 lines
That is fine in principle: the whole reason for using GUIDs as identifiers in UEFI is that everyone can invent their own, and the risk of conflicts is negligible.
All LINUX_EFI_* GUIDs are Linux inventions, and are not mentioned in the UEFI spec at all.
OK, then I think the direction of this series is correct now, and I hope there will be more archs share this GUID.
BTW, I think LINUX_EFI_KEXEC_HANDOVER_GUID may be a little better than LINUX_EFI_KHO_TABLE_GUID.
Huacai
Quoted 1 line
Pratyush Yadav
maintainerRe: [PATCH v4 1/4] efi: add a KHO configuration table GUID
Quoted 58 lines · Huacai Chen
Quoted 57 lines · Ard Biesheuvel
Quoted 52 lines · Huacai Chen
Hi, George,
Quoted 42 lines · George Guo
From: George Guo <[email protected]>
Kexec Handover (KHO) passes the address of its state FDT and of its scratch area from the current kernel to the next one. On architectures that boot with a device tree, the current kernel writes the linux,kho-fdt and linux,kho-scratch properties into /chosen, and the next kernel reads them back in
early_init_dt_check_kho().Architectures that boot through EFI without a device tree have no such channel. LoongArch is one of them: its efistub passes the EFI system table and the command line to the core kernel directly and never creates an FDT. x86 has the same problem and carries the state out of band instead, in a struct
kho_datain thesetup_datachain of its boot protocol.Add an out-of-band channel for EFI: a
LINUX_EFI_KHO_TABLE_GUIDconfiguration table entry, under a randomly generated GUID, pointing at a structlinux_efi_kho_data. The
current kernel loads the structure and an extended configuration table as kexec segments, then switches the EFI system table to the new table before jumping. The next kernel finds the entry by GUID and callskho_populate().The structure carries no version field. An incompatible change to the layout must use a new GUID, which is the usual rule for EFI configuration tables. The handover payload itself is versioned separately, by the compatible string of the KHO state FDT that
kho_populate()checks.This patch adds the definitions only. LoongArch is the first user; any other EFI architecture without a boot FDT can use the same channel.
Signed-off-by George Guo <[email protected]>--- include/linux/efi.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)include/linux/efi.h +0
-0include/linux/efi.h void efi_native_runtime_setup(void); · line 425
Quoted 4 lines
include/linux/efi.h +1
-0@@ -422,6 +422,7 @@ void efi_native_runtime_setup(void);#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)#define LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID EFI_GUID(0xd5d1de3c, 0x105c, 0x44f9, 0x9e, 0xa9, 0xbc, 0xef, 0x98, 0x12, 0x00, 0x31) +#define LINUX_EFI_KHO_TABLE_GUID EFI_GUID(0xc941b6c7, 0x7b3f, 0x4af6, 0x9e, 0x50, 0xfc, 0xb3, 0xa8, 0x86, 0x8a, 0x17)I don't know whether it is allowed to define a new TABLE ID while doesn't touch the UEFI SPEC.
Quoted 8 lines
Quoted 6 lines
That is fine in principle: the whole reason for using GUIDs as identifiers in UEFI is that everyone can invent their own, and the risk of conflicts is negligible.
All LINUX_EFI_* GUIDs are Linux inventions, and are not mentioned in the UEFI spec at all.
OK, then I think the direction of this series is correct now, and I hope there will be more archs share this GUID.
Agreed.
Perhaps we can move x86 over to use this as well? If I understand correctly, pretty much all modern x86 systems have UEFI, so it would make sense for KHO to directly use the generic UEFI bits for x86 as well instead of having it via setup data.
Quoted 3 lines
BTW, I think
LINUX_EFI_KEXEC_HANDOVER_GUIDmay be a little better thanLINUX_EFI_KHO_TABLE_GUID.
+1, that sounds better.
Signature · 2 lines
Regards, Pratyush Yadav
PATCH v4 2/4 LoongArch: kexec: add KHO support
In reply to George GuoFrom: George Guo <[email protected]>
Enable Kexec Handover (KHO) on LoongArch64.
LoongArch has no boot FDT: the efistub passes the EFI system table and the command line to the core kernel directly, so the arm64 /chosen path (append linux,kho-fdt / linux,kho-scratch and let early_init_dt_check_kho() read them) does not apply. Follow the x86 model instead, which has no boot FDT either: carry the KHO pointer out of band and call kho_populate() directly. The channel is the EFI configuration table entry added by the previous patch.
- Kconfig: ARCH_SUPPORTS_KEXEC_HANDOVER is def_bool 64BIT.
- machine_kexec_file.c: kho_load_data() builds a small handover blob (struct linux_efi_kho_data) holding the KHO state FDT and scratch addresses, and a new EFI configuration table with a LINUX_EFI_KHO_TABLE_GUID entry pointing to it; both are loaded as kexec segments.
- machine_kexec.c: before jumping to the next kernel, switch the EFI system table to the extended configuration table.
- setup.c: kho_populate_from_efi() scans the configuration table for LINUX_EFI_KHO_TABLE_GUID and calls kho_populate() from setup_arch(), after efi_init() and before memblock_init().
Handover is set up by the kexec_file_load() syscall only. kho_load_data() runs from load_other_segments(), which the older kexec_load() syscall does not reach. This matches x86, where KHO lives in the bzImage64 loader.
Tested on a LoongArch machine booting through ACPI/UEFI. After the kexec, the second kernel reports
KHO: found kexec handover data.
and the two-stage test passes: luo_kexec_simple --stage 1, kexec into the second kernel, then luo_kexec_simple --stage 2.
--- arch/loongarch/Kconfig | 3 + arch/loongarch/include/asm/kexec.h | 7 ++ arch/loongarch/kernel/machine_kexec.c | 16 +++ arch/loongarch/kernel/machine_kexec_file.c | 131 +++++++++++++++++++++ arch/loongarch/kernel/setup.c | 41 +++++++ 5 files changed, 198 insertions(+)
arch/loongarch/Kconfig +3 -0
@@ -684,6 +684,9 @@ config ARCH_SUPPORTS_KEXEC config ARCH_SUPPORTS_KEXEC_FILE def_bool 64BIT +config ARCH_SUPPORTS_KEXEC_HANDOVER + def_bool 64BIT + config ARCH_SELECTS_KEXEC_FILE def_bool 64BIT depends on KEXEC_FILE
arch/loongarch/include/asm/kexec.h +7 -0
@@ -39,6 +39,13 @@ struct kimage_arch {unsigned long efi_boot;unsigned long cmdline_ptr;unsigned long systable_ptr; +#ifdef CONFIG_KEXEC_HANDOVER +void *kho_data;/* KHO handover blob buffer (virtual) */ +unsigned long kho_data_mem;/* physical address of the KHO handover blob */ +void *efi_tables;/* new EFI config table buffer (virtual) */ +unsigned long efi_tables_mem;/* physical address of new EFI config table */ +unsigned long efi_tables_cnt;/* number of entries in new EFI config table */ +#endif };struct kimage ;
arch/loongarch/kernel/machine_kexec.c +16 -0
@@ -6,6 +6,7 @@*/ #include <linux/compiler.h> #include <linux/cpu.h> +#include <linux/efi.h> #include <linux/kexec.h> #include <linux/crash_dump.h> #include <linux/delay.h>
@@ -287,6 +288,21 @@ void machine_kexec(struct kimage *image)pr_notice ("We will call new kernel at 0x%lx\n" , start_addr);pr_notice ("Bye ...\n" ); +#ifdef CONFIG_KEXEC_HANDOVER +/* +* KHO: switch the EFI system table to the extended configuration table +* built in kho_load_data(), which carries the LINUX_EFI_KHO_TABLE_GUID +* entry the next kernel reads to find the KHO handover blob. +*/ +if (internal->efi_tables_mem) { +efi_system_table_t *st = + (efi_system_table_t *)TO_CACHE (systable_ptr); + + st->tables = internal->efi_tables_mem; + st->nr_tables = internal->efi_tables_cnt; + } +#endif +/* Make reboot code buffer available to the boot CPU. */ flush_cache_all ();
arch/loongarch/kernel/machine_kexec_file.c +131 -0
161 lines not on this page · raw message
arch/loongarch/kernel/setup.c +41 -0
59 lines not on this page · raw message
Signature · 1 line
2.53.0
Huacai Chen
maintainerRe: [PATCH v4 2/4] LoongArch: kexec: add KHO support
Hi, George,
Quoted 181 lines · George Guo
From: George Guo <[email protected]>
Enable Kexec Handover (KHO) on LoongArch64.
LoongArch has no boot FDT: the efistub passes the EFI system table and the command line to the core kernel directly, so the arm64 /chosen path (append linux,kho-fdt / linux,kho-scratch and let
early_init_dt_check_kho()read them) does not apply. Follow the x86 model instead, which has no boot FDT either: carry the KHO pointer out of band and callkho_populate()directly. The channel is the EFI configuration table entry added by the previous patch.-
Kconfig:ARCH_SUPPORTS_KEXEC_HANDOVERisdef_bool64BIT.
-machine_kexec_file.c:kho_load_data()builds a small handover blob (structlinux_efi_kho_data) holding the KHO state FDT and scratch addresses, and a new EFI configuration table with aLINUX_EFI_KHO_TABLE_GUIDentry pointing to it; both are loaded as kexec segments.
-machine_kexec.c: before jumping to the next kernel, switch the EFI system table to the extended configuration table.
-setup.c:kho_populate_from_efi()scans the configuration table forLINUX_EFI_KHO_TABLE_GUIDand callskho_populate()fromsetup_arch(), afterefi_init()and beforememblock_init().Handover is set up by the
kexec_file_load()syscall only.kho_load_data()runs fromload_other_segments(), which the olderkexec_load()syscall does not reach. This matches x86, where KHO lives in the bzImage64 loader.Tested on a LoongArch machine booting through ACPI/UEFI. After the kexec, the second kernel reports
KHO: found kexec handover data.
and the two-stage test passes:
luo_kexec_simple--stage 1, kexec into the second kernel, thenluo_kexec_simple--stage 2.Co-developed-by Kexin Liu <[email protected]>Signed-off-by Kexin Liu <[email protected]>Signed-off-by George Guo <[email protected]>--- arch/loongarch/Kconfig | 3 + arch/loongarch/include/asm/kexec.h | 7 ++ arch/loongarch/kernel/machine_kexec.c | 16 +++ arch/loongarch/kernel/machine_kexec_file.c | 131 +++++++++++++++++++++ arch/loongarch/kernel/setup.c | 41 +++++++ 5 files changed, 198 insertions(+)arch/loongarch/Kconfig +3
-0@@ -684,6 +684,9 @@ config ARCH_SUPPORTS_KEXEC config ARCH_SUPPORTS_KEXEC_FILE def_bool 64BIT +config ARCH_SUPPORTS_KEXEC_HANDOVER + def_bool 64BIT + config ARCH_SELECTS_KEXEC_FILE def_bool 64BIT depends on KEXEC_FILEarch/loongarch/include/asm/kexec.h +7
-0@@ -39,6 +39,13 @@ struct kimage_arch {unsigned long efi_boot;unsigned long cmdline_ptr;unsigned long systable_ptr; +#ifdef CONFIG_KEXEC_HANDOVER +void *kho_data;/* KHO handover blob buffer (virtual) */ +unsigned long kho_data_mem;/* physical address of the KHO handover blob */ +void *efi_tables;/* new EFI config table buffer (virtual) */ +unsigned long efi_tables_mem;/* physical address of new EFI config table */ +unsigned long efi_tables_cnt;/* number of entries in new EFI config table */ +#endif };struct kimage ;arch/loongarch/kernel/machine_kexec.c +16
-0@@ -6,6 +6,7 @@*/ #include <linux/compiler.h> #include <linux/cpu.h> +#include <linux/efi.h> #include <linux/kexec.h> #include <linux/crash_dump.h> #include <linux/delay.h> @@ -287,6 +288,21 @@ void machine_kexec(struct kimage *image)pr_notice ("We will call new kernel at 0x%lx\n" , start_addr);pr_notice ("Bye ...\n" ); +#ifdef CONFIG_KEXEC_HANDOVER +/* +* KHO: switch the EFI system table to the extended configuration table +* built in kho_load_data(), which carries the LINUX_EFI_KHO_TABLE_GUID +* entry the next kernel reads to find the KHO handover blob. +*/ +if (internal->efi_tables_mem) { +efi_system_table_t *st = + (efi_system_table_t *)TO_CACHE (systable_ptr); + + st->tables = internal->efi_tables_mem; + st->nr_tables = internal->efi_tables_cnt; + } +#endif +/* Make reboot code buffer available to the boot CPU. */ flush_cache_all ();arch/loongarch/kernel/machine_kexec_file.c +38
-0@@ -10,6 +10,7 @@#define pr_fmt (fmt) "kexec_file: " fmt +#include <linux/efi.h> #include <linux/ioport.h> #include <linux/kernel.h> #include <linux/kexec.h> @@ -18,6 +19,7 @@#include <linux/string.h> #include <linux/types.h> #include <linux/vmalloc.h> +#include <asm/addrspace.h> #include <asm/bootinfo.h> const struct kexec_file_ops *const kexec_file_loaders[] = {@@ -32,6 +34,13 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image) image->elf_headers =NULL ; image->elf_headers_sz =0 ; +#ifdef CONFIG_KEXEC_HANDOVER +kfree (image->arch.kho_data); + image->arch.kho_data =NULL ; +kvfree (image->arch.efi_tables); + image->arch.efi_tables =NULL ; +#endif +return kexec_image_post_load_cleanup_default (image); }@@ -55,6 +64,121 @@ static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl *cmdline_tmplen += initrd_strlen; } +#ifdef CONFIG_KEXEC_HANDOVER +/* + * Hand the KHO state to the next kernel through a dedicated EFI configuration + * table entry. + * + * LoongArch has no boot FDT: the efistub passes the EFI system table and the + * command line to the core kernel directly. So instead of the arm64 /chosen + * FDT path, build a small handover blob (struct linux_efi_kho_data) holding the + * KHO state FDT and scratch addresses, register it in the EFI configuration + * table under LINUX_EFI_KHO_TABLE_GUID, and let the next kernel read it and + * call kho_populate() directly. + * + * Both the blob and the extended configuration table are loaded as kexec + * segments; machine_kexec() switches st->tables to the new table before jumping. + * + * image->kho.fdt and image->kho.scratch are filled in by kho_fill_kimage() + * before the arch loader runs, so they are valid here. + */ +static int kho_load_data(struct kimage *image) +{ + struct linux_efi_kho_data *kho; + efi_system_table_t *st; + efi_config_table_t *ct, *new_ct; + size_t old_sz, new_sz; + struct kexec_buf kbuf = { + .image = image, + .buf_min = 0, + .buf_max = ULONG_MAX, + .top_down = true,
arch/loongarch/kernel/machine_kexec_file.c static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl · line 105
Quoted 10 lines
arch/loongarch/kernel/machine_kexec_file.c +10
-0+ }; +int ret; + +if (!image->kho.fdt || !image->kho.scratch) +return 0 ; + +if (!fw_arg2) { +pr_err ("KHO requires an EFI boot, no EFI system table found\n" ); +return -EINVAL ; + }
This check is unnecessary, if no EFI system table, you cannot boot your system, and have no chance for kexec.
Quoted 134 lines
arch/loongarch/kernel/machine_kexec_file.c +83
-0+ +/* Build the handover blob and load it as a kexec segment. */ + kho =kzalloc (sizeof (*kho),GFP_KERNEL ); +if (!kho) +return -ENOMEM ; + + kho->fdt_addr = image->kho.fdt; + kho->fdt_size =PAGE_SIZE ; + kho->scratch_addr = image->kho.scratch->mem; + kho->scratch_size = image->kho.scratch->memsz; + + kbuf.buffer = kho; + kbuf.bufsz =sizeof (*kho); + kbuf.memsz =sizeof (*kho); + kbuf.buf_align =sizeof (u64); + kbuf.mem =KEXEC_BUF_MEM_UNKNOWN ; + + ret =kexec_add_buffer (&kbuf); +if (ret) { +kfree (kho); +return ret; + } + image->arch.kho_data = kho; + image->arch.kho_data_mem = kbuf.mem; + +kexec_dprintk ("Loaded KHO handover blob at 0x%lx bufsz=0x%lx memsz=0x%lx\n" , + image->arch.kho_data_mem, kbuf.bufsz, kbuf.memsz); +kexec_dprintk ("KHO fdt at 0x%llx, scratch at 0x%llx size 0x%llx\n" , + kho->fdt_addr, kho->scratch_addr, kho->scratch_size); + +/* +* Build a new EFI configuration table with a LINUX_EFI_KHO_TABLE_GUID +* entry appended, pointing at the handover blob, and load it as a kexec +* segment. machine_kexec() updates st->tables / st->nr_tables to point +* to it before jumping. +* +* fw_arg2 is the EFI system table physical address passed by the +* firmware/bootloader. Use it directly because image->arch.systable_ptr +* is set later in machine_kexec_prepare(), which runs after this. +*/ + st = (efi_system_table_t *)TO_CACHE (fw_arg2); + ct = (efi_config_table_t *)TO_CACHE ((unsigned long )st->tables); + old_sz = st->nr_tables *sizeof (efi_config_table_t); + new_sz = old_sz +sizeof (efi_config_table_t); + + new_ct =kvmalloc (new_sz,GFP_KERNEL ); +if (!new_ct) +return -ENOMEM ; + +memcpy (new_ct, ct, old_sz); + new_ct[st->nr_tables].guid =LINUX_EFI_KHO_TABLE_GUID ; + new_ct[st->nr_tables].table = (void *)image->arch.kho_data_mem; + + kbuf.buffer = new_ct; + kbuf.bufsz = new_sz; + kbuf.memsz = new_sz; + kbuf.buf_align =sizeof (void *); + kbuf.mem =KEXEC_BUF_MEM_UNKNOWN ; + + ret =kexec_add_buffer (&kbuf); +if (ret) { +kvfree (new_ct); +return ret; + } + image->arch.efi_tables = new_ct; + image->arch.efi_tables_mem = kbuf.mem; + image->arch.efi_tables_cnt = st->nr_tables +1 ; + +kexec_dprintk ("Loaded EFI config table at 0x%lx bufsz=0x%lx memsz=0x%lx nr_tables=%lu\n" , + image->arch.efi_tables_mem, kbuf.bufsz, kbuf.memsz, + image->arch.efi_tables_cnt); + + return 0; +} +#endif +#ifdef CONFIG_CRASH_DUMP static int prepare_elf_headers (void **addr,unsigned long *sz)@@ -220,6 +344,13 @@ int load_other_segments(struct kimage *image,cmdline_add_initrd (image, &cmdline_tmplen, modified_cmdline, initrd_load_addr); } +#ifdef CONFIG_KEXEC_HANDOVER +/* Load the KHO handover blob and the extended EFI configuration table */ + ret =kho_load_data (image); +if (ret) + goto out_err; +#endif +if (cmdline_len + cmdline_tmplen >COMMAND_LINE_SIZE ) {pr_err ("Appending command line exceeds COMMAND_LINE_SIZE\n" ); ret = -EINVAL ;arch/loongarch/kernel/setup.c +26
-0@@ -20,6 +20,7 @@#include <linux/initrd.h> #include <linux/ioport.h> #include <linux/kexec.h> +#include <linux/kexec_handover.h> #include <linux/crash_dump.h> #include <linux/root_dev.h> #include <linux/console.h> @@ -280,6 +281,45 @@ static void __init arch_reserve_crashkernel(void)reserve_crashkernel_generic (crash_size, crash_base, low_size, high); } +#ifdef CONFIG_KEXEC_HANDOVER +/* +* On a KHO kexec boot the previous kernel registered a handover blob in the EFI +* configuration table under LINUX_EFI_KHO_TABLE_GUID (see +* arch/loongarch/kernel/machine_kexec_file.c). Scan the configuration table +* for it, read the KHO state FDT and scratch addresses, and hand them to the +* KHO core. fw_arg2 is the EFI system table physical address. +* +* This runs from setup_arch(), after efi_init() and before memblock_init(), +* which is where the generic reader early_init_dt_check_kho() would call +* kho_populate(). +*/ +static void __init kho_populate_from_efi (void ) +{ +efi_system_table_t *st; +efi_config_table_t *ct; +struct linux_efi_kho_data *kho; +unsigned long i; + +if (!fw_arg2) +return ; + + st = (efi_system_table_t *)TO_CACHE (fw_arg2); + ct = (efi_config_table_t *)TO_CACHE ((unsigned long )st->tables); +
arch/loongarch/kernel/setup.c static void __init arch_reserve_crashkernel(void) · line 318
Quoted 10 lines
arch/loongarch/kernel/setup.c +10
-0+for (i =0 ; i < st->nr_tables; i++) { +if (efi_guidcmp (ct[i].guid,LINUX_EFI_KHO_TABLE_GUID )) +continue ; + + kho = (struct linux_efi_kho_data *)TO_CACHE ((unsigned long )ct[i].table); +kho_populate (kho->fdt_addr, kho->fdt_size, + kho->scratch_addr, kho->scratch_size); +break ; + } +}
If you do this in efi.c, you can significantly simplify the code. By defining the KHO table in arch_tables[], you almost only need to call kho_populate() at the end of efi_init().
Huacai
Quoted 18 lines
arch/loongarch/kernel/setup.c +5
-1+#else +static void __init kho_populate_from_efi (void ) { } +#endif +static void __init fdt_setup (void ) {#ifdef CONFIG_OF_EARLY_FLATTREE @@ -599,6 +639,7 @@ void __init setup_arch(char **cmdline_p)init_environ ();efi_init (); +kho_populate_from_efi ();fdt_setup ();memblock_init ();pagetable_init (); --2.53.0
Pratyush Yadav
maintainerRe: [PATCH v4 2/4] LoongArch: kexec: add KHO support
In reply to George GuoQuoted 39 lines · George Guo
From: George Guo <[email protected]>
Enable Kexec Handover (KHO) on LoongArch64.
LoongArch has no boot FDT: the efistub passes the EFI system table and the command line to the core kernel directly, so the arm64 /chosen path (append linux,kho-fdt / linux,kho-scratch and let
early_init_dt_check_kho()read them) does not apply. Follow the x86 model instead, which has no boot FDT either: carry the KHO pointer out of band and callkho_populate()directly. The channel is the EFI configuration table entry added by the previous patch.-
Kconfig:ARCH_SUPPORTS_KEXEC_HANDOVERisdef_bool64BIT.
-machine_kexec_file.c:kho_load_data()builds a small handover blob (structlinux_efi_kho_data) holding the KHO state FDT and scratch addresses, and a new EFI configuration table with aLINUX_EFI_KHO_TABLE_GUIDentry pointing to it; both are loaded as kexec segments.
-machine_kexec.c: before jumping to the next kernel, switch the EFI system table to the extended configuration table.
-setup.c:kho_populate_from_efi()scans the configuration table forLINUX_EFI_KHO_TABLE_GUIDand callskho_populate()fromsetup_arch(), afterefi_init()and beforememblock_init().Handover is set up by the
kexec_file_load()syscall only.kho_load_data()runs fromload_other_segments(), which the olderkexec_load()syscall does not reach. This matches x86, where KHO lives in the bzImage64 loader.Tested on a LoongArch machine booting through ACPI/UEFI. After the kexec, the second kernel reports
KHO: found kexec handover data.
and the two-stage test passes:
luo_kexec_simple--stage 1, kexec into the second kernel, thenluo_kexec_simple--stage 2.Co-developed-by Kexin Liu <[email protected]>Signed-off-by Kexin Liu <[email protected]>Signed-off-by George Guo <[email protected]>
[...]
Quoted 73 lines
arch/loongarch/kernel/machine_kexec_file.c +69
-0@@ -55,6 +64,121 @@ static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl *cmdline_tmplen += initrd_strlen; } +#ifdef CONFIG_KEXEC_HANDOVER +/* +* Hand the KHO state to the next kernel through a dedicated EFI configuration +* table entry. +* +* LoongArch has no boot FDT: the efistub passes the EFI system table and the +* command line to the core kernel directly. So instead of the arm64 /chosen +* FDT path, build a small handover blob (struct linux_efi_kho_data) holding the +* KHO state FDT and scratch addresses, register it in the EFI configuration +* table under LINUX_EFI_KHO_TABLE_GUID, and let the next kernel read it and +* call kho_populate() directly. +* +* Both the blob and the extended configuration table are loaded as kexec +* segments; machine_kexec() switches st->tables to the new table before jumping. +* +* image->kho.fdt and image->kho.scratch are filled in by kho_fill_kimage() +* before the arch loader runs, so they are valid here. +*/ +static int kho_load_data (struct kimage *image) +{ +struct linux_efi_kho_data *kho; +efi_system_table_t *st; +efi_config_table_t *ct, *new_ct; +size_t old_sz, new_sz; +struct kexec_buf kbuf = { + .image = image, + .buf_min =0 , + .buf_max =ULONG_MAX , + .top_down = true, + }; +int ret; + +if (!image->kho.fdt || !image->kho.scratch) +return 0 ; + +if (!fw_arg2) { +pr_err ("KHO requires an EFI boot, no EFI system table found\n" ); +return -EINVAL ; + } + +/* Build the handover blob and load it as a kexec segment. */ + kho =kzalloc (sizeof (*kho),GFP_KERNEL ); +if (!kho) +return -ENOMEM ; + + kho->fdt_addr = image->kho.fdt; + kho->fdt_size =PAGE_SIZE ; + kho->scratch_addr = image->kho.scratch->mem; + kho->scratch_size = image->kho.scratch->memsz; + + kbuf.buffer = kho; + kbuf.bufsz =sizeof (*kho); + kbuf.memsz =sizeof (*kho); + kbuf.buf_align =sizeof (u64); + kbuf.mem =KEXEC_BUF_MEM_UNKNOWN ; + + ret =kexec_add_buffer (&kbuf); +if (ret) { +kfree (kho); +return ret; + } + image->arch.kho_data = kho; + image->arch.kho_data_mem = kbuf.mem; + +kexec_dprintk ("Loaded KHO handover blob at 0x%lx bufsz=0x%lx memsz=0x%lx\n" , + image->arch.kho_data_mem, kbuf.bufsz, kbuf.memsz); +kexec_dprintk ("KHO fdt at 0x%llx, scratch at 0x%llx size 0x%llx\n" , + kho->fdt_addr, kho->scratch_addr, kho->scratch_size); +
arch/loongarch/kernel/machine_kexec_file.c static void cmdline_add_initrd(struct kimage *image, unsigned long *cmdline_tmpl · line 145
Quoted 10 lines
arch/loongarch/kernel/machine_kexec_file.c +10
-0+/* +* Build a new EFI configuration table with a LINUX_EFI_KHO_TABLE_GUID +* entry appended, pointing at the handover blob, and load it as a kexec +* segment. machine_kexec() updates st->tables / st->nr_tables to point +* to it before jumping. +* +* fw_arg2 is the EFI system table physical address passed by the +* firmware/bootloader. Use it directly because image->arch.systable_ptr +* is set later in machine_kexec_prepare(), which runs after this. +*/
This looks wrong. I don't think you should be modifying the EFI configuration table in this way. You also should have this in architecture-agnostic code.
I'm not an EFI expert, but I took a look at how the other Linux-specific tables work. I picked LINUX_EFI_MEMRESERVE_TABLE_GUID as my example. The table is allocated and installed from the EFI stub (see install_memreserve_table()). Then efi_memreserve_map_root() maps the table and it is used by efi_mem_reserve_persistent().
You should do something similar. Allocate and install the table from the stub, and then just update it on kexec. This would also let other architectures use this GUID without having to reinvent this again.
Quoted 53 lines
arch/loongarch/kernel/machine_kexec_file.c +43
-0+ st = (efi_system_table_t *)TO_CACHE (fw_arg2); + ct = (efi_config_table_t *)TO_CACHE ((unsigned long )st->tables); + old_sz = st->nr_tables *sizeof (efi_config_table_t); + new_sz = old_sz +sizeof (efi_config_table_t); + + new_ct =kvmalloc (new_sz,GFP_KERNEL ); +if (!new_ct) +return -ENOMEM ; + +memcpy (new_ct, ct, old_sz); + new_ct[st->nr_tables].guid =LINUX_EFI_KHO_TABLE_GUID ; + new_ct[st->nr_tables].table = (void *)image->arch.kho_data_mem; + + kbuf.buffer = new_ct; + kbuf.bufsz = new_sz; + kbuf.memsz = new_sz; + kbuf.buf_align =sizeof (void *); + kbuf.mem =KEXEC_BUF_MEM_UNKNOWN ; + + ret =kexec_add_buffer (&kbuf); +if (ret) { +kvfree (new_ct); +return ret; + } + image->arch.efi_tables = new_ct; + image->arch.efi_tables_mem = kbuf.mem; + image->arch.efi_tables_cnt = st->nr_tables +1 ; + +kexec_dprintk ("Loaded EFI config table at 0x%lx bufsz=0x%lx memsz=0x%lx nr_tables=%lu\n" , + image->arch.efi_tables_mem, kbuf.bufsz, kbuf.memsz, + image->arch.efi_tables_cnt); + + return 0; +} +#endif +#ifdef CONFIG_CRASH_DUMP static int prepare_elf_headers (void **addr,unsigned long *sz)@@ -220,6 +344,13 @@ int load_other_segments(struct kimage *image,cmdline_add_initrd (image, &cmdline_tmplen, modified_cmdline, initrd_load_addr); } +#ifdef CONFIG_KEXEC_HANDOVER +/* Load the KHO handover blob and the extended EFI configuration table */ + ret =kho_load_data (image); +if (ret) + goto out_err; +#endif +if (cmdline_len + cmdline_tmplen >COMMAND_LINE_SIZE ) {pr_err ("Appending command line exceeds COMMAND_LINE_SIZE\n" ); ret = -EINVAL ;
[...]
Signature · 2 lines
Regards, Pratyush Yadav
PATCH v4 3/4 liveupdate: luo_session: include linux/mm.h for virt/phys translation
In reply to George GuoFrom: George Guo <[email protected]>
luo_session.c calls virt_to_phys() and phys_to_virt(). On LoongArch with CONFIG_KFENCE=y, these macros (in arch/loongarch/include/asm/io.h) expand to offset_in_page() and page_address(), both declared in <linux/mm.h>.
Since luo_session.c only includes <linux/io.h>, the translation unit fails to build with CONFIG_KFENCE=y:
asm/io.h: error: implicit declaration of function 'offset_in_page' asm/io.h: error: implicit declaration of function 'page_address'
Add the missing include to fix these build errors.
--- kernel/liveupdate/luo_session.c | 1 + 1 file changed, 1 insertion(+)
kernel/liveupdate/luo_session.c +1 -0
@@ -94,6 +94,7 @@#include <linux/kho/abi/luo.h> #include <linux/list.h> #include <linux/liveupdate.h> +#include <linux/mm.h> #include <linux/mutex.h> #include <linux/rwsem.h> #include <linux/slab.h>
Signature · 1 line
2.53.0
Huacai Chen
maintainerRe: [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation
Hi, George,
This should be the 2nd patch.
Huacai
Quoted 39 lines · George Guo
From: George Guo <[email protected]>
luo_session.ccallsvirt_to_phys()andphys_to_virt(). On LoongArch withCONFIG_KFENCE=y, these macros (inarch/loongarch/include/asm/io.h) expand tooffset_in_page()andpage_address(), both declared in <linux/mm.h>.Since
luo_session.conly includes <linux/io.h>, the translation unit fails to build withCONFIG_KFENCE=y:
asm/io.h: error: implicit declaration of function 'offset_in_page'asm/io.h: error: implicit declaration of function 'page_address'Add the missing include to fix these build errors.
Co-developed-by Kexin Liu <[email protected]>Signed-off-by Kexin Liu <[email protected]>Signed-off-by George Guo <[email protected]>--- kernel/liveupdate/luo_session.c | 1 + 1 file changed, 1 insertion(+)kernel/liveupdate/luo_session.c +1
-1@@ -94,6 +94,7 @@#include <linux/kho/abi/luo.h> #include <linux/list.h> #include <linux/liveupdate.h> +#include <linux/mm.h> #include <linux/mutex.h> #include <linux/rwsem.h> #include <linux/slab.h> --2.53.0
Re: [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation
Quoted 3 lines · Huacai Chen
Hi, George,
This should be the 2nd patch.
Agreed.
With that done,
Quoted 43 lines
Huacai
Quoted 39 lines · George Guo
From: George Guo <[email protected]>
luo_session.ccallsvirt_to_phys()andphys_to_virt(). On LoongArch withCONFIG_KFENCE=y, these macros (inarch/loongarch/include/asm/io.h) expand tooffset_in_page()andpage_address(), both declared in <linux/mm.h>.Since
luo_session.conly includes <linux/io.h>, the translation unit fails to build withCONFIG_KFENCE=y:
asm/io.h: error: implicit declaration of function 'offset_in_page'asm/io.h: error: implicit declaration of function 'page_address'Add the missing include to fix these build errors.
Co-developed-by Kexin Liu <[email protected]>Signed-off-by Kexin Liu <[email protected]>Signed-off-by George Guo <[email protected]>--- kernel/liveupdate/luo_session.c | 1 + 1 file changed, 1 insertion(+)kernel/liveupdate/luo_session.c +1
-1@@ -94,6 +94,7 @@#include <linux/kho/abi/luo.h> #include <linux/list.h> #include <linux/liveupdate.h> +#include <linux/mm.h> #include <linux/mutex.h> #include <linux/rwsem.h> #include <linux/slab.h> --2.53.0
Signature · 2 lines
Regards, Pratyush Yadav
Pratyush Yadav
maintainerRe: [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation
Quoted 11 lines · Pratyush Yadav
Quoted 3 lines · Huacai Chen
Hi, George,
This should be the 2nd patch.
Agreed.
With that done,
Reviewed-by Pratyush Yadav <[email protected]>
Actually, I take this back. Sashiko has found some problems. See below.
Quoted 11 lines
Quoted 11 lines
Huacai
Quoted 6 lines · George Guo
From: George Guo <[email protected]>
luo_session.ccallsvirt_to_phys()andphys_to_virt(). On LoongArch withCONFIG_KFENCE=y, these macros (inarch/loongarch/include/asm/io.h) expand tooffset_in_page()andpage_address(), both declared in <linux/mm.h>.
https://sashiko.dev/#/patchset/[email protected]
Is this description accurate? Looking at luo_session.c, it does not actually call virt_to_phys().
The implicit declaration error appears to originate from arch_kfence_init_pool() in arch/loongarch/include/asm/kfence.h, which is implicitly included via <linux/slab.h>. arch/loongarch/include/asm/kfence.h:arch_kfence_init_pool() {
...
virt_to_phys((void *)kfence_pool), PAGE_KERNEL);
...
}
Could the fix be applied to the architecture header instead, to prevent any other kernel C file on LoongArch with CONFIG_KFENCE=y from suffering the same build failure if it includes <linux/slab.h> before <linux/mm.h>?
I at least don't see any virt_to_phys() or phys_to_virt() in luo_session.c. So you need to go and take another look at what the real problem is and what the fix should be.
Quoted 33 lines
Quoted 33 lines
Quoted 33 lines
Since
luo_session.conly includes <linux/io.h>, the translation unit fails to build withCONFIG_KFENCE=y:
asm/io.h: error: implicit declaration of function 'offset_in_page'asm/io.h: error: implicit declaration of function 'page_address'Add the missing include to fix these build errors.
Co-developed-by Kexin Liu <[email protected]>Signed-off-by Kexin Liu <[email protected]>Signed-off-by George Guo <[email protected]>--- kernel/liveupdate/luo_session.c | 1 + 1 file changed, 1 insertion(+)kernel/liveupdate/luo_session.c +1
-1@@ -94,6 +94,7 @@#include <linux/kho/abi/luo.h> #include <linux/list.h> #include <linux/liveupdate.h> +#include <linux/mm.h> #include <linux/mutex.h> #include <linux/rwsem.h> #include <linux/slab.h> --2.53.0
Signature · 2 lines
Regards, Pratyush Yadav
Re: [PATCH v4 3/4] liveupdate: luo_session: include linux/mm.h for virt/phys translation
Hi Pratyush,
You are right: the current luo_session.c does not call virt_to_phys() or phys_to_virt(). I failed to update the target of this fix when rebasing the patch. The calls that trigger the current failure are in kernel/liveupdate/kho_block.c. Sorry about that.
I also checked the include chain. asm/kfence.h is not included by this translation unit. include/linux/slab.h does not include linux/kfence.h; that inclusion is in the MM-private mm/slab.h. Moreover, asm/kfence.h itself includes linux/kfence.h, which includes linux/mm.h, so arch_kfence_init_pool() already has the required declarations.
The actual failure is:
kernel/liveupdate/kho_block.c: In function 'kho_block_set_is_cyclic':
./arch/loongarch/include/asm/io.h:81:9: error: implicit declaration of function 'page_address' kernel/liveupdate/kho_block.c:210:16: note: in expansion of macro 'phys_to_virt'
The underlying issue is that LoongArch's CONFIG_KFENCE version of phys_to_virt() uses page_address(), which is provided by linux/mm.h.
Your broader point about fixing this at the architecture level is valid. I previously tried including linux/mm.h from asm/io.h [1], but that introduces a circular include through:
linux/slab.h -> linux/kasan.h -> asm/kasan.h -> asm/io.h -> linux/mm.h -> linux/slab.h
As reported by the kernel test robot [2], this leaves kfree() undeclared while linux/mm.h is being parsed. A proper architecture-wide fix therefore requires refactoring the address conversion helpers rather than adding that include to asm/io.h.
For this series I will move the linux/mm.h include from luo_session.c to the actual user, kho_block.c, and consider the architecture-wide cleanup separately.
[1] https://lore.kernel.org/r/[email protected]/
[2] https://lore.kernel.org/r/[email protected]/
Thanks,
George
PATCH v4 4/4 selftests/kho: add LoongArch vmtest support
In reply to George GuoFrom: George Guo <[email protected]>
Add loongarch.conf to configure QEMU's LoongArch virtual machine (VM) with a la464 CPU, enable the 8250 serial console, and set the kernel image to vmlinux.efi. Extend vmtest.sh to recognise loongarch64 as a supported target and map it to the 'loongarch' kernel arch name.
QEMU's LoongArch VM provides no ACPI tables and relies on FDT to describe hardware. Without 'earlycon' on the kernel command line, the FDT is not scanned for a console UART, no output reaches the console, and vmtest.sh's console log stays empty causing the test to always fail. Add 'earlycon' to KERNEL_CMDLINE in loongarch.conf.
QEMU's LoongArch VM has no i8042 PS/2 controller. When PNP detection finds nothing, i8042_init() falls back to probing the ports directly. On LoongArch the I/O ports are memory-mapped, and the i8042 port addresses are not backed by any device on the VM, so i8042_flush() takes a page fault and the kernel panics:
i8042: PNP: No PS/2 controller found.
i8042: Probing ports directly.
CPU 0 Unable to handle kernel paging request at virtual address ffff800000008064
ERA: i8042_flush+0x50/0x198
RA: i8042_init+0x2a8/0x35c
Kernel panic - not syncing: Attempted to kill init!
Disable SERIO_I8042 and its dependents (KEYBOARD_ATKBD, MOUSE_PS2) in the QEMU_KCONFIG fragment to prevent the driver from being built. All three options are scoped to loongarch.conf; no other architecture is affected.
Wrap the QEMU invocation in run_qemu() with timeout(1) using a local time limit so the test always terminates, even when QEMU does not exit on its own. This is useful for every architecture; on LoongArch, for example, QEMU provides no EFI runtime services and machine_restart() falls through to an idle loop after kexec, so QEMU would never exit otherwise.
--- tools/testing/selftests/kho/loongarch.conf | 11 +++++++++++ tools/testing/selftests/kho/vmtest.sh | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tools/testing/selftests/kho/loongarch.conf
tools/testing/selftests/kho/loongarch.conf new file +11 -0
@@ -0,0 +1,11 @@ +QEMU_CMD="qemu-system-loongarch64 -M virt -cpu la464" +QEMU_KCONFIG=" +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SPARSEMEM_MANUAL=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO_I8042 is not set +" +KERNEL_IMAGE="vmlinux.efi" +KERNEL_CMDLINE="console=ttyS0 earlycon kho_scratch=16M,16M,16M"
tools/testing/selftests/kho/vmtest.sh +15 -7
@@ -21,7 +21,7 @@ Options: -d) path to the kernel build directory -j) number of jobs for compilation, similar to -j in make -t) run test for target_arch, requires CROSS_COMPILE set - supported targets: aarch64, x86_64 + supported targets: aarch64, x86_64, loongarch64 -h) display this help EOF }
@@ -111,12 +111,19 @@ function run_qemu() { cmdline="$cmdline kho=on panic=-1" - $qemu_cmd -m 1G -smp 2 -no-reboot -nographic -nodefaults \ - -accel kvm -accel hvf -accel tcg \ - -serial file:"$serial" \ - -append "$cmdline" \ - -kernel "$kernel" \ - -initrd "$initrd" + local qemu_args=( + -m 1G -smp 2 -no-reboot -nographic -nodefaults + -accel kvm -accel hvf -accel tcg + -serial file:"$serial" + -append "$cmdline" + -kernel "$kernel" + -initrd "$initrd" + ) + + # Bound the QEMU run so the test always terminates, even when QEMU + # does not exit on its own (e.g. no EFI runtime services after kexec). + local qemu_timeout=60 + timeout "$qemu_timeout" $qemu_cmd "${qemu_args[@]}" || true grep "KHO restore succeeded" "$serial" &> /dev/null || fail "KHO failed" }
@@ -127,6 +134,7 @@ function target_to_arch() { case $target in aarch64) echo "arm64" ;; x86_64) echo "x86" ;; + loongarch64) echo "loongarch" ;; *) skip "architecture $target is not supported" esac }
Signature · 1 line
2.53.0
Huacai Chen
maintainerRe: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
Hi, George,
Quoted 20 lines · George Guo
From: George Guo <[email protected]>
Add loongarch.conf to configure QEMU's LoongArch virtual machine (VM) with a la464 CPU, enable the 8250 serial console, and set the kernel image to vmlinux.efi. Extend
vmtest.shto recognise loongarch64 as a supported target and map it to the 'loongarch' kernel arch name.QEMU's LoongArch VM provides no ACPI tables and relies on FDT to describe hardware. Without 'earlycon' on the kernel command line, the FDT is not scanned for a console UART, no output reaches the console, and vmtest.sh's console log stays empty causing the test to always fail. Add 'earlycon' to
KERNEL_CMDLINEin loongarch.conf.QEMU's LoongArch VM has no i8042 PS/2 controller. When PNP detection finds nothing,
i8042_init()falls back to probing the ports directly. On LoongArch the I/O ports are memory-mapped, and the i8042 port addresses are not backed by any device on the VM, soi8042_flush()takes a page fault and the kernel panics:
Quoted 6 lines
i8042: PNP: No PS/2 controller found.
i8042: Probing ports directly.
CPU 0 Unable to handle kernel paging request at virtual addressffff800000008064
ERA:i8042_flush+0x50/0x198
RA:i8042_init+0x2a8/0x35cKernel panic - not syncing: Attempted to kill init!
You never answer me why in your test you should disable i8042 from V1 until V4. In normal use we use a single kernel for both host and guest.
Huacai
Quoted 89 lines
Disable
SERIO_I8042and its dependents (KEYBOARD_ATKBD,MOUSE_PS2) in theQEMU_KCONFIGfragment to prevent the driver from being built. All three options are scoped to loongarch.conf; no other architecture is affected.Wrap the QEMU invocation in
run_qemu()with timeout(1) using a local time limit so the test always terminates, even when QEMU does not exit on its own. This is useful for every architecture; on LoongArch, for example, QEMU provides no EFI runtime services andmachine_restart()falls through to an idle loop after kexec, so QEMU would never exit otherwise.Co-developed-by Kexin Liu <[email protected]>Signed-off-by Kexin Liu <[email protected]>Signed-off-by George Guo <[email protected]>--- tools/testing/selftests/kho/loongarch.conf | 11 +++++++++++ tools/testing/selftests/kho/vmtest.sh | 22 +++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tools/testing/selftests/kho/loongarch.conftools/testing/selftests/kho/loongarch.conf new file +11
-0@@ -0,0 +1,11 @@ +QEMU_CMD="qemu-system-loongarch64 -M virt -cpu la464" +QEMU_KCONFIG=" +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SPARSEMEM_MANUAL=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO_I8042 is not set +" +KERNEL_IMAGE="vmlinux.efi" +KERNEL_CMDLINE="console=ttyS0 earlycon kho_scratch=16M,16M,16M"tools/testing/selftests/kho/vmtest.sh +15
-8@@ -21,7 +21,7 @@ Options: -d) path to the kernel build directory -j) number of jobs for compilation, similar to -j in make -t) run test for target_arch, requires CROSS_COMPILE set - supported targets: aarch64, x86_64 + supported targets: aarch64, x86_64, loongarch64 -h) display this help EOF }@@ -111,12 +111,19 @@ function run_qemu() { cmdline="$cmdline kho=on panic=-1" - $qemu_cmd -m 1G -smp 2 -no-reboot -nographic -nodefaults \ - -accel kvm -accel hvf -accel tcg \ - -serial file:"$serial" \ - -append "$cmdline" \ - -kernel "$kernel" \ - -initrd "$initrd" + local qemu_args=( + -m 1G -smp 2 -no-reboot -nographic -nodefaults + -accel kvm -accel hvf -accel tcg + -serial file:"$serial" + -append "$cmdline" + -kernel "$kernel" + -initrd "$initrd" + ) + + # Bound the QEMU run so the test always terminates, even when QEMU + # does not exit on its own (e.g. no EFI runtime services after kexec). + local qemu_timeout=60 + timeout "$qemu_timeout" $qemu_cmd "${qemu_args[@]}" || true grep "KHO restore succeeded" "$serial" &> /dev/null || fail "KHO failed" }@@ -127,6 +134,7 @@ function target_to_arch() { case $target in aarch64) echo "arm64" ;; x86_64) echo "x86" ;; + loongarch64) echo "loongarch" ;; *) skip "architecture $target is not supported" esac } --2.53.0
Re: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
Hi Huacai,
Quoted 2 lines · Huacai Chen
You never answer me why in your test you should disable i8042 from V1 until V4. In normal use we use a single kernel for both host and guest.
I owe you an apology: I did not actually understand your question. I thought the commit message had already explained the reason (the i8042_flush() panic), so I treated it as answered and never addressed what you were really asking. Let me answer it directly now.
You are right that this is not just a selftest detail. i8042 is built on every LoongArch kernel: arch/loongarch/Kconfig selects ARCH_MIGHT_HAVE_PC_SERIO, and KEYBOARD_ATKBD and MOUSE_PS2 (both default
y) select SERIO_I8042 under it. So your "single kernel for host and guest" point is correct -- a normal defconfig kernel has i8042 built in.
On the QEMU virtual machine there is no i8042, so PNP finds nothing and i8042_pnp_init() falls back to probing the i8042 status and data registers (I8042_STATUS_REG, I8042_DATA_REG) directly. On LoongArch those registers are memory-mapped, and on the virtual machine they are not backed by any device, so i8042_flush() takes a page fault and the kernel panics before userspace. A normal LoongArch defconfig kernel booted as a QEMU guest hits the same panic -- the "# CONFIG_SERIO_I8042 is not set" in loongarch.conf is only a workaround to let the KHO selftest boot, not a fix.
The real fix is separate from the KHO series: make i8042 bail out on LoongArch when ACPI/PNP does not describe a controller, so the direct-port fallback never runs. I have prepared that as a standalone patch -- the relevant hunk is below -- and will send the full patch separately. The selftest workaround can be dropped once it lands.
drivers/input/serio/i8042-acpipnpio.h +0 -0
@@ -1633,8 +1633,14 @@ static int __init i8042_pnp_init(void)#else
pr_info("PNP: No PS/2 controller found.\n"); #if defined(__loongarch__)
- if (acpi_disabled == 0)
- return -ENODEV;
+ /*
+ * LoongArch legacy I/O ports are memory-mapped and are not
+ * safely probeable when no controller is present: a direct
+ * probe faults on the QEMU virtual machine and on any FDT-based
+ * boot. Do not fall back to probing them directly; if ACPI/PNP
+ * did not describe a controller, assume there is none.
+ */
+ return -ENODEV;
#else
if (x86_platform.legacy.i8042 !=
X86_LEGACY_I8042_EXPECTED_PRESENT)Thanks,
George
Huacai Chen
maintainerRe: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
Quoted 28 lines · George Guo
Hi Huacai,
Quoted 2 lines · Huacai Chen
You never answer me why in your test you should disable i8042 from V1 until V4. In normal use we use a single kernel for both host and guest.
I owe you an apology: I did not actually understand your question. I thought the commit message had already explained the reason (the
i8042_flush()panic), so I treated it as answered and never addressed what you were really asking. Let me answer it directly now.You are right that this is not just a selftest detail. i8042 is built on every LoongArch kernel:
arch/loongarch/KconfigselectsARCH_MIGHT_HAVE_PC_SERIO, andKEYBOARD_ATKBDandMOUSE_PS2(both default
y) selectSERIO_I8042under it. So your "single kernel for host and guest" point is correct -- a normal defconfig kernel has i8042 built in.On the QEMU virtual machine there is no i8042, so PNP finds nothing and
i8042_pnp_init()falls back to probing the i8042 status and data registers (I8042_STATUS_REG,I8042_DATA_REG) directly. On LoongArch those registers are memory-mapped, and on the virtual machine they are not backed by any device, soi8042_flush()takes a page fault and the kernel panics before userspace. A normal LoongArch defconfig kernel booted as a QEMU guest hits the same panic -- the "#CONFIG_SERIO_I8042is not set" in loongarch.conf is only a workaround to let the KHO selftest boot, not a fix.
Quoted 5 lines
The real fix is separate from the KHO series: make i8042 bail out on LoongArch when ACPI/PNP does not describe a controller, so the direct-port fallback never runs. I have prepared that as a standalone patch -- the relevant hunk is below -- and will send the full patch separately. The selftest workaround can be dropped once it lands.
You nearly answered nothing.
Does your employer use different kernels for host and guest in KylinOS?
Huacai
Quoted 24 lines
drivers/input/serio/i8042-acpipnpio.h +8
-2@@ -1633,8 +1633,14 @@ static int __init i8042_pnp_init(void)#else pr_info ("PNP: No PS/2 controller found.\n" );#if defined(__loongarch__) -if (acpi_disabled ==0 ) -return -ENODEV ; +/* +* LoongArch legacy I/O ports are memory-mapped and are not +* safely probeable when no controller is present: a direct +* probe faults on the QEMU virtual machine and on any FDT-based +* boot. Do not fall back to probing them directly; if ACPI/PNP +* did not describe a controller, assume there is none. +*/ +return -ENODEV ;#else if (x86_platform.legacy.i8042 !=X86_LEGACY_I8042_EXPECTED_PRESENT )Thanks,
George
Re: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
Hi Huacai,
Quoted 3 lines
You nearly answered nothing.
Does your employer use different kernels for host and guest in KylinOS?
No. Host and guests run the same distro kernel in KylinOS, and guests boot with edk2 firmware, so ACPI is delivered and i8042 bails out through the PNP path. That is the normal case and it never panics.
I have since finished the investigation, also for the firmware-less case. The same QEMU command with two kernels gives two different results, and the difference is the kernel configuration:
- A distro kernel (CONFIG_PCI_HOST_GENERIC=y) maps the PCI_IOBASE I/O window through DT PCIe host enumeration, so even without firmware the i8042 probe reads garbage and fails cleanly ("No controller found").
- The selftest's minimal kernel maps nothing there, so the same read takes a page fault in i8042_flush() and panics before userspace.
So the panic needs three conditions together: a firmware-less boot, SERIO_I8042=y (the Kconfig default), and no registered PIO range -- which is only the selftest-style kernel. I agree the mainline fix is not necessary. For the selftest I will enable CONFIG_PCI_HOST_GENERIC=y in loongarch.conf instead of disabling i8042, so the selftest kernel stays closer to a normal one; the standalone patch will not be sent.
Thanks,
George
Re: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
In reply to George GuoHi,
While preparing v5, I retested the LoongArch vmtest without the explicit kho_scratch=16M,16M,16M setting. That setting was masking a pre-existing bug in the generic percentage-based KHO scratch sizing.
The percentage heuristic itself is reasonable, but the old implementation calculated each per-node baseline after allocating the lowmem and global scratch areas. Since memblock allocations are marked MEMBLOCK_RSRV_KERN, those scratch areas were counted as new kernel demand and scaled again.
On the 1 GiB LoongArch guest, the 98.45 MiB reservation baseline and 32 MiB alignment made the old ordering request 224 MiB of lowmem scratch followed by 672 MiB for node 0. The node allocation failed and disabled KHO. I sent a separate generic fix here:
https://lore.kernel.org/loongarch/[email protected]
With that fix, the total aligned request is 448 MiB and the LoongArch vmtest passes using the default percentage-based sizing. I also ran the x86 KHO vmtest with the fix; it passes as well.
Therefore, I will remove kho_scratch=16M,16M,16M from loongarch.conf in v5 so that it tests the default sizing path, matching the existing x86 selftest behavior.
Thanks,
George
Pratyush Yadav
maintainerRe: [PATCH v4 4/4] selftests/kho: add LoongArch vmtest support
Quoted 11 lines · George Guo
Hi,
While preparing v5, I retested the LoongArch vmtest without the explicit
kho_scratch=16M,16M,16Msetting. That setting was masking a pre-existing bug in the generic percentage-based KHO scratch sizing.The percentage heuristic itself is reasonable, but the old implementation calculated each per-node baseline after allocating the lowmem and global scratch areas. Since memblock allocations are marked
MEMBLOCK_RSRV_KERN, those scratch areas were counted as new kernel demand and scaled again.
Quoted 6 lines
On the 1 GiB LoongArch guest, the 98.45 MiB reservation baseline and 32 MiB alignment made the old ordering request 224 MiB of lowmem scratch followed by 672 MiB for node 0. The node allocation failed and disabled KHO. I sent a separate generic fix here:
Oh, cool! Nice find. I just wrote Sourabh (+Cc) an email [0] about this too.
I think there is other wonky stuff going on with scratch sizing, like global scratch being inflated. See my email [0] about that.
Let me go review that patch, since this seems to be causing a lot of pain.
[0] https://lore.kernel.org/kexec/[email protected]/T/#t
Quoted 11 lines
With that fix, the total aligned request is 448 MiB and the LoongArch vmtest passes using the default percentage-based sizing. I also ran the x86 KHO vmtest with the fix; it passes as well.
Therefore, I will remove
kho_scratch=16M,16M,16Mfrom loongarch.conf in v5 so that it tests the default sizing path, matching the existing x86 selftest behavior.Thanks,
George
Signature · 2 lines
Regards, Pratyush Yadav