* [PATCHv2 0/6] arm64: zboot support
@ 2023-05-16 7:31 Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 1/6] kexec: Change the image probe's prototype Pingfan Liu
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
As more complicated capsule kernel format occurs like zboot, where the
compressed kernel is stored as a payload. The straight forward
decompression can not meet the demand.
As the first step, on aarch64, reading in the kernel file in a probe
method and decide how to unfold the content by the method itself.
The new designed probe interface returns two factors:
1. the parsed kernel_buf should be returned so that it can be used by
the image load method later.
2. the final fd passed to sys_kexec_file_load, since aarch64 kernel can
only work with Image format, the outer payload should be stripped and a
temporary file of Image should be created.
* Things left to do on arches besides aarch64 *
After substitution, although each probe mehod seems to have the same
prototype, they have differenct purpose on the first argument.
On aarch64, the argument is used to pass the kernel file name, while on
the other arches, it is used to passs the decompressed kernel.
This can be cured by scattering out the logic of reading the kernel file
into each probe. (This should be done by coccinelle. But let us keep a
small step for the time being)
v1 -> v2:
take in Jeremy's patches to implement zboot format support
use coccinelle and sed to substitue the image probe method prototype.
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
Jeremy Linton (4):
arm64: Fix some issues with zImage _probe()
kexec/zboot: Add arch independent zboot support
arm64: Add ZBOOT PE containing compressed image support
arm64: Hook up the ZBOOT support as vmlinuz
Pingfan Liu (2):
kexec: Change the image probe's prototype
arm64: Scatter the logic of reading of kernel file into each probe
include/kexec-pe-zboot.h | 15 +++
kexec/Makefile | 1 +
kexec/arch/arm/kexec-arm.h | 6 +-
kexec/arch/arm/kexec-uImage-arm.c | 2 +-
kexec/arch/arm64/Makefile | 3 +-
kexec/arch/arm64/image-header.h | 1 +
kexec/arch/arm64/kexec-arm64.c | 1 +
kexec/arch/arm64/kexec-arm64.h | 19 ++-
kexec/arch/arm64/kexec-elf-arm64.c | 8 +-
kexec/arch/arm64/kexec-image-arm64.c | 7 +-
kexec/arch/arm64/kexec-uImage-arm64.c | 17 ++-
kexec/arch/arm64/kexec-vmlinuz-arm64.c | 101 ++++++++++++++++
kexec/arch/arm64/kexec-zImage-arm64.c | 32 ++---
kexec/arch/cris/kexec-cris.h | 3 +-
kexec/arch/cris/kexec-elf-cris.c | 2 +-
kexec/arch/hppa/kexec-elf-hppa.c | 2 +-
kexec/arch/hppa/kexec-hppa.h | 3 +-
kexec/arch/i386/kexec-beoboot-x86.c | 4 +-
kexec/arch/i386/kexec-bzImage.c | 2 +-
kexec/arch/i386/kexec-elf-x86.c | 2 +-
kexec/arch/i386/kexec-mb2-x86.c | 5 +-
kexec/arch/i386/kexec-multiboot-x86.c | 7 +-
kexec/arch/i386/kexec-nbi.c | 2 +-
kexec/arch/i386/kexec-x86.h | 19 ++-
kexec/arch/ia64/kexec-elf-ia64.c | 2 +-
kexec/arch/ia64/kexec-ia64.h | 3 +-
kexec/arch/loongarch/kexec-elf-loongarch.c | 3 +-
kexec/arch/loongarch/kexec-loongarch.h | 7 +-
kexec/arch/loongarch/kexec-pei-loongarch.c | 3 +-
kexec/arch/m68k/kexec-elf-m68k.c | 2 +-
kexec/arch/m68k/kexec-m68k.h | 3 +-
kexec/arch/mips/kexec-elf-mips.c | 2 +-
kexec/arch/mips/kexec-mips.h | 3 +-
kexec/arch/ppc/kexec-dol-ppc.c | 2 +-
kexec/arch/ppc/kexec-elf-ppc.c | 2 +-
kexec/arch/ppc/kexec-ppc.h | 9 +-
kexec/arch/ppc/kexec-uImage-ppc.c | 2 +-
kexec/arch/ppc64/kexec-elf-ppc64.c | 2 +-
kexec/arch/ppc64/kexec-ppc64.h | 3 +-
kexec/arch/sh/kexec-elf-sh.c | 2 +-
kexec/arch/sh/kexec-sh.h | 12 +-
kexec/arch/sh/kexec-uImage-sh.c | 2 +-
kexec/arch/x86_64/kexec-bzImage64.c | 2 +-
kexec/arch/x86_64/kexec-elf-x86_64.c | 2 +-
kexec/arch/x86_64/kexec-x86_64.h | 10 +-
kexec/kexec-pe-zboot.c | 134 +++++++++++++++++++++
kexec/kexec.c | 50 +++++---
kexec/kexec.h | 4 +-
48 files changed, 423 insertions(+), 107 deletions(-)
create mode 100644 include/kexec-pe-zboot.h
create mode 100644 kexec/arch/arm64/kexec-vmlinuz-arm64.c
create mode 100644 kexec/kexec-pe-zboot.c
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCHv2 1/6] kexec: Change the image probe's prototype
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
@ 2023-05-16 7:31 ` Pingfan Liu
2023-05-24 11:52 ` Simon Horman
2023-05-16 7:31 ` [PATCHv2 2/6] arm64: Fix some issues with zImage _probe() Pingfan Liu
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
As more complicated kernel format occurs such as zboot, where the
compressed kernel is stored as a payload. The straight forward
decompression can not meet the demand.
A new image probe method is expected to read in the kernel file and decide
how to unfold the content by itself.
This patch aims to change the image probe's prototype from
typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
to
typedef int (probe_t)(const char *kernel_buf, off_t kernel_size, struct kexec_info *info);
Later, info can be used to return both the file descriptor and the
parsed kernel buffer.
In case your are curious, the remaing part of the log describes the
process of the substitution of the new prototype, which can be divided
into three groups.
1. change function pointer and its callsites:
sed -i 's/(probe_t)(const char \*kernel_buf, off_t kernel_size);/(probe_t)(const char \*kernel, off_t kernel_size, struct kexec_info \*info);/g' kexec/kexec.h
sed -i 's/\.probe(\([^,]*\), \([^)]*\))/\.probe(\1, \2, NULL)/g' kexec/kexec.c
2. change the function declaration and definition of each 'probe'
instance by coccinelle because they may cross lines
The cocci file looks like:
@ rule1 @
identifier fn =~ "_probe";
identifier buf, size;
typedef off_t;
@@
-int fn(const char *buf, off_t size)
+int fn(const char *buf, off_t size, struct kexec_info *info)
{
...
}
@ rule2 @
identifier fn =~ "_probe";
identifier buf, size;
typedef off_t;
@@
+int fn(const char *buf, off_t size, struct kexec_info *info);
-int fn(const char *buf, off_t size);
Then running the command
spatch --sp-file cocci/define.cocci --dir kexec --include-headers > ../define.patch
git apply --directory=kexec ../define.patch
3. change the direct calls to the probe instances
Originally I planned to achieve this by coccinelle, but failed similar
to [1]. I have tried using "-I and --include" option for coccinelle, but it
still did not work.
Checking the direct callsite by "git grep "_probe(" | grep -v const"
Fortunatelly, it turns out that only a few direct callsites exist, which
lies in i386, and easy to be amended manually.
Anyway, just FYI, the cocci file looks like:
@ rule1 @
identifier fn =~ "_probe";
identifier buf, size;
identifier info;
typedef off_t;
@@
int fn(const char *buf, off_t size, struct kexec_info *info);
/* change the direct callsite of any probe */
@ rule2 @
identifier rule1.fn;
expression E1, E2;
@@
fn(E1, E2
+ ,NULL
)
Then running the command:
spatch --sp-file cocci/direct.cocci --dir kexec --include-headers
[1]: https://lore.kernel.org/all/alpine.DEB.2.22.394.2202280705080.3112@hadrien/T/
Signed-off-by: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
---
kexec/arch/arm/kexec-arm.h | 6 ++++--
kexec/arch/arm/kexec-uImage-arm.c | 2 +-
kexec/arch/arm64/kexec-arm64.h | 15 +++++++++++----
kexec/arch/arm64/kexec-elf-arm64.c | 3 ++-
kexec/arch/arm64/kexec-image-arm64.c | 3 ++-
kexec/arch/arm64/kexec-uImage-arm64.c | 2 +-
kexec/arch/arm64/kexec-zImage-arm64.c | 3 ++-
kexec/arch/cris/kexec-cris.h | 3 ++-
kexec/arch/cris/kexec-elf-cris.c | 2 +-
kexec/arch/hppa/kexec-elf-hppa.c | 2 +-
kexec/arch/hppa/kexec-hppa.h | 3 ++-
kexec/arch/i386/kexec-beoboot-x86.c | 4 ++--
kexec/arch/i386/kexec-bzImage.c | 2 +-
kexec/arch/i386/kexec-elf-x86.c | 2 +-
kexec/arch/i386/kexec-mb2-x86.c | 5 +++--
kexec/arch/i386/kexec-multiboot-x86.c | 7 ++++---
kexec/arch/i386/kexec-nbi.c | 2 +-
kexec/arch/i386/kexec-x86.h | 19 +++++++++++++------
kexec/arch/ia64/kexec-elf-ia64.c | 2 +-
kexec/arch/ia64/kexec-ia64.h | 3 ++-
kexec/arch/loongarch/kexec-elf-loongarch.c | 3 ++-
kexec/arch/loongarch/kexec-loongarch.h | 7 +++++--
kexec/arch/loongarch/kexec-pei-loongarch.c | 3 ++-
kexec/arch/m68k/kexec-elf-m68k.c | 2 +-
kexec/arch/m68k/kexec-m68k.h | 3 ++-
kexec/arch/mips/kexec-elf-mips.c | 2 +-
kexec/arch/mips/kexec-mips.h | 3 ++-
kexec/arch/ppc/kexec-dol-ppc.c | 2 +-
kexec/arch/ppc/kexec-elf-ppc.c | 2 +-
kexec/arch/ppc/kexec-ppc.h | 9 ++++++---
kexec/arch/ppc/kexec-uImage-ppc.c | 2 +-
kexec/arch/ppc64/kexec-elf-ppc64.c | 2 +-
kexec/arch/ppc64/kexec-ppc64.h | 3 ++-
kexec/arch/sh/kexec-elf-sh.c | 2 +-
kexec/arch/sh/kexec-sh.h | 12 ++++++++----
kexec/arch/sh/kexec-uImage-sh.c | 2 +-
kexec/arch/x86_64/kexec-bzImage64.c | 2 +-
kexec/arch/x86_64/kexec-elf-x86_64.c | 2 +-
kexec/arch/x86_64/kexec-x86_64.h | 10 +++++++---
kexec/kexec.c | 10 +++++-----
kexec/kexec.h | 2 +-
41 files changed, 109 insertions(+), 66 deletions(-)
diff --git a/kexec/arch/arm/kexec-arm.h b/kexec/arch/arm/kexec-arm.h
index a74cce2..4d447b2 100644
--- a/kexec/arch/arm/kexec-arm.h
+++ b/kexec/arch/arm/kexec-arm.h
@@ -9,12 +9,14 @@
extern off_t initrd_base, initrd_size;
-int zImage_arm_probe(const char *buf, off_t len);
+int zImage_arm_probe(const char *buf, off_t len, struct kexec_info *info);
+
int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void zImage_arm_usage(void);
-int uImage_arm_probe(const char *buf, off_t len);
+int uImage_arm_probe(const char *buf, off_t len, struct kexec_info *info);
+
int uImage_arm_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
extern int have_sysfs_fdt(void);
diff --git a/kexec/arch/arm/kexec-uImage-arm.c b/kexec/arch/arm/kexec-uImage-arm.c
index 03c2f4d..d955eb3 100644
--- a/kexec/arch/arm/kexec-uImage-arm.c
+++ b/kexec/arch/arm/kexec-uImage-arm.c
@@ -9,7 +9,7 @@
#include "../../kexec.h"
#include "kexec-arm.h"
-int uImage_arm_probe(const char *buf, off_t len)
+int uImage_arm_probe(const char *buf, off_t len, struct kexec_info *info)
{
return uImage_probe_kernel(buf, len, IH_ARCH_ARM);
}
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 5eb9fc0..2825c46 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -29,22 +29,29 @@
#define NOT_KV_ADDR (0x0)
#define NOT_PADDR (ULONGLONG_MAX)
-int elf_arm64_probe(const char *kernel_buf, off_t kernel_size);
+int elf_arm64_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info);
+
int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info);
void elf_arm64_usage(void);
-int image_arm64_probe(const char *kernel_buf, off_t kernel_size);
+int image_arm64_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info);
+
int image_arm64_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info);
void image_arm64_usage(void);
-int uImage_arm64_probe(const char *buf, off_t len);
+int uImage_arm64_probe(const char *buf, off_t len, struct kexec_info *info);
+
int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void uImage_arm64_usage(void);
-int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size);
+int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info);
+
int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info);
void zImage_arm64_usage(void);
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
index e14f8e9..0299349 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -16,7 +16,8 @@
#include "kexec-elf.h"
#include "kexec-syscall.h"
-int elf_arm64_probe(const char *kernel_buf, off_t kernel_size)
+int elf_arm64_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
index aa8f2e2..e8b72f9 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -14,7 +14,8 @@
#include "kexec-syscall.h"
#include "arch/options.h"
-int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
+int image_arm64_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info)
{
const struct arm64_image_header *h;
diff --git a/kexec/arch/arm64/kexec-uImage-arm64.c b/kexec/arch/arm64/kexec-uImage-arm64.c
index c466913..f5b94c8 100644
--- a/kexec/arch/arm64/kexec-uImage-arm64.c
+++ b/kexec/arch/arm64/kexec-uImage-arm64.c
@@ -9,7 +9,7 @@
#include "../../kexec.h"
#include "kexec-arm64.h"
-int uImage_arm64_probe(const char *buf, off_t len)
+int uImage_arm64_probe(const char *buf, off_t len, struct kexec_info *info)
{
int ret;
diff --git a/kexec/arch/arm64/kexec-zImage-arm64.c b/kexec/arch/arm64/kexec-zImage-arm64.c
index 6ee82ff..c04669f 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -40,7 +40,8 @@
* fd : File descriptor of the temp file containing the decompressed
* Image.
*/
-int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size)
+int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info)
{
int ret = -1;
int fd = 0;
diff --git a/kexec/arch/cris/kexec-cris.h b/kexec/arch/cris/kexec-cris.h
index 7ee9945..40b7b83 100644
--- a/kexec/arch/cris/kexec-cris.h
+++ b/kexec/arch/cris/kexec-cris.h
@@ -1,7 +1,8 @@
#ifndef KEXEC_CRIS_H
#define KEXEC_CRIS_H
-int elf_cris_probe(const char *buf, off_t len);
+int elf_cris_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_cris_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_cris_usage(void);
diff --git a/kexec/arch/cris/kexec-elf-cris.c b/kexec/arch/cris/kexec-elf-cris.c
index 7e251e6..124f059 100644
--- a/kexec/arch/cris/kexec-elf-cris.c
+++ b/kexec/arch/cris/kexec-elf-cris.c
@@ -40,7 +40,7 @@
#include <arch/options.h>
#include "kexec-cris.h"
-int elf_cris_probe(const char *buf, off_t len)
+int elf_cris_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/hppa/kexec-elf-hppa.c b/kexec/arch/hppa/kexec-elf-hppa.c
index 474a919..92c4b12 100644
--- a/kexec/arch/hppa/kexec-elf-hppa.c
+++ b/kexec/arch/hppa/kexec-elf-hppa.c
@@ -30,7 +30,7 @@
extern unsigned long phys_offset;
-int elf_hppa_probe(const char *buf, off_t len)
+int elf_hppa_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/hppa/kexec-hppa.h b/kexec/arch/hppa/kexec-hppa.h
index 485e5b6..9e37516 100644
--- a/kexec/arch/hppa/kexec-hppa.h
+++ b/kexec/arch/hppa/kexec-hppa.h
@@ -1,7 +1,8 @@
#ifndef KEXEC_HPPA_H
#define KEXEC_HPPA_H
-int elf_hppa_probe(const char *buf, off_t len);
+int elf_hppa_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_hppa_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_hppa_usage(void);
diff --git a/kexec/arch/i386/kexec-beoboot-x86.c b/kexec/arch/i386/kexec-beoboot-x86.c
index d949ab8..e72d64f 100644
--- a/kexec/arch/i386/kexec-beoboot-x86.c
+++ b/kexec/arch/i386/kexec-beoboot-x86.c
@@ -38,7 +38,7 @@
#include "kexec-x86.h"
#include <arch/options.h>
-int beoboot_probe(const char *buf, off_t len)
+int beoboot_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct beoboot_header bb_header;
const char *cmdline, *kernel;
@@ -57,7 +57,7 @@ int beoboot_probe(const char *buf, off_t len)
*/
cmdline = buf + sizeof(bb_header);
kernel = cmdline + bb_header.cmdline_size;
- result = bzImage_probe(kernel, bb_header.kernel_size);
+ result = bzImage_probe(kernel, bb_header.kernel_size, NULL);
return result;
}
diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c
index 1b8f20c..0415df2 100644
--- a/kexec/arch/i386/kexec-bzImage.c
+++ b/kexec/arch/i386/kexec-bzImage.c
@@ -42,7 +42,7 @@
static const int probe_debug = 0;
int bzImage_support_efi_boot = 0;
-int bzImage_probe(const char *buf, off_t len)
+int bzImage_probe(const char *buf, off_t len, struct kexec_info *info)
{
const struct x86_linux_header *header;
if ((uintmax_t)len < (uintmax_t)(2 * 512)) {
diff --git a/kexec/arch/i386/kexec-elf-x86.c b/kexec/arch/i386/kexec-elf-x86.c
index 8eba242..87ac41d 100644
--- a/kexec/arch/i386/kexec-elf-x86.c
+++ b/kexec/arch/i386/kexec-elf-x86.c
@@ -96,7 +96,7 @@ int elf_x86_any_probe(const char *buf, off_t len, enum coretype arch)
return result;
}
-int elf_x86_probe(const char *buf, off_t len) {
+int elf_x86_probe(const char *buf, off_t len, struct kexec_info *info) {
return elf_x86_any_probe(buf, len, CORE_TYPE_ELF32);
}
diff --git a/kexec/arch/i386/kexec-mb2-x86.c b/kexec/arch/i386/kexec-mb2-x86.c
index 0d2e93b..0d2b734 100644
--- a/kexec/arch/i386/kexec-mb2-x86.c
+++ b/kexec/arch/i386/kexec-mb2-x86.c
@@ -72,7 +72,8 @@ struct multiboot2_header_info {
#define ALIGN_UP(addr, align) \
((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
-int multiboot2_x86_probe(const char *buf, off_t buf_len)
+int multiboot2_x86_probe(const char *buf, off_t buf_len,
+ struct kexec_info *info)
/* Is it a good idea to try booting this file? */
{
int i, len;
@@ -438,7 +439,7 @@ int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len,
uint64_t rel_min, rel_max;
/* Probe for the MB header if it's not already found */
- if (mbh == NULL && multiboot_x86_probe(buf, len) != 1)
+ if (mbh == NULL && multiboot_x86_probe(buf, len, NULL) != 1)
{
fprintf(stderr, "Cannot find a loadable multiboot2 header.\n");
return -1;
diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c
index 33c885a..e4ec1c9 100644
--- a/kexec/arch/i386/kexec-multiboot-x86.c
+++ b/kexec/arch/i386/kexec-multiboot-x86.c
@@ -69,7 +69,8 @@ static off_t mbh_offset = 0;
#define MIN(_x,_y) (((_x)<=(_y))?(_x):(_y))
-int multiboot_x86_probe(const char *buf, off_t buf_len)
+int multiboot_x86_probe(const char *buf, off_t buf_len,
+ struct kexec_info *info)
/* Is it a good idea to try booting this file? */
{
int i, len;
@@ -119,7 +120,7 @@ int multiboot_x86_probe(const char *buf, off_t buf_len)
return -1;
}
} else {
- if ((i=elf_x86_probe(buf, buf_len)) < 0)
+ if ((i=elf_x86_probe(buf, buf_len, NULL)) < 0)
return i;
}
if (mbh->flags & MULTIBOOT_UNSUPPORTED) {
@@ -252,7 +253,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
static const char short_options[] = KEXEC_ARCH_OPT_STR "";
/* Probe for the MB header if it's not already found */
- if (mbh == NULL && multiboot_x86_probe(buf, len) != 1) {
+ if (mbh == NULL && multiboot_x86_probe(buf, len, NULL) != 1) {
fprintf(stderr, "Cannot find a loadable multiboot header.\n");
return -1;
}
diff --git a/kexec/arch/i386/kexec-nbi.c b/kexec/arch/i386/kexec-nbi.c
index 8eb2154..16f5d6b 100644
--- a/kexec/arch/i386/kexec-nbi.c
+++ b/kexec/arch/i386/kexec-nbi.c
@@ -68,7 +68,7 @@ struct imgheader
static const int probe_debug = 0;
-int nbi_probe(const char *buf, off_t len)
+int nbi_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct imgheader hdr;
struct segheader seg;
diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h
index 46e2898..01e5a41 100644
--- a/kexec/arch/i386/kexec-x86.h
+++ b/kexec/arch/i386/kexec-x86.h
@@ -55,7 +55,8 @@ struct arch_options_t {
uint8_t reuse_video_type;
};
-int multiboot_x86_probe(const char *buf, off_t len);
+int multiboot_x86_probe(const char *buf, off_t len, struct kexec_info *info);
+
int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void multiboot_x86_usage(void);
@@ -63,15 +64,19 @@ void multiboot_x86_usage(void);
int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void multiboot2_x86_usage(void);
-int multiboot2_x86_probe(const char *buf, off_t buf_len);
+int multiboot2_x86_probe(const char *buf, off_t buf_len,
+ struct kexec_info *info);
+
+
+int elf_x86_probe(const char *buf, off_t len, struct kexec_info *info);
-int elf_x86_probe(const char *buf, off_t len);
int elf_x86_any_probe(const char *buf, off_t len, enum coretype arch);
int elf_x86_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_x86_usage(void);
-int bzImage_probe(const char *buf, off_t len);
+int bzImage_probe(const char *buf, off_t len, struct kexec_info *info);
+
int bzImage_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void bzImage_usage(void);
@@ -82,12 +87,14 @@ int do_bzImage_load(struct kexec_info *info,
const char *dtb, off_t dtb_len,
int real_mode_entry);
-int beoboot_probe(const char *buf, off_t len);
+int beoboot_probe(const char *buf, off_t len, struct kexec_info *info);
+
int beoboot_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void beoboot_usage(void);
-int nbi_probe(const char *buf, off_t len);
+int nbi_probe(const char *buf, off_t len, struct kexec_info *info);
+
int nbi_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void nbi_usage(void);
diff --git a/kexec/arch/ia64/kexec-elf-ia64.c b/kexec/arch/ia64/kexec-elf-ia64.c
index 142dee3..f01ea46 100644
--- a/kexec/arch/ia64/kexec-elf-ia64.c
+++ b/kexec/arch/ia64/kexec-elf-ia64.c
@@ -53,7 +53,7 @@ extern unsigned long saved_efi_memmap_size;
*
* Make sure that the file image has a reasonable chance of working.
*/
-int elf_ia64_probe(const char *buf, off_t len)
+int elf_ia64_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/ia64/kexec-ia64.h b/kexec/arch/ia64/kexec-ia64.h
index 31e4041..a481215 100644
--- a/kexec/arch/ia64/kexec-ia64.h
+++ b/kexec/arch/ia64/kexec-ia64.h
@@ -2,7 +2,8 @@
#define KEXEC_IA64_H
extern int max_memory_ranges;
-int elf_ia64_probe(const char *buf, off_t len);
+int elf_ia64_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_ia64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_ia64_usage(void);
diff --git a/kexec/arch/loongarch/kexec-elf-loongarch.c b/kexec/arch/loongarch/kexec-elf-loongarch.c
index 45387ca..8484b04 100644
--- a/kexec/arch/loongarch/kexec-elf-loongarch.c
+++ b/kexec/arch/loongarch/kexec-elf-loongarch.c
@@ -23,7 +23,8 @@
off_t initrd_base, initrd_size;
-int elf_loongarch_probe(const char *kernel_buf, off_t kernel_size)
+int elf_loongarch_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/loongarch/kexec-loongarch.h b/kexec/arch/loongarch/kexec-loongarch.h
index 5120a26..d6b077d 100644
--- a/kexec/arch/loongarch/kexec-loongarch.h
+++ b/kexec/arch/loongarch/kexec-loongarch.h
@@ -18,12 +18,15 @@
#define KiB(x) ((x) * 1024UL)
#define MiB(x) (KiB(x) * 1024UL)
-int elf_loongarch_probe(const char *kernel_buf, off_t kernel_size);
+int elf_loongarch_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info);
+
int elf_loongarch_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_loongarch_usage(void);
-int pei_loongarch_probe(const char *buf, off_t len);
+int pei_loongarch_probe(const char *buf, off_t len, struct kexec_info *info);
+
int pei_loongarch_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void pei_loongarch_usage(void);
diff --git a/kexec/arch/loongarch/kexec-pei-loongarch.c b/kexec/arch/loongarch/kexec-pei-loongarch.c
index 1a11103..326ce4a 100644
--- a/kexec/arch/loongarch/kexec-pei-loongarch.c
+++ b/kexec/arch/loongarch/kexec-pei-loongarch.c
@@ -24,7 +24,8 @@
#include "kexec-loongarch.h"
#include "arch/options.h"
-int pei_loongarch_probe(const char *kernel_buf, off_t kernel_size)
+int pei_loongarch_probe(const char *kernel_buf, off_t kernel_size,
+ struct kexec_info *info)
{
const struct loongarch_image_header *h;
diff --git a/kexec/arch/m68k/kexec-elf-m68k.c b/kexec/arch/m68k/kexec-elf-m68k.c
index a2bf7ee..e3a71c8 100644
--- a/kexec/arch/m68k/kexec-elf-m68k.c
+++ b/kexec/arch/m68k/kexec-elf-m68k.c
@@ -33,7 +33,7 @@
#define PAGE_SIZE 4 KiB
-int elf_m68k_probe(const char *buf, off_t len)
+int elf_m68k_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/m68k/kexec-m68k.h b/kexec/arch/m68k/kexec-m68k.h
index 99482c4..74eb67c 100644
--- a/kexec/arch/m68k/kexec-m68k.h
+++ b/kexec/arch/m68k/kexec-m68k.h
@@ -1,7 +1,8 @@
#ifndef KEXEC_M68K_H
#define KEXEC_M68K_H
-int elf_m68k_probe(const char *buf, off_t len);
+int elf_m68k_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_m68k_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_m68k_usage(void);
diff --git a/kexec/arch/mips/kexec-elf-mips.c b/kexec/arch/mips/kexec-elf-mips.c
index 230d806..628cc68 100644
--- a/kexec/arch/mips/kexec-elf-mips.c
+++ b/kexec/arch/mips/kexec-elf-mips.c
@@ -92,7 +92,7 @@ static int patch_initrd_info(char *cmdline, unsigned long base,
return 0;
}
-int elf_mips_probe(const char *buf, off_t len)
+int elf_mips_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/mips/kexec-mips.h b/kexec/arch/mips/kexec-mips.h
index 222c815..0fbd6a4 100644
--- a/kexec/arch/mips/kexec-mips.h
+++ b/kexec/arch/mips/kexec-mips.h
@@ -12,7 +12,8 @@
#define CORE_TYPE_ELF32 1
#define CORE_TYPE_ELF64 2
-int elf_mips_probe(const char *buf, off_t len);
+int elf_mips_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_mips_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_mips_usage(void);
diff --git a/kexec/arch/ppc/kexec-dol-ppc.c b/kexec/arch/ppc/kexec-dol-ppc.c
index 800c072..0c44c13 100644
--- a/kexec/arch/ppc/kexec-dol-ppc.c
+++ b/kexec/arch/ppc/kexec-dol-ppc.c
@@ -234,7 +234,7 @@ void fix_dol_segments_overlaps(dol_segment * seg, int max_segs)
}
}
-int dol_ppc_probe(const char *buf, off_t dol_length)
+int dol_ppc_probe(const char *buf, off_t dol_length, struct kexec_info *info)
{
dol_header header, *h;
int i, valid = 0;
diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c
index 4a4886e..7f81310 100644
--- a/kexec/arch/ppc/kexec-elf-ppc.c
+++ b/kexec/arch/ppc/kexec-elf-ppc.c
@@ -73,7 +73,7 @@ static struct boot_notes {
};
#endif
-int elf_ppc_probe(const char *buf, off_t len)
+int elf_ppc_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
diff --git a/kexec/arch/ppc/kexec-ppc.h b/kexec/arch/ppc/kexec-ppc.h
index 04e728e..8c9e385 100644
--- a/kexec/arch/ppc/kexec-ppc.h
+++ b/kexec/arch/ppc/kexec-ppc.h
@@ -25,17 +25,20 @@ extern struct {
#define SIZE_16M (16*1024*1024UL)
-int elf_ppc_probe(const char *buf, off_t len);
+int elf_ppc_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_ppc_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_ppc_usage(void);
-int uImage_ppc_probe(const char *buf, off_t len);
+int uImage_ppc_probe(const char *buf, off_t len, struct kexec_info *info);
+
int uImage_ppc_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void uImage_ppc_usage(void);
-int dol_ppc_probe(const char *buf, off_t len);
+int dol_ppc_probe(const char *buf, off_t len, struct kexec_info *info);
+
int dol_ppc_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void dol_ppc_usage(void);
diff --git a/kexec/arch/ppc/kexec-uImage-ppc.c b/kexec/arch/ppc/kexec-uImage-ppc.c
index e8f7adc..cea0278 100644
--- a/kexec/arch/ppc/kexec-uImage-ppc.c
+++ b/kexec/arch/ppc/kexec-uImage-ppc.c
@@ -76,7 +76,7 @@ char *slurp_ramdisk_ppc(const char *filename, off_t *r_size)
return buf;
}
-int uImage_ppc_probe(const char *buf, off_t len)
+int uImage_ppc_probe(const char *buf, off_t len, struct kexec_info *info)
{
return uImage_probe_kernel(buf, len, IH_ARCH_PPC);
}
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index 01d045f..429851f 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -45,7 +45,7 @@ uint64_t initrd_base, initrd_size;
unsigned char reuse_initrd = 0;
const char *ramdisk;
-int elf_ppc64_probe(const char *buf, off_t len)
+int elf_ppc64_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/ppc64/kexec-ppc64.h b/kexec/arch/ppc64/kexec-ppc64.h
index 434b4bf..fea3640 100644
--- a/kexec/arch/ppc64/kexec-ppc64.h
+++ b/kexec/arch/ppc64/kexec-ppc64.h
@@ -19,7 +19,8 @@ extern int get_devtree_value(const char *fname, unsigned long long *pvalue);
int setup_memory_ranges(unsigned long kexec_flags);
-int elf_ppc64_probe(const char *buf, off_t len);
+int elf_ppc64_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_ppc64_usage(void);
diff --git a/kexec/arch/sh/kexec-elf-sh.c b/kexec/arch/sh/kexec-elf-sh.c
index 897552c..00c0c7e 100644
--- a/kexec/arch/sh/kexec-elf-sh.c
+++ b/kexec/arch/sh/kexec-elf-sh.c
@@ -40,7 +40,7 @@
#include "crashdump-sh.h"
#include "kexec-sh.h"
-int elf_sh_probe(const char *buf, off_t len)
+int elf_sh_probe(const char *buf, off_t len, struct kexec_info *info)
{
struct mem_ehdr ehdr;
int result;
diff --git a/kexec/arch/sh/kexec-sh.h b/kexec/arch/sh/kexec-sh.h
index 7d28ade..d320240 100644
--- a/kexec/arch/sh/kexec-sh.h
+++ b/kexec/arch/sh/kexec-sh.h
@@ -3,21 +3,25 @@
#define COMMAND_LINE_SIZE 2048
-int uImage_sh_probe(const char *buf, off_t len);
+int uImage_sh_probe(const char *buf, off_t len, struct kexec_info *info);
+
int uImage_sh_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
-int zImage_sh_probe(const char *buf, off_t len);
+int zImage_sh_probe(const char *buf, off_t len, struct kexec_info *info);
+
int zImage_sh_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void zImage_sh_usage(void);
-int elf_sh_probe(const char *buf, off_t len);
+int elf_sh_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_sh_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_sh_usage(void);
-int netbsd_sh_probe(const char *buf, off_t len);
+int netbsd_sh_probe(const char *buf, off_t len, struct kexec_info *info);
+
int netbsd_sh_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void netbsd_sh_usage(void);
diff --git a/kexec/arch/sh/kexec-uImage-sh.c b/kexec/arch/sh/kexec-uImage-sh.c
index 130f12c..7b8284b 100644
--- a/kexec/arch/sh/kexec-uImage-sh.c
+++ b/kexec/arch/sh/kexec-uImage-sh.c
@@ -11,7 +11,7 @@
#include "../../kexec.h"
#include "kexec-sh.h"
-int uImage_sh_probe(const char *buf, off_t len)
+int uImage_sh_probe(const char *buf, off_t len, struct kexec_info *info)
{
return uImage_probe_kernel(buf, len, IH_ARCH_SH);
}
diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c
index aba4e3b..35dce27 100644
--- a/kexec/arch/x86_64/kexec-bzImage64.c
+++ b/kexec/arch/x86_64/kexec-bzImage64.c
@@ -43,7 +43,7 @@
static const int probe_debug = 0;
-int bzImage64_probe(const char *buf, off_t len)
+int bzImage64_probe(const char *buf, off_t len, struct kexec_info *info)
{
const struct x86_linux_header *header;
diff --git a/kexec/arch/x86_64/kexec-elf-x86_64.c b/kexec/arch/x86_64/kexec-elf-x86_64.c
index 7f9540a..f61e670 100644
--- a/kexec/arch/x86_64/kexec-elf-x86_64.c
+++ b/kexec/arch/x86_64/kexec-elf-x86_64.c
@@ -41,7 +41,7 @@
#include "../i386/crashdump-x86.h"
#include <arch/options.h>
-int elf_x86_64_probe(const char *buf, off_t len)
+int elf_x86_64_probe(const char *buf, off_t len, struct kexec_info *info)
{
return elf_x86_any_probe(buf, len, CORE_TYPE_ELF64);
}
diff --git a/kexec/arch/x86_64/kexec-x86_64.h b/kexec/arch/x86_64/kexec-x86_64.h
index 21c3a73..8dbec70 100644
--- a/kexec/arch/x86_64/kexec-x86_64.h
+++ b/kexec/arch/x86_64/kexec-x86_64.h
@@ -23,12 +23,14 @@ struct entry64_regs {
uint64_t rip;
};
-int elf_x86_64_probe(const char *buf, off_t len);
+int elf_x86_64_probe(const char *buf, off_t len, struct kexec_info *info);
+
int elf_x86_64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void elf_x86_64_usage(void);
-int bzImage64_probe(const char *buf, off_t len);
+int bzImage64_probe(const char *buf, off_t len, struct kexec_info *info);
+
int bzImage64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void bzImage64_usage(void);
@@ -36,6 +38,8 @@ void bzImage64_usage(void);
int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void multiboot2_x86_usage(void);
-int multiboot2_x86_probe(const char *buf, off_t buf_len);
+int multiboot2_x86_probe(const char *buf, off_t buf_len,
+ struct kexec_info *info);
+
#endif /* KEXEC_X86_64_H */
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 36bb2ad..f5ea73c 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -742,13 +742,13 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
return -1;
} else {
/* make sure our file is really of that type */
- if (file_type[i].probe(kernel_buf, kernel_size) < 0)
+ if (file_type[i].probe(kernel_buf, kernel_size, NULL) < 0)
guess_only = 1;
}
}
if (!type || guess_only) {
for (i = 0; i < file_types; i++) {
- if (file_type[i].probe(kernel_buf, kernel_size) == 0)
+ if (file_type[i].probe(kernel_buf, kernel_size, NULL) == 0)
break;
}
if (i == file_types) {
@@ -1304,15 +1304,15 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
#ifdef __aarch64__
/* handle Image.gz like cases */
if (is_zlib_file(kernel, &kernel_size)) {
- if ((ret = file_type[i].probe(kernel, kernel_size)) >= 0) {
+ if ((ret = file_type[i].probe(kernel, kernel_size, NULL)) >= 0) {
kernel_fd = ret;
break;
}
} else
- if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+ if (file_type[i].probe(kernel_buf, kernel_size, NULL) >= 0)
break;
#else
- if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+ if (file_type[i].probe(kernel_buf, kernel_size, NULL) >= 0)
break;
#endif
}
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 0d820ad..0706e46 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -191,7 +191,7 @@ unsigned long locate_hole(struct kexec_info *info,
unsigned long hole_min, unsigned long hole_max,
int hole_end);
-typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
+typedef int (probe_t)(const char *kernel, off_t kernel_size, struct kexec_info *info);
typedef int (load_t )(int argc, char **argv,
const char *kernel_buf, off_t kernel_size,
struct kexec_info *info);
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCHv2 2/6] arm64: Fix some issues with zImage _probe()
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 1/6] kexec: Change the image probe's prototype Pingfan Liu
@ 2023-05-16 7:31 ` Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 3/6] arm64: Scatter the logic of reading of kernel file into each probe Pingfan Liu
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Jeremy Linton, Pingfan Liu, horms, ardb
From: Jeremy Linton <jeremy.linton@arm.com>
Current compilers note that fname will be null while
attempting to print failures from strdup().
Further fix a memory leak caused by kernel_uncompressed_buf
never being used/freed before the allocated block is replaced
by the one returned by slurp_decompress_file().
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
---
kexec/arch/arm64/kexec-zImage-arm64.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/kexec/arch/arm64/kexec-zImage-arm64.c b/kexec/arch/arm64/kexec-zImage-arm64.c
index c04669f..8a23dea 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -56,8 +56,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
}
if (!(fname = strdup(FILENAME_IMAGE))) {
- dbgprintf("%s: Can't duplicate strings %s\n", __func__,
- fname);
+ dbgprintf("%s: Can't duplicate strings\n", __func__);
return -1;
}
@@ -68,15 +67,6 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
goto fail_mkstemp;
}
- kernel_uncompressed_buf =
- (char *) calloc(kernel_size, sizeof(off_t));
- if (!kernel_uncompressed_buf) {
- dbgprintf("%s: Can't calloc %ld bytes\n",
- __func__, kernel_size);
- ret= -ENOMEM;
- goto fail_calloc;
- }
-
/* slurp in the input kernel */
dbgprintf("%s: ", __func__);
kernel_uncompressed_buf = slurp_decompress_file(kernel_buf,
@@ -129,7 +119,6 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
fail_bad_header:
free(kernel_uncompressed_buf);
-fail_calloc:
if (fd >= 0)
close(fd);
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCHv2 3/6] arm64: Scatter the logic of reading of kernel file into each probe
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 1/6] kexec: Change the image probe's prototype Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 2/6] arm64: Fix some issues with zImage _probe() Pingfan Liu
@ 2023-05-16 7:31 ` Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 4/6] kexec/zboot: Add arch independent zboot support Pingfan Liu
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
As more complicated capsule kernel format ,such as zboot, emerge, where
the compressed kernel is stored as a payload. The straight forward
decompression can not meet the demand.
Therefore, let a probe method read in the kernel file and decide how to
unfold the content by the method itself.
Since other arches still read the kernel image before probe method,
the purpose of the first argument differs from that in aarch64.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
---
kexec/arch/arm64/kexec-arm64.h | 6 ++--
kexec/arch/arm64/kexec-elf-arm64.c | 7 +++-
kexec/arch/arm64/kexec-image-arm64.c | 6 +++-
kexec/arch/arm64/kexec-uImage-arm64.c | 17 ++++++---
kexec/arch/arm64/kexec-zImage-arm64.c | 18 +++-------
kexec/kexec.c | 50 +++++++++++++++++----------
kexec/kexec.h | 2 ++
7 files changed, 66 insertions(+), 40 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 2825c46..bce93a1 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -29,14 +29,14 @@
#define NOT_KV_ADDR (0x0)
#define NOT_PADDR (ULONGLONG_MAX)
-int elf_arm64_probe(const char *kernel_buf, off_t kernel_size,
+int elf_arm64_probe(const char *kern_fname, off_t kernel_size,
struct kexec_info *info);
int elf_arm64_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info);
void elf_arm64_usage(void);
-int image_arm64_probe(const char *kernel_buf, off_t kernel_size,
+int image_arm64_probe(const char *kern_fname, off_t kernel_size,
struct kexec_info *info);
int image_arm64_load(int argc, char **argv, const char *kernel_buf,
@@ -49,7 +49,7 @@ int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void uImage_arm64_usage(void);
-int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
+int zImage_arm64_probe(const char *kern_fname, off_t kernel_size,
struct kexec_info *info);
int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
index 0299349..38afecf 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -16,12 +16,14 @@
#include "kexec-elf.h"
#include "kexec-syscall.h"
-int elf_arm64_probe(const char *kernel_buf, off_t kernel_size,
+int elf_arm64_probe(const char *kern_fname, off_t kernel_size,
struct kexec_info *info)
{
struct mem_ehdr ehdr;
+ char *kernel_buf;
int result;
+ kernel_buf = slurp_file(kern_fname, &kernel_size);
result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0);
if (result < 0) {
@@ -35,8 +37,11 @@ int elf_arm64_probe(const char *kernel_buf, off_t kernel_size,
goto on_exit;
}
+ info->kernel_fd = open(kern_fname, O_RDONLY);
+ info->kernel_buf = kernel_buf;
result = 0;
on_exit:
+ free(kernel_buf);
free_elf_info(&ehdr);
return result;
}
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
index e8b72f9..668091f 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -14,11 +14,13 @@
#include "kexec-syscall.h"
#include "arch/options.h"
-int image_arm64_probe(const char *kernel_buf, off_t kernel_size,
+int image_arm64_probe(const char *kern_fname, off_t kernel_size,
struct kexec_info *info)
{
const struct arm64_image_header *h;
+ char *kernel_buf;
+ kernel_buf = slurp_file(kern_fname, &kernel_size);
if (kernel_size < sizeof(struct arm64_image_header)) {
dbgprintf("%s: No arm64 image header.\n", __func__);
return -1;
@@ -30,6 +32,8 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size,
dbgprintf("%s: Bad arm64 image header.\n", __func__);
return -1;
}
+ info->kernel_fd = open(kern_fname, O_RDONLY);
+ info->kernel_buf = kernel_buf;
return 0;
}
diff --git a/kexec/arch/arm64/kexec-uImage-arm64.c b/kexec/arch/arm64/kexec-uImage-arm64.c
index f5b94c8..cce1c76 100644
--- a/kexec/arch/arm64/kexec-uImage-arm64.c
+++ b/kexec/arch/arm64/kexec-uImage-arm64.c
@@ -3,26 +3,35 @@
*/
#include <stdint.h>
#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <image.h>
#include <kexec-uImage.h>
#include "../../kexec.h"
#include "kexec-arm64.h"
-int uImage_arm64_probe(const char *buf, off_t len, struct kexec_info *info)
+int uImage_arm64_probe(const char *kern_fname, off_t len, struct kexec_info *info)
{
int ret;
+ char *kernel_buf;
- ret = uImage_probe_kernel(buf, len, IH_ARCH_ARM64);
+ kernel_buf = slurp_file(kern_fname, &len);
+ ret = uImage_probe_kernel(kernel_buf, len, IH_ARCH_ARM64);
/* 0 - valid uImage.
* -1 - uImage is corrupted.
* 1 - image is not a uImage.
*/
- if (!ret)
+ if (!ret) {
+ info->kernel_fd = open(kern_fname, O_RDONLY);
+ info->kernel_buf = kernel_buf;
return 0;
- else
+ }
+ else {
+ free(kernel_buf);
return -1;
+ }
}
int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
diff --git a/kexec/arch/arm64/kexec-zImage-arm64.c b/kexec/arch/arm64/kexec-zImage-arm64.c
index 8a23dea..1c32275 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -37,10 +37,8 @@
/* Returns:
* -1 : in case of error/invalid format (not a valid Image.gz format.
- * fd : File descriptor of the temp file containing the decompressed
- * Image.
*/
-int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
+int zImage_arm64_probe(const char *kern_fname, off_t kernel_size,
struct kexec_info *info)
{
int ret = -1;
@@ -50,11 +48,6 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
char *kernel_uncompressed_buf = NULL;
const struct arm64_image_header *h;
- if (!is_zlib_file(kernel_buf, &kernel_size)) {
- dbgprintf("%s: Not an zImage file (Image.gz).\n", __func__);
- return -1;
- }
-
if (!(fname = strdup(FILENAME_IMAGE))) {
dbgprintf("%s: Can't duplicate strings\n", __func__);
return -1;
@@ -69,7 +62,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
/* slurp in the input kernel */
dbgprintf("%s: ", __func__);
- kernel_uncompressed_buf = slurp_decompress_file(kernel_buf,
+ kernel_uncompressed_buf = slurp_decompress_file(kern_fname,
&kernel_size);
/* check for correct header magic */
@@ -108,13 +101,12 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size,
ret = -1;
goto fail_bad_header;
}
-
+ info->kernel_fd = kernel_fd;
+ info->kernel_buf = kernel_uncompressed_buf;
unlink(fname);
-
- free(kernel_uncompressed_buf);
free(fname);
- return kernel_fd;
+ return 0;
fail_bad_header:
free(kernel_uncompressed_buf);
diff --git a/kexec/kexec.c b/kexec/kexec.c
index f5ea73c..767b173 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -701,7 +701,7 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
unsigned long kexec_flags, int skip_checks, void *entry)
{
char *kernel;
- char *kernel_buf;
+ char *kernel_buf, *probe_buf;
off_t kernel_size;
int i = 0;
int result;
@@ -720,11 +720,15 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
return -1;
}
kernel = argv[fileind];
+#ifndef __aarch64__
/* slurp in the input kernel */
- kernel_buf = slurp_decompress_file(kernel, &kernel_size);
+ probe_buf = kernel_buf = slurp_decompress_file(kernel, &kernel_size);
dbgprintf("kernel: %p kernel_size: %#llx\n",
kernel_buf, (unsigned long long)kernel_size);
+#else
+ probe_buf = kernel;
+#endif
if (get_memory_ranges(&info.memory_range, &info.memory_ranges,
info.kexec_flags) < 0 || info.memory_ranges == 0) {
@@ -742,14 +746,21 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
return -1;
} else {
/* make sure our file is really of that type */
- if (file_type[i].probe(kernel_buf, kernel_size, NULL) < 0)
+ if (file_type[i].probe(probe_buf, kernel_size, &info) < 0) {
guess_only = 1;
+ } else {
+ if (info.kernel_buf != NULL)
+ kernel_buf = info.kernel_buf;
+ }
}
}
if (!type || guess_only) {
for (i = 0; i < file_types; i++) {
- if (file_type[i].probe(kernel_buf, kernel_size, NULL) == 0)
+ if (file_type[i].probe(probe_buf, kernel_size, &info) == 0) {
+ if (info.kernel_buf != NULL)
+ kernel_buf = info.kernel_buf;
break;
+ }
}
if (i == file_types) {
fprintf(stderr, "Cannot determine the file type "
@@ -1266,7 +1277,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
int kernel_fd, i;
struct kexec_info info;
int ret = 0;
- char *kernel_buf;
+ char *kernel_buf, *probe_buf;
off_t kernel_size;
memset(&info, 0, sizeof(info));
@@ -1278,6 +1289,8 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
info.file_mode = 1;
info.initrd_fd = -1;
+ info.kernel_fd = -1;
+ info.kernel_buf = NULL;
if (!is_kexec_file_load_implemented())
return EFALLBACK;
@@ -1290,6 +1303,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
kernel = argv[fileind];
+#ifndef __aarch64__
kernel_fd = open(kernel, O_RDONLY);
if (kernel_fd == -1) {
fprintf(stderr, "Failed to open file %s:%s\n", kernel,
@@ -1298,23 +1312,23 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
}
/* slurp in the input kernel */
- kernel_buf = slurp_decompress_file(kernel, &kernel_size);
+ probe_buf = kernel_buf = slurp_decompress_file(kernel, &kernel_size);
+#else
+ probe_buf = kernel;
+#endif
for (i = 0; i < file_types; i++) {
-#ifdef __aarch64__
- /* handle Image.gz like cases */
- if (is_zlib_file(kernel, &kernel_size)) {
- if ((ret = file_type[i].probe(kernel, kernel_size, NULL)) >= 0) {
- kernel_fd = ret;
- break;
+ if (file_type[i].probe(probe_buf, kernel_size, &info) >= 0) {
+ if (info.kernel_fd != -1) {
+ close(kernel_fd);
+ kernel_fd = info.kernel_fd;
+ }
+ if (info.kernel_buf != NULL) {
+ free(kernel_buf);
+ kernel_buf = info.kernel_buf;
}
- } else
- if (file_type[i].probe(kernel_buf, kernel_size, NULL) >= 0)
- break;
-#else
- if (file_type[i].probe(kernel_buf, kernel_size, NULL) >= 0)
break;
-#endif
+ }
}
if (i == file_types) {
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 0706e46..2dca917 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -164,7 +164,9 @@ struct kexec_info {
unsigned long file_mode :1;
/* Filled by kernel image processing code */
+ int kernel_fd;
int initrd_fd;
+ char *kernel_buf;
char *command_line;
int command_line_len;
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCHv2 4/6] kexec/zboot: Add arch independent zboot support
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
` (2 preceding siblings ...)
2023-05-16 7:31 ` [PATCHv2 3/6] arm64: Scatter the logic of reading of kernel file into each probe Pingfan Liu
@ 2023-05-16 7:31 ` Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 5/6] arm64: Add ZBOOT PE containing compressed image support Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 6/6] arm64: Hook up the ZBOOT support as vmlinuz Pingfan Liu
5 siblings, 0 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Jeremy Linton, Pingfan Liu, horms, ardb
From: Jeremy Linton <jeremy.linton@arm.com>
The linux kernel CONFIG_ZBOOT option creates
self decompressing PE kernel images. So this means
that kexec should have a generic understanding of
the format which may be used by multiple arches.
So lets add an arch independent validation
and decompression routine.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
[Modified by Pingfan to adapt the new probe interface]
Signed-off-by: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
---
include/kexec-pe-zboot.h | 15 +++++
kexec/Makefile | 1 +
kexec/kexec-pe-zboot.c | 134 +++++++++++++++++++++++++++++++++++++++
3 files changed, 150 insertions(+)
create mode 100644 include/kexec-pe-zboot.h
create mode 100644 kexec/kexec-pe-zboot.c
diff --git a/include/kexec-pe-zboot.h b/include/kexec-pe-zboot.h
new file mode 100644
index 0000000..6381485
--- /dev/null
+++ b/include/kexec-pe-zboot.h
@@ -0,0 +1,15 @@
+#ifndef __KEXEC_PE_ZBOOT_H__
+#define __KEXEC_PE_ZBOOT_H__
+
+/* see drivers/firmware/efi/libstub/zboot-header.S */
+struct linux_pe_zboot_header {
+ uint32_t mz_magic;
+ uint32_t image_type;
+ uint32_t payload_offset;
+ uint32_t payload_size;
+ uint32_t reserved[2];
+ uint32_t compress_type;
+};
+
+int pez_prepare(const char *crude_buf, off_t kernel_size, struct kexec_info *info);
+#endif
diff --git a/kexec/Makefile b/kexec/Makefile
index 8a52e8d..11682bf 100644
--- a/kexec/Makefile
+++ b/kexec/Makefile
@@ -17,6 +17,7 @@ KEXEC_SRCS_base += kexec/kexec-elf-exec.c
KEXEC_SRCS_base += kexec/kexec-elf-core.c
KEXEC_SRCS_base += kexec/kexec-elf-rel.c
KEXEC_SRCS_base += kexec/kexec-elf-boot.c
+KEXEC_SRCS_base += kexec/kexec-pe-zboot.c
KEXEC_SRCS_base += kexec/kexec-iomem.c
KEXEC_SRCS_base += kexec/firmware_memmap.c
KEXEC_SRCS_base += kexec/crashdump.c
diff --git a/kexec/kexec-pe-zboot.c b/kexec/kexec-pe-zboot.c
new file mode 100644
index 0000000..24330a1
--- /dev/null
+++ b/kexec/kexec-pe-zboot.c
@@ -0,0 +1,134 @@
+/*
+ * Generic PE compressed Image (vmlinuz, ZBOOT) support.
+ *
+ * Several distros use 'make zinstall' with CONFIG_ZBOOT
+ * enabled to create UEFI PE images that contain
+ * a decompressor and a compressed kernel image.
+ *
+ * Currently we cannot use kexec_file_load() to load vmlinuz
+ * PE images that self decompress.
+ *
+ * To support ZBOOT, we should:
+ * a). Copy the compressed contents of vmlinuz to a temporary file.
+ * b). Decompress (gunzip-decompress) the contents inside the
+ * temporary file.
+ * c). Validate the resulting image and write it back to the
+ * temporary file.
+ * d). Pass the 'fd' of the temporary file to the kernel space.
+ *
+ * This module contains the arch independent code for the above,
+ * arch specific PE and image checks should wrap calls
+ * to functions in this module.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "kexec.h"
+#include <kexec-pe-zboot.h>
+
+#define FILENAME_IMAGE "/tmp/ImageXXXXXX"
+
+/*
+ * Returns -1 : in case of error/invalid format (not a valid PE+compressed ZBOOT format.
+ *
+ * crude_buf: the content, which is read from the kernel file without any processing
+ */
+int pez_prepare(const char *crude_buf, off_t kernel_size, struct kexec_info *info)
+{
+ int ret = -1;
+ int fd = 0;
+ int kernel_fd = 0;
+ char *fname = NULL;
+ char *kernel_uncompressed_buf = NULL;
+ off_t decompressed_size = 0;
+ const struct linux_pe_zboot_header *z;
+
+ z = (const struct linux_pe_zboot_header *)(crude_buf);
+
+ if (memcmp(&z->image_type, "zimg", sizeof(z->image_type))) {
+ dbgprintf("%s: PE doesn't contain a compressed kernel.\n", __func__);
+ return -1;
+ }
+
+ /*
+ * At the moment its possible to create images with more compression
+ * algorithms than are supported here, error out if we detect that.
+ */
+ if (memcmp(&z->compress_type, "gzip", 4) &&
+ memcmp(&z->compress_type, "lzma", 4)) {
+ dbgprintf("%s: kexec can only decompress gziped and lzma images.\n", __func__);
+ return -1;
+ }
+
+ if (kernel_size < z->payload_offset + z->payload_size) {
+ dbgprintf("%s: PE too small to contain complete payload.\n", __func__);
+ return -1;
+ }
+
+ if (!(fname = strdup(FILENAME_IMAGE))) {
+ dbgprintf("%s: Can't duplicate strings\n", __func__);
+ return -1;
+ }
+
+ if ((fd = mkstemp(fname)) < 0) {
+ dbgprintf("%s: Can't open file %s\n", __func__, fname);
+ ret = -1;
+ goto fail_mkstemp;
+ }
+
+ if (write(fd, &crude_buf[z->payload_offset],
+ z->payload_size) != z->payload_size) {
+ dbgprintf("%s: Can't write the compressed file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_write;
+ }
+
+ kernel_uncompressed_buf = slurp_decompress_file(fname,
+ &decompressed_size);
+
+ dbgprintf("%s: decompressed size %ld\n", __func__, decompressed_size);
+
+ lseek(fd, 0, SEEK_SET);
+
+ if (write(fd, kernel_uncompressed_buf,
+ decompressed_size) != decompressed_size) {
+ dbgprintf("%s: Can't write the decompressed file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ kernel_fd = open(fname, O_RDONLY);
+ if (kernel_fd == -1) {
+ dbgprintf("%s: Failed to open file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ dbgprintf("%s: ", __func__);
+
+ info->kernel_fd = kernel_fd;
+ info->kernel_buf = kernel_uncompressed_buf;
+ ret = 0;
+ goto fail_write;
+
+fail_bad_header:
+ free(kernel_uncompressed_buf);
+
+fail_write:
+ if (fd >= 0)
+ close(fd);
+
+ unlink(fname);
+
+fail_mkstemp:
+ free(fname);
+
+ return ret;
+}
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCHv2 5/6] arm64: Add ZBOOT PE containing compressed image support
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
` (3 preceding siblings ...)
2023-05-16 7:31 ` [PATCHv2 4/6] kexec/zboot: Add arch independent zboot support Pingfan Liu
@ 2023-05-16 7:31 ` Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 6/6] arm64: Hook up the ZBOOT support as vmlinuz Pingfan Liu
5 siblings, 0 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Jeremy Linton, Pingfan Liu, horms, ardb
From: Jeremy Linton <jeremy.linton@arm.com>
The kernel EFI stub ZBOOT feature creates a PE that
contains a compressed linux kernel image. The stub
when run in a valid UEFI environment then decompresses
the resulting image and executes it.
Support these image formats with kexec as well to avoid
having to keep an alternate kernel image around.
This patch adds a the _probe() and usage() routines needed
for kexec to understand this format.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
[Modified by Pingfan to adapt the new probe interface]
Signed-off-by: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
---
| 1 +
kexec/arch/arm64/kexec-vmlinuz-arm64.c | 101 +++++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 kexec/arch/arm64/kexec-vmlinuz-arm64.c
--git a/kexec/arch/arm64/image-header.h b/kexec/arch/arm64/image-header.h
index 158d411..26bb02f 100644
--- a/kexec/arch/arm64/image-header.h
+++ b/kexec/arch/arm64/image-header.h
@@ -37,6 +37,7 @@ struct arm64_image_header {
static const uint8_t arm64_image_magic[4] = {'A', 'R', 'M', 0x64U};
static const uint8_t arm64_image_pe_sig[2] = {'M', 'Z'};
+static const uint8_t arm64_pe_machtype[6] = {'P','E', 0x0, 0x0, 0x64, 0xAA};
static const uint64_t arm64_image_flag_be = (1UL << 0);
static const uint64_t arm64_image_flag_page_size = (3UL << 1);
static const uint64_t arm64_image_flag_placement = (1UL << 3);
diff --git a/kexec/arch/arm64/kexec-vmlinuz-arm64.c b/kexec/arch/arm64/kexec-vmlinuz-arm64.c
new file mode 100644
index 0000000..8c3f7c6
--- /dev/null
+++ b/kexec/arch/arm64/kexec-vmlinuz-arm64.c
@@ -0,0 +1,101 @@
+/*
+ * ARM64 PE compressed Image (vmlinuz, ZBOOT) support.
+ *
+ * Several distros use 'make zinstall' rule inside
+ * 'arch/arm64/boot/Makefile' to install the arm64
+ * ZBOOT compressed file inside the boot destination
+ * directory (for e.g. /boot).
+ *
+ * Currently we cannot use kexec_file_load() to load vmlinuz
+ * PE images that self decompress.
+ *
+ * To support ZBOOT, we should:
+ * a). Copy the compressed contents of vmlinuz to a temporary file.
+ * b). Decompress (gunzip-decompress) the contents inside the
+ * temporary file.
+ * c). Validate the resulting image and write it back to the
+ * temporary file.
+ * d). Pass the 'fd' of the temporary file to the kernel space.
+ *
+ * Note this, module doesn't provide a _load() function instead
+ * relying on image_arm64_load() to load the resulting decompressed
+ * image.
+ *
+ * So basically the kernel space still gets a decompressed
+ * kernel image to load via kexec-tools.
+ */
+
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "kexec-arm64.h"
+#include <kexec-pe-zboot.h>
+#include "arch/options.h"
+
+
+/* Returns:
+ * -1 : in case of error/invalid format (not a valid PE+compressed ZBOOT format.
+ */
+int pez_arm64_probe(const char *kern_fname, off_t kernel_size,
+ struct kexec_info *info)
+{
+ int ret = -1;
+ const struct arm64_image_header *h;
+ char *kernel_buf;
+
+ kernel_buf = slurp_file(kern_fname, &kernel_size);
+ if (!kernel_buf)
+ return -1;
+ h = (const struct arm64_image_header *)(kernel_buf);
+
+ dbgprintf("%s: PROBE.\n", __func__);
+ if (kernel_size < sizeof(struct arm64_image_header)) {
+ dbgprintf("%s: Not large enough to be a PE image.\n", __func__);
+ return -1;
+ }
+ if (!arm64_header_check_pe_sig(h)) {
+ dbgprintf("%s: Not an PE image.\n", __func__);
+ return -1;
+ }
+
+ if (kernel_size < sizeof(struct arm64_image_header) + h->pe_header) {
+ dbgprintf("%s: PE image offset larger than image.\n", __func__);
+ return -1;
+ }
+
+ if (memcmp(&kernel_buf[h->pe_header],
+ arm64_pe_machtype, sizeof(arm64_pe_machtype))) {
+ dbgprintf("%s: PE header doesn't match machine type.\n", __func__);
+ return -1;
+ }
+
+ ret = pez_prepare(kernel_buf, kernel_size, info);
+
+ if (!ret) {
+ /* validate the arm64 specific header */
+ struct arm64_image_header hdr_check;
+ if (read(info->kernel_fd, &hdr_check, sizeof(hdr_check)) != sizeof(hdr_check))
+ goto bad_header;
+
+ lseek(info->kernel_fd, 0, SEEK_SET);
+
+ if (!arm64_header_check_magic(&hdr_check)) {
+ dbgprintf("%s: Bad arm64 image header.\n", __func__);
+ goto bad_header;
+ }
+ }
+
+ return ret;
+bad_header:
+ close(info->kernel_fd);
+ free(info->kernel_buf);
+ return -1;
+}
+
+void pez_arm64_usage(void)
+{
+ printf(
+" An ARM64 vmlinuz, PE image of a compressed, little endian.\n"
+" kernel, built with ZBOOT enabled.\n\n");
+}
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCHv2 6/6] arm64: Hook up the ZBOOT support as vmlinuz
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
` (4 preceding siblings ...)
2023-05-16 7:31 ` [PATCHv2 5/6] arm64: Add ZBOOT PE containing compressed image support Pingfan Liu
@ 2023-05-16 7:31 ` Pingfan Liu
5 siblings, 0 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-05-16 7:31 UTC (permalink / raw)
To: kexec; +Cc: Jeremy Linton, Pingfan Liu, horms, ardb
From: Jeremy Linton <jeremy.linton@arm.com>
Add the previously defined _probe() and _usage() routines
to the kexec file types table, and build the new module.
It should be noted that this "vmlinuz" support reuses the
"Image" support to actually load the resulting image after
it has been decompressed to a temporary file.
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
---
kexec/arch/arm64/Makefile | 3 ++-
kexec/arch/arm64/kexec-arm64.c | 1 +
kexec/arch/arm64/kexec-arm64.h | 4 ++++
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index d27c8ee..900f246 100644
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -16,7 +16,8 @@ arm64_KEXEC_SRCS += \
kexec/arch/arm64/kexec-elf-arm64.c \
kexec/arch/arm64/kexec-uImage-arm64.c \
kexec/arch/arm64/kexec-image-arm64.c \
- kexec/arch/arm64/kexec-zImage-arm64.c
+ kexec/arch/arm64/kexec-zImage-arm64.c \
+ kexec/arch/arm64/kexec-vmlinuz-arm64.c
arm64_UIMAGE = kexec/kexec-uImage.c
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index ec6df4b..f6f96df 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -75,6 +75,7 @@ struct file_type file_type[] = {
{"Image", image_arm64_probe, image_arm64_load, image_arm64_usage},
{"uImage", uImage_arm64_probe, uImage_arm64_load, uImage_arm64_usage},
{"zImage", zImage_arm64_probe, zImage_arm64_load, zImage_arm64_usage},
+ {"vmlinuz", pez_arm64_probe, image_arm64_load, pez_arm64_usage},
};
int file_types = sizeof(file_type) / sizeof(file_type[0]);
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index bce93a1..e2fa97c 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -56,6 +56,10 @@ int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info);
void zImage_arm64_usage(void);
+int pez_arm64_probe(const char *kern_fname, off_t kernel_size,
+ struct kexec_info *info);
+void pez_arm64_usage(void);
+
extern off_t initrd_base;
extern off_t initrd_size;
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCHv2 1/6] kexec: Change the image probe's prototype
2023-05-16 7:31 ` [PATCHv2 1/6] kexec: Change the image probe's prototype Pingfan Liu
@ 2023-05-24 11:52 ` Simon Horman
2023-05-25 3:32 ` Pingfan Liu
0 siblings, 1 reply; 11+ messages in thread
From: Simon Horman @ 2023-05-24 11:52 UTC (permalink / raw)
To: Pingfan Liu; +Cc: kexec, horms, ardb, jeremy.linton
On Tue, May 16, 2023 at 03:31:19PM +0800, Pingfan Liu wrote:
> As more complicated kernel format occurs such as zboot, where the
> compressed kernel is stored as a payload. The straight forward
> decompression can not meet the demand.
>
> A new image probe method is expected to read in the kernel file and decide
> how to unfold the content by itself.
>
> This patch aims to change the image probe's prototype from
> typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
> to
> typedef int (probe_t)(const char *kernel_buf, off_t kernel_size, struct kexec_info *info);
>
> Later, info can be used to return both the file descriptor and the
> parsed kernel buffer.
>
> In case your are curious, the remaing part of the log describes the
> process of the substitution of the new prototype, which can be divided
> into three groups.
>
> 1. change function pointer and its callsites:
> sed -i 's/(probe_t)(const char \*kernel_buf, off_t kernel_size);/(probe_t)(const char \*kernel, off_t kernel_size, struct kexec_info \*info);/g' kexec/kexec.h
> sed -i 's/\.probe(\([^,]*\), \([^)]*\))/\.probe(\1, \2, NULL)/g' kexec/kexec.c
>
> 2. change the function declaration and definition of each 'probe'
> instance by coccinelle because they may cross lines
>
> The cocci file looks like:
>
> @ rule1 @
> identifier fn =~ "_probe";
> identifier buf, size;
> typedef off_t;
> @@
>
> -int fn(const char *buf, off_t size)
> +int fn(const char *buf, off_t size, struct kexec_info *info)
> {
> ...
> }
>
> @ rule2 @
> identifier fn =~ "_probe";
> identifier buf, size;
> typedef off_t;
> @@
>
> +int fn(const char *buf, off_t size, struct kexec_info *info);
> -int fn(const char *buf, off_t size);
>
> Then running the command
> spatch --sp-file cocci/define.cocci --dir kexec --include-headers > ../define.patch
> git apply --directory=kexec ../define.patch
>
> 3. change the direct calls to the probe instances
>
> Originally I planned to achieve this by coccinelle, but failed similar
> to [1]. I have tried using "-I and --include" option for coccinelle, but it
> still did not work.
>
> Checking the direct callsite by "git grep "_probe(" | grep -v const"
> Fortunatelly, it turns out that only a few direct callsites exist, which
> lies in i386, and easy to be amended manually.
>
> Anyway, just FYI, the cocci file looks like:
> @ rule1 @
> identifier fn =~ "_probe";
> identifier buf, size;
> identifier info;
> typedef off_t;
> @@
>
> int fn(const char *buf, off_t size, struct kexec_info *info);
>
> /* change the direct callsite of any probe */
> @ rule2 @
> identifier rule1.fn;
> expression E1, E2;
> @@
>
> fn(E1, E2
> + ,NULL
> )
>
> Then running the command:
> spatch --sp-file cocci/direct.cocci --dir kexec --include-headers
>
> [1]: https://lore.kernel.org/all/alpine.DEB.2.22.394.2202280705080.3112@hadrien/T/
>
> Signed-off-by: Pingfan Liu <piliu@redhat.com>
> To: kexec@lists.infradead.org
> Cc: horms@verge.net.au
> Cc: ardb@kernel.org
> Cc: jeremy.linton@arm.com
Unfortunately I am seeing a build failure on (at least) sh4 with this change:
../../kexec/arch/sh/kexec-zImage-sh.c:54:5: error: conflicting types for ‘zImage_sh_probe’
54 | int zImage_sh_probe(const char *buf, off_t UNUSED(len))
| ^~~~~~~~~~~~~~~
In file included from ../../kexec/arch/sh/kexec-zImage-sh.c:27:
../../kexec/arch/sh/kexec-sh.h:11:5: note: previous declaration of ‘zImage_sh_probe’ was here
11 | int zImage_sh_probe(const char *buf, off_t len, struct kexec_info *info);
| ^~~~~~~~~~~~~~~
../../kexec/arch/sh/kexec-zImage-sh.c:29:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
29 | static const int probe_debug = 0;
| ^~~~~~~~~~~
make[1]: *** [Makefile:124: kexec/arch/sh/kexec-zImage-sh.o] Error 1
make[1]: *** Waiting for unfinished jobs....
../../kexec/arch/sh/kexec-netbsd-sh.c:28:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
28 | static const int probe_debug = 0;
| ^~~~~~~~~~~
Link: https://github.com/horms/kexec-tools/actions/runs/5068250493/jobs/9100319093#step:5:215
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCHv2 1/6] kexec: Change the image probe's prototype
2023-05-24 11:52 ` Simon Horman
@ 2023-05-25 3:32 ` Pingfan Liu
2023-06-01 1:45 ` Pingfan Liu
0 siblings, 1 reply; 11+ messages in thread
From: Pingfan Liu @ 2023-05-25 3:32 UTC (permalink / raw)
To: Simon Horman; +Cc: kexec, horms, ardb, jeremy.linton
On Wed, May 24, 2023 at 7:53 PM Simon Horman <horms@kernel.org> wrote:
>
> On Tue, May 16, 2023 at 03:31:19PM +0800, Pingfan Liu wrote:
> > As more complicated kernel format occurs such as zboot, where the
> > compressed kernel is stored as a payload. The straight forward
> > decompression can not meet the demand.
> >
> > A new image probe method is expected to read in the kernel file and decide
> > how to unfold the content by itself.
> >
> > This patch aims to change the image probe's prototype from
> > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
> > to
> > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size, struct kexec_info *info);
> >
> > Later, info can be used to return both the file descriptor and the
> > parsed kernel buffer.
> >
> > In case your are curious, the remaing part of the log describes the
> > process of the substitution of the new prototype, which can be divided
> > into three groups.
> >
> > 1. change function pointer and its callsites:
> > sed -i 's/(probe_t)(const char \*kernel_buf, off_t kernel_size);/(probe_t)(const char \*kernel, off_t kernel_size, struct kexec_info \*info);/g' kexec/kexec.h
> > sed -i 's/\.probe(\([^,]*\), \([^)]*\))/\.probe(\1, \2, NULL)/g' kexec/kexec.c
> >
> > 2. change the function declaration and definition of each 'probe'
> > instance by coccinelle because they may cross lines
> >
> > The cocci file looks like:
> >
> > @ rule1 @
> > identifier fn =~ "_probe";
> > identifier buf, size;
> > typedef off_t;
> > @@
> >
> > -int fn(const char *buf, off_t size)
> > +int fn(const char *buf, off_t size, struct kexec_info *info)
> > {
> > ...
> > }
> >
> > @ rule2 @
> > identifier fn =~ "_probe";
> > identifier buf, size;
> > typedef off_t;
> > @@
> >
> > +int fn(const char *buf, off_t size, struct kexec_info *info);
> > -int fn(const char *buf, off_t size);
> >
> > Then running the command
> > spatch --sp-file cocci/define.cocci --dir kexec --include-headers > ../define.patch
> > git apply --directory=kexec ../define.patch
> >
> > 3. change the direct calls to the probe instances
> >
> > Originally I planned to achieve this by coccinelle, but failed similar
> > to [1]. I have tried using "-I and --include" option for coccinelle, but it
> > still did not work.
> >
> > Checking the direct callsite by "git grep "_probe(" | grep -v const"
> > Fortunatelly, it turns out that only a few direct callsites exist, which
> > lies in i386, and easy to be amended manually.
> >
> > Anyway, just FYI, the cocci file looks like:
> > @ rule1 @
> > identifier fn =~ "_probe";
> > identifier buf, size;
> > identifier info;
> > typedef off_t;
> > @@
> >
> > int fn(const char *buf, off_t size, struct kexec_info *info);
> >
> > /* change the direct callsite of any probe */
> > @ rule2 @
> > identifier rule1.fn;
> > expression E1, E2;
> > @@
> >
> > fn(E1, E2
> > + ,NULL
> > )
> >
> > Then running the command:
> > spatch --sp-file cocci/direct.cocci --dir kexec --include-headers
> >
> > [1]: https://lore.kernel.org/all/alpine.DEB.2.22.394.2202280705080.3112@hadrien/T/
> >
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > To: kexec@lists.infradead.org
> > Cc: horms@verge.net.au
> > Cc: ardb@kernel.org
> > Cc: jeremy.linton@arm.com
>
> Unfortunately I am seeing a build failure on (at least) sh4 with this change:
>
> ../../kexec/arch/sh/kexec-zImage-sh.c:54:5: error: conflicting types for ‘zImage_sh_probe’
> 54 | int zImage_sh_probe(const char *buf, off_t UNUSED(len))
> | ^~~~~~~~~~~~~~~
It may be because the macro UNUSED() is not tackled correctly by coccinelle.
And there are several other places, which use UNUSED()
git grep UNUSED | grep probe
kexec/arch/arm/kexec-zImage-arm.c:138:int zImage_arm_probe(const char
*UNUSED(buf), off_t UNUSED(len))
kexec/arch/s390/kexec-image.c:219:image_s390_probe(const char
*UNUSED(kernel_buf), off_t UNUSED(kernel_size))
kexec/arch/sh/kexec-netbsd-sh.c:38:int netbsd_sh_probe(const char
*buf, off_t UNUSED(len))
kexec/arch/sh/kexec-zImage-sh.c:54:int zImage_sh_probe(const char
*buf, off_t UNUSED(len))
I will see how to handle them.
Thanks,
Pingfan
> In file included from ../../kexec/arch/sh/kexec-zImage-sh.c:27:
> ../../kexec/arch/sh/kexec-sh.h:11:5: note: previous declaration of ‘zImage_sh_probe’ was here
> 11 | int zImage_sh_probe(const char *buf, off_t len, struct kexec_info *info);
> | ^~~~~~~~~~~~~~~
> ../../kexec/arch/sh/kexec-zImage-sh.c:29:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
> 29 | static const int probe_debug = 0;
> | ^~~~~~~~~~~
> make[1]: *** [Makefile:124: kexec/arch/sh/kexec-zImage-sh.o] Error 1
> make[1]: *** Waiting for unfinished jobs....
> ../../kexec/arch/sh/kexec-netbsd-sh.c:28:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
> 28 | static const int probe_debug = 0;
> | ^~~~~~~~~~~
>
> Link: https://github.com/horms/kexec-tools/actions/runs/5068250493/jobs/9100319093#step:5:215
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCHv2 1/6] kexec: Change the image probe's prototype
2023-05-25 3:32 ` Pingfan Liu
@ 2023-06-01 1:45 ` Pingfan Liu
2023-06-29 3:57 ` Pingfan Liu
0 siblings, 1 reply; 11+ messages in thread
From: Pingfan Liu @ 2023-06-01 1:45 UTC (permalink / raw)
To: Simon Horman; +Cc: kexec, horms, ardb, jeremy.linton
On Thu, May 25, 2023 at 11:32 AM Pingfan Liu <piliu@redhat.com> wrote:
>
> On Wed, May 24, 2023 at 7:53 PM Simon Horman <horms@kernel.org> wrote:
> >
> > On Tue, May 16, 2023 at 03:31:19PM +0800, Pingfan Liu wrote:
> > > As more complicated kernel format occurs such as zboot, where the
> > > compressed kernel is stored as a payload. The straight forward
> > > decompression can not meet the demand.
> > >
> > > A new image probe method is expected to read in the kernel file and decide
> > > how to unfold the content by itself.
> > >
> > > This patch aims to change the image probe's prototype from
> > > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
> > > to
> > > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size, struct kexec_info *info);
> > >
> > > Later, info can be used to return both the file descriptor and the
> > > parsed kernel buffer.
> > >
> > > In case your are curious, the remaing part of the log describes the
> > > process of the substitution of the new prototype, which can be divided
> > > into three groups.
> > >
> > > 1. change function pointer and its callsites:
> > > sed -i 's/(probe_t)(const char \*kernel_buf, off_t kernel_size);/(probe_t)(const char \*kernel, off_t kernel_size, struct kexec_info \*info);/g' kexec/kexec.h
> > > sed -i 's/\.probe(\([^,]*\), \([^)]*\))/\.probe(\1, \2, NULL)/g' kexec/kexec.c
> > >
> > > 2. change the function declaration and definition of each 'probe'
> > > instance by coccinelle because they may cross lines
> > >
> > > The cocci file looks like:
> > >
> > > @ rule1 @
> > > identifier fn =~ "_probe";
> > > identifier buf, size;
> > > typedef off_t;
> > > @@
> > >
> > > -int fn(const char *buf, off_t size)
> > > +int fn(const char *buf, off_t size, struct kexec_info *info)
> > > {
> > > ...
> > > }
> > >
> > > @ rule2 @
> > > identifier fn =~ "_probe";
> > > identifier buf, size;
> > > typedef off_t;
> > > @@
> > >
> > > +int fn(const char *buf, off_t size, struct kexec_info *info);
> > > -int fn(const char *buf, off_t size);
> > >
> > > Then running the command
> > > spatch --sp-file cocci/define.cocci --dir kexec --include-headers > ../define.patch
> > > git apply --directory=kexec ../define.patch
> > >
> > > 3. change the direct calls to the probe instances
> > >
> > > Originally I planned to achieve this by coccinelle, but failed similar
> > > to [1]. I have tried using "-I and --include" option for coccinelle, but it
> > > still did not work.
> > >
> > > Checking the direct callsite by "git grep "_probe(" | grep -v const"
> > > Fortunatelly, it turns out that only a few direct callsites exist, which
> > > lies in i386, and easy to be amended manually.
> > >
> > > Anyway, just FYI, the cocci file looks like:
> > > @ rule1 @
> > > identifier fn =~ "_probe";
> > > identifier buf, size;
> > > identifier info;
> > > typedef off_t;
> > > @@
> > >
> > > int fn(const char *buf, off_t size, struct kexec_info *info);
> > >
> > > /* change the direct callsite of any probe */
> > > @ rule2 @
> > > identifier rule1.fn;
> > > expression E1, E2;
> > > @@
> > >
> > > fn(E1, E2
> > > + ,NULL
> > > )
> > >
> > > Then running the command:
> > > spatch --sp-file cocci/direct.cocci --dir kexec --include-headers
> > >
> > > [1]: https://lore.kernel.org/all/alpine.DEB.2.22.394.2202280705080.3112@hadrien/T/
> > >
> > > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > > To: kexec@lists.infradead.org
> > > Cc: horms@verge.net.au
> > > Cc: ardb@kernel.org
> > > Cc: jeremy.linton@arm.com
> >
> > Unfortunately I am seeing a build failure on (at least) sh4 with this change:
> >
> > ../../kexec/arch/sh/kexec-zImage-sh.c:54:5: error: conflicting types for ‘zImage_sh_probe’
> > 54 | int zImage_sh_probe(const char *buf, off_t UNUSED(len))
> > | ^~~~~~~~~~~~~~~
>
> It may be because the macro UNUSED() is not tackled correctly by coccinelle.
>
> And there are several other places, which use UNUSED()
> git grep UNUSED | grep probe
> kexec/arch/arm/kexec-zImage-arm.c:138:int zImage_arm_probe(const char
> *UNUSED(buf), off_t UNUSED(len))
> kexec/arch/s390/kexec-image.c:219:image_s390_probe(const char
> *UNUSED(kernel_buf), off_t UNUSED(kernel_size))
> kexec/arch/sh/kexec-netbsd-sh.c:38:int netbsd_sh_probe(const char
> *buf, off_t UNUSED(len))
> kexec/arch/sh/kexec-zImage-sh.c:54:int zImage_sh_probe(const char
> *buf, off_t UNUSED(len))
>
> I will see how to handle them.
>
I'm having trouble figuring out how to make Coccinelle recognize
"UNUSED()" even though it can recognize "attribute(unused)". So I
fixed these issues manually.
I have do cross-compiling for "arm/arm64/m68k/mips/m68k/ppc64/s390/sh"
using the toolchains on https://toolchains.bootlin.com/
And I open a pull request [1] for [PATCHv3 0/6] arm64: zboot support.
The only change from v2->v3 is to fix the compiling issue in [1/6]
[1]: https://github.com/horms/kexec-tools/pull/4
Thanks,
Pingfan
>
> Thanks,
>
> Pingfan
> > In file included from ../../kexec/arch/sh/kexec-zImage-sh.c:27:
> > ../../kexec/arch/sh/kexec-sh.h:11:5: note: previous declaration of ‘zImage_sh_probe’ was here
> > 11 | int zImage_sh_probe(const char *buf, off_t len, struct kexec_info *info);
> > | ^~~~~~~~~~~~~~~
> > ../../kexec/arch/sh/kexec-zImage-sh.c:29:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
> > 29 | static const int probe_debug = 0;
> > | ^~~~~~~~~~~
> > make[1]: *** [Makefile:124: kexec/arch/sh/kexec-zImage-sh.o] Error 1
> > make[1]: *** Waiting for unfinished jobs....
> > ../../kexec/arch/sh/kexec-netbsd-sh.c:28:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
> > 28 | static const int probe_debug = 0;
> > | ^~~~~~~~~~~
> >
> > Link: https://github.com/horms/kexec-tools/actions/runs/5068250493/jobs/9100319093#step:5:215
> >
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCHv2 1/6] kexec: Change the image probe's prototype
2023-06-01 1:45 ` Pingfan Liu
@ 2023-06-29 3:57 ` Pingfan Liu
0 siblings, 0 replies; 11+ messages in thread
From: Pingfan Liu @ 2023-06-29 3:57 UTC (permalink / raw)
To: Simon Horman; +Cc: kexec, horms, ardb, jeremy.linton
I have another try, which drops the changes of the prototype of the
probe method. Instead, introducing the 'probe2' interface and
migrating all arm64 image probe methods to that interface.
I will do more test on the new series and sent it out soon
Thanks,
Pingfan
On Thu, Jun 1, 2023 at 9:45 AM Pingfan Liu <piliu@redhat.com> wrote:
>
> On Thu, May 25, 2023 at 11:32 AM Pingfan Liu <piliu@redhat.com> wrote:
> >
> > On Wed, May 24, 2023 at 7:53 PM Simon Horman <horms@kernel.org> wrote:
> > >
> > > On Tue, May 16, 2023 at 03:31:19PM +0800, Pingfan Liu wrote:
> > > > As more complicated kernel format occurs such as zboot, where the
> > > > compressed kernel is stored as a payload. The straight forward
> > > > decompression can not meet the demand.
> > > >
> > > > A new image probe method is expected to read in the kernel file and decide
> > > > how to unfold the content by itself.
> > > >
> > > > This patch aims to change the image probe's prototype from
> > > > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
> > > > to
> > > > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size, struct kexec_info *info);
> > > >
> > > > Later, info can be used to return both the file descriptor and the
> > > > parsed kernel buffer.
> > > >
> > > > In case your are curious, the remaing part of the log describes the
> > > > process of the substitution of the new prototype, which can be divided
> > > > into three groups.
> > > >
> > > > 1. change function pointer and its callsites:
> > > > sed -i 's/(probe_t)(const char \*kernel_buf, off_t kernel_size);/(probe_t)(const char \*kernel, off_t kernel_size, struct kexec_info \*info);/g' kexec/kexec.h
> > > > sed -i 's/\.probe(\([^,]*\), \([^)]*\))/\.probe(\1, \2, NULL)/g' kexec/kexec.c
> > > >
> > > > 2. change the function declaration and definition of each 'probe'
> > > > instance by coccinelle because they may cross lines
> > > >
> > > > The cocci file looks like:
> > > >
> > > > @ rule1 @
> > > > identifier fn =~ "_probe";
> > > > identifier buf, size;
> > > > typedef off_t;
> > > > @@
> > > >
> > > > -int fn(const char *buf, off_t size)
> > > > +int fn(const char *buf, off_t size, struct kexec_info *info)
> > > > {
> > > > ...
> > > > }
> > > >
> > > > @ rule2 @
> > > > identifier fn =~ "_probe";
> > > > identifier buf, size;
> > > > typedef off_t;
> > > > @@
> > > >
> > > > +int fn(const char *buf, off_t size, struct kexec_info *info);
> > > > -int fn(const char *buf, off_t size);
> > > >
> > > > Then running the command
> > > > spatch --sp-file cocci/define.cocci --dir kexec --include-headers > ../define.patch
> > > > git apply --directory=kexec ../define.patch
> > > >
> > > > 3. change the direct calls to the probe instances
> > > >
> > > > Originally I planned to achieve this by coccinelle, but failed similar
> > > > to [1]. I have tried using "-I and --include" option for coccinelle, but it
> > > > still did not work.
> > > >
> > > > Checking the direct callsite by "git grep "_probe(" | grep -v const"
> > > > Fortunatelly, it turns out that only a few direct callsites exist, which
> > > > lies in i386, and easy to be amended manually.
> > > >
> > > > Anyway, just FYI, the cocci file looks like:
> > > > @ rule1 @
> > > > identifier fn =~ "_probe";
> > > > identifier buf, size;
> > > > identifier info;
> > > > typedef off_t;
> > > > @@
> > > >
> > > > int fn(const char *buf, off_t size, struct kexec_info *info);
> > > >
> > > > /* change the direct callsite of any probe */
> > > > @ rule2 @
> > > > identifier rule1.fn;
> > > > expression E1, E2;
> > > > @@
> > > >
> > > > fn(E1, E2
> > > > + ,NULL
> > > > )
> > > >
> > > > Then running the command:
> > > > spatch --sp-file cocci/direct.cocci --dir kexec --include-headers
> > > >
> > > > [1]: https://lore.kernel.org/all/alpine.DEB.2.22.394.2202280705080.3112@hadrien/T/
> > > >
> > > > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > > > To: kexec@lists.infradead.org
> > > > Cc: horms@verge.net.au
> > > > Cc: ardb@kernel.org
> > > > Cc: jeremy.linton@arm.com
> > >
> > > Unfortunately I am seeing a build failure on (at least) sh4 with this change:
> > >
> > > ../../kexec/arch/sh/kexec-zImage-sh.c:54:5: error: conflicting types for ‘zImage_sh_probe’
> > > 54 | int zImage_sh_probe(const char *buf, off_t UNUSED(len))
> > > | ^~~~~~~~~~~~~~~
> >
> > It may be because the macro UNUSED() is not tackled correctly by coccinelle.
> >
> > And there are several other places, which use UNUSED()
> > git grep UNUSED | grep probe
> > kexec/arch/arm/kexec-zImage-arm.c:138:int zImage_arm_probe(const char
> > *UNUSED(buf), off_t UNUSED(len))
> > kexec/arch/s390/kexec-image.c:219:image_s390_probe(const char
> > *UNUSED(kernel_buf), off_t UNUSED(kernel_size))
> > kexec/arch/sh/kexec-netbsd-sh.c:38:int netbsd_sh_probe(const char
> > *buf, off_t UNUSED(len))
> > kexec/arch/sh/kexec-zImage-sh.c:54:int zImage_sh_probe(const char
> > *buf, off_t UNUSED(len))
> >
> > I will see how to handle them.
> >
>
> I'm having trouble figuring out how to make Coccinelle recognize
> "UNUSED()" even though it can recognize "attribute(unused)". So I
> fixed these issues manually.
>
> I have do cross-compiling for "arm/arm64/m68k/mips/m68k/ppc64/s390/sh"
> using the toolchains on https://toolchains.bootlin.com/
>
> And I open a pull request [1] for [PATCHv3 0/6] arm64: zboot support.
> The only change from v2->v3 is to fix the compiling issue in [1/6]
>
>
> [1]: https://github.com/horms/kexec-tools/pull/4
>
>
> Thanks,
>
> Pingfan
>
> >
> > Thanks,
> >
> > Pingfan
> > > In file included from ../../kexec/arch/sh/kexec-zImage-sh.c:27:
> > > ../../kexec/arch/sh/kexec-sh.h:11:5: note: previous declaration of ‘zImage_sh_probe’ was here
> > > 11 | int zImage_sh_probe(const char *buf, off_t len, struct kexec_info *info);
> > > | ^~~~~~~~~~~~~~~
> > > ../../kexec/arch/sh/kexec-zImage-sh.c:29:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
> > > 29 | static const int probe_debug = 0;
> > > | ^~~~~~~~~~~
> > > make[1]: *** [Makefile:124: kexec/arch/sh/kexec-zImage-sh.o] Error 1
> > > make[1]: *** Waiting for unfinished jobs....
> > > ../../kexec/arch/sh/kexec-netbsd-sh.c:28:18: warning: ‘probe_debug’ defined but not used [-Wunused-const-variable=]
> > > 28 | static const int probe_debug = 0;
> > > | ^~~~~~~~~~~
> > >
> > > Link: https://github.com/horms/kexec-tools/actions/runs/5068250493/jobs/9100319093#step:5:215
> > >
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-06-29 3:58 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-16 7:31 [PATCHv2 0/6] arm64: zboot support Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 1/6] kexec: Change the image probe's prototype Pingfan Liu
2023-05-24 11:52 ` Simon Horman
2023-05-25 3:32 ` Pingfan Liu
2023-06-01 1:45 ` Pingfan Liu
2023-06-29 3:57 ` Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 2/6] arm64: Fix some issues with zImage _probe() Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 3/6] arm64: Scatter the logic of reading of kernel file into each probe Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 4/6] kexec/zboot: Add arch independent zboot support Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 5/6] arm64: Add ZBOOT PE containing compressed image support Pingfan Liu
2023-05-16 7:31 ` [PATCHv2 6/6] arm64: Hook up the ZBOOT support as vmlinuz Pingfan Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox