[PATCHv4 4/8] arm64: Transfer from probe() to probe2()
Pingfan Liu
piliu at redhat.com
Tue Jul 4 19:47:21 PDT 2023
Scatter the logic of reading of kernel file into each probe
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, introduce a method probe2, which reads in the kernel file and
decides how to unfold the content by itself.
At present, only aarch64 supports zboot image and implements probe2().
Signed-off-by: Pingfan Liu <piliu at redhat.com>
To: kexec at lists.infradead.org
Cc: horms at verge.net.au
Cc: ardb at kernel.org
Cc: jeremy.linton at arm.com
---
kexec/arch/arm64/kexec-arm64.c | 9 +++++----
kexec/arch/arm64/kexec-arm64.h | 8 ++++----
kexec/arch/arm64/kexec-elf-arm64.c | 7 +++++--
kexec/arch/arm64/kexec-image-arm64.c | 15 +++++++++-----
kexec/arch/arm64/kexec-uImage-arm64.c | 15 ++++++++++----
kexec/arch/arm64/kexec-zImage-arm64.c | 28 +++++++++------------------
6 files changed, 44 insertions(+), 38 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index ec6df4b..f391f77 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -70,11 +70,12 @@ const struct arch_map_entry arches[] = {
{ NULL, 0 },
};
+/* On arm64, probe2 is used, probe is abandoned */
struct file_type file_type[] = {
- {"vmlinux", elf_arm64_probe, elf_arm64_load, elf_arm64_usage},
- {"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},
+ {"vmlinux", NULL, elf_arm64_load, elf_arm64_usage, elf_arm64_probe},
+ {"Image", NULL, image_arm64_load, image_arm64_usage, image_arm64_probe},
+ {"uImage", NULL, uImage_arm64_load, uImage_arm64_usage, uImage_arm64_probe},
+ {"zImage", NULL, zImage_arm64_load, zImage_arm64_usage, zImage_arm64_probe},
};
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 5eb9fc0..eeb35ae 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -29,22 +29,22 @@
#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, struct parsed_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, struct parsed_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 *kern_fname, struct parsed_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 *kern_fname, struct parsed_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..4e8f8d9 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -16,12 +16,13 @@
#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, struct parsed_info *info)
{
struct mem_ehdr ehdr;
int result;
- result = build_elf_exec_info(kernel_buf, kernel_size, &ehdr, 0);
+ info->kernel_buf = slurp_file(kern_fname, &info->kernel_size);
+ result = build_elf_exec_info(info->kernel_buf, info->kernel_size, &ehdr, 0);
if (result < 0) {
dbgprintf("%s: Not an ELF executable.\n", __func__);
@@ -34,8 +35,10 @@ int elf_arm64_probe(const char *kernel_buf, off_t kernel_size)
goto on_exit;
}
+ info->fd = open(kern_fname, O_RDONLY);
result = 0;
on_exit:
+ free(info->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 aa8f2e2..e2e5c20 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -14,23 +14,28 @@
#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, struct parsed_info *info)
{
const struct arm64_image_header *h;
- if (kernel_size < sizeof(struct arm64_image_header)) {
+ info->kernel_buf = slurp_file(kern_fname, &info->kernel_size);
+ if (info->kernel_size < sizeof(struct arm64_image_header)) {
dbgprintf("%s: No arm64 image header.\n", __func__);
- return -1;
+ goto err;
}
- h = (const struct arm64_image_header *)(kernel_buf);
+ h = (const struct arm64_image_header *)(info->kernel_buf);
if (!arm64_header_check_magic(h)) {
dbgprintf("%s: Bad arm64 image header.\n", __func__);
- return -1;
+ goto err;
}
+ info->fd = open(kern_fname, O_RDONLY);
return 0;
+error:
+ free(info->kernel_buf);
+ return -1;
}
int image_arm64_load(int argc, char **argv, const char *kernel_buf,
diff --git a/kexec/arch/arm64/kexec-uImage-arm64.c b/kexec/arch/arm64/kexec-uImage-arm64.c
index c466913..2bd4607 100644
--- a/kexec/arch/arm64/kexec-uImage-arm64.c
+++ b/kexec/arch/arm64/kexec-uImage-arm64.c
@@ -3,26 +3,33 @@
*/
#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)
+int uImage_arm64_probe(const char *kern_fname, struct parsed_info *info)
{
int ret;
- ret = uImage_probe_kernel(buf, len, IH_ARCH_ARM64);
+ info->kernel_buf = slurp_file(kern_fname, &info->kernel_size);
+ ret = uImage_probe_kernel(info->kernel_buf, info->kernel_size, IH_ARCH_ARM64);
/* 0 - valid uImage.
* -1 - uImage is corrupted.
* 1 - image is not a uImage.
*/
- if (!ret)
+ if (!ret) {
+ info->fd = open(kern_fname, O_RDONLY);
return 0;
- else
+ }
+ else {
+ free(info->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 3eb1ad8..4e488a5 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -37,23 +37,15 @@
/* 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, struct parsed_info *info)
{
int ret = -1;
int fd = 0;
- int kernel_fd = 0;
char *fname = NULL;
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;
@@ -68,11 +60,11 @@ 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_size);
+ kernel_uncompressed_buf = slurp_decompress_file(kern_fname,
+ &info->kernel_size);
/* check for correct header magic */
- if (kernel_size < sizeof(struct arm64_image_header)) {
+ if (info->kernel_size < sizeof(struct arm64_image_header)) {
dbgprintf("%s: No arm64 image header.\n", __func__);
ret = -1;
goto fail_bad_header;
@@ -87,7 +79,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size)
}
if (write(fd, kernel_uncompressed_buf,
- kernel_size) != kernel_size) {
+ info->kernel_size) != info->kernel_size) {
dbgprintf("%s: Can't write the uncompressed file %s\n",
__func__, fname);
ret = -1;
@@ -100,20 +92,18 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size)
* opening the file in O_RDWR and calling kexec_file_load()
* causes the kernel to return -ETXTBSY
*/
- kernel_fd = open(fname, O_RDONLY);
- if (kernel_fd == -1) {
+ info->fd = open(fname, O_RDONLY);
+ if (info->fd == -1) {
dbgprintf("%s: Failed to open file %s\n",
__func__, fname);
ret = -1;
goto fail_bad_header;
}
-
+ 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);
--
2.31.1
More information about the kexec
mailing list