* [PATCH 0/5] arm64: zboot support
@ 2023-05-05 2:54 Pingfan Liu
2023-05-05 2:54 ` [PATCH 1/5] kexec: Adding missing free for kernel_buf Pingfan Liu
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-05 2:54 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.
To: kexec@lists.infradead.org
Cc: horms@verge.net.au
Cc: ardb@kernel.org
Cc: jeremy.linton@arm.com
Pingfan Liu (5):
kexec: Adding missing free for kernel_buf
arm64/zImage: Remove unnecessary allocation for
kernel_uncompressed_buf
arm64: change the prototype of image probe function
arm64: Scatter the reading of kernel file into each probe
arm64: add support for zboot image
kexec/arch/arm/kexec-arm.h | 4 +-
kexec/arch/arm/kexec-uImage-arm.c | 2 +-
kexec/arch/arm64/Makefile | 3 +-
kexec/arch/arm64/kexec-arm64.c | 1 +
kexec/arch/arm64/kexec-arm64.h | 13 +-
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 | 23 +--
kexec/arch/arm64/kexec-zboot-arm64.c | 261 ++++++++++++++++++++++++++
kexec/arch/arm64/zboot.h | 26 +++
kexec/kexec.c | 48 +++--
kexec/kexec.h | 8 +
13 files changed, 377 insertions(+), 42 deletions(-)
create mode 100644 kexec/arch/arm64/kexec-zboot-arm64.c
create mode 100644 kexec/arch/arm64/zboot.h
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/5] kexec: Adding missing free for kernel_buf
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
@ 2023-05-05 2:54 ` Pingfan Liu
2023-05-05 15:32 ` Simon Horman
2023-05-05 2:54 ` [PATCH 2/5] arm64/zImage: Remove unnecessary allocation for kernel_uncompressed_buf Pingfan Liu
` (6 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Pingfan Liu @ 2023-05-05 2:54 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
slurp_decompress_file() allocates memory but nowhere to free it.
Adding that missing free.
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/kexec.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 36bb2ad..614cd1d 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1379,6 +1379,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
}
}
+ free(kernel_buf);
close(kernel_fd);
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] 13+ messages in thread
* [PATCH 2/5] arm64/zImage: Remove unnecessary allocation for kernel_uncompressed_buf
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
2023-05-05 2:54 ` [PATCH 1/5] kexec: Adding missing free for kernel_buf Pingfan Liu
@ 2023-05-05 2:54 ` Pingfan Liu
2023-05-05 2:54 ` [PATCH 3/5] arm64: change the prototype of image probe function Pingfan Liu
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-05 2:54 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
Since slurp_decompress_file() allocates the buffer to hold the content
read from the file, no need to allocate the buffer again.
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 | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/kexec/arch/arm64/kexec-zImage-arm64.c b/kexec/arch/arm64/kexec-zImage-arm64.c
index 6ee82ff..166d7ef 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -67,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,
@@ -128,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] 13+ messages in thread
* [PATCH 3/5] arm64: change the prototype of image probe function
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
2023-05-05 2:54 ` [PATCH 1/5] kexec: Adding missing free for kernel_buf Pingfan Liu
2023-05-05 2:54 ` [PATCH 2/5] arm64/zImage: Remove unnecessary allocation for kernel_uncompressed_buf Pingfan Liu
@ 2023-05-05 2:54 ` Pingfan Liu
2023-05-05 15:42 ` Simon Horman
2023-05-05 2:54 ` [PATCH 4/5] arm64: Scatter the logic of reading of kernel file into each probe Pingfan Liu
` (4 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Pingfan Liu @ 2023-05-05 2:54 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
Changing the aarch64 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 parsed kernel
buffer. The fd is passed to sys_kexec_file_load, and the parsed kernel
buffer is used by image's load function.
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 | 4 ++--
kexec/arch/arm/kexec-uImage-arm.c | 2 +-
kexec/arch/arm64/kexec-arm64.h | 8 ++++----
kexec/arch/arm64/kexec-elf-arm64.c | 2 +-
kexec/arch/arm64/kexec-image-arm64.c | 2 +-
kexec/arch/arm64/kexec-uImage-arm64.c | 2 +-
kexec/arch/arm64/kexec-zImage-arm64.c | 2 +-
kexec/kexec.c | 15 +++++++++++++--
kexec/kexec.h | 6 ++++++
9 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/kexec/arch/arm/kexec-arm.h b/kexec/arch/arm/kexec-arm.h
index a74cce2..18069f3 100644
--- a/kexec/arch/arm/kexec-arm.h
+++ b/kexec/arch/arm/kexec-arm.h
@@ -9,12 +9,12 @@
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..88bb508 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 *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..9238dd5 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -16,7 +16,7 @@
#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..84aca72 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -14,7 +14,7 @@
#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 166d7ef..7877741 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -40,7 +40,7 @@
* 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/kexec.c b/kexec/kexec.c
index 614cd1d..116fb4a 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -742,14 +742,25 @@ 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 */
+#ifndef __aarch64__
if (file_type[i].probe(kernel_buf, kernel_size) < 0)
guess_only = 1;
+#else
+ if (file_type[i].probe(kernel_buf, kernel_size, &info) < 0)
+ guess_only = 1;
+
+#endif
}
}
if (!type || guess_only) {
for (i = 0; i < file_types; i++) {
+#ifndef __aarch64__
if (file_type[i].probe(kernel_buf, kernel_size) == 0)
break;
+#else
+ if (file_type[i].probe(kernel_buf, kernel_size, &info) == 0)
+ break;
+#endif
}
if (i == file_types) {
fprintf(stderr, "Cannot determine the file type "
@@ -1304,12 +1315,12 @@ 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, &info)) >= 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, &info) >= 0)
break;
#else
if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 0d820ad..6e8430e 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -191,7 +191,13 @@ unsigned long locate_hole(struct kexec_info *info,
unsigned long hole_min, unsigned long hole_max,
int hole_end);
+#ifndef __aarch64__
typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
+#else
+typedef int (probe_t)(const char *kern_fname, off_t kernel_size,
+ struct kexec_info *info);
+#endif
+
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] 13+ messages in thread
* [PATCH 4/5] arm64: Scatter the logic of reading of kernel file into each probe
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
` (2 preceding siblings ...)
2023-05-05 2:54 ` [PATCH 3/5] arm64: change the prototype of image probe function Pingfan Liu
@ 2023-05-05 2:54 ` Pingfan Liu
2023-05-05 2:54 ` [PATCH 4/5] arm64: Scatter the " Pingfan Liu
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-05 2:54 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.
So reading in the kernel file in a probe method and decide how to unfold
the content by the method itself.
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-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 | 13 ++++-----
kexec/kexec.c | 42 ++++++++++++++++++---------
kexec/kexec.h | 2 ++
6 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
index 9238dd5..cedf3c6 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -16,11 +16,13 @@
#include "kexec-elf.h"
#include "kexec-syscall.h"
-int elf_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info)
+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) {
@@ -34,8 +36,11 @@ int elf_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info
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 84aca72..90cd40a 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -14,10 +14,12 @@
#include "kexec-syscall.h"
#include "arch/options.h"
-int image_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info)
+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;
@@ -29,6 +31,8 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_in
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 7877741..450a915 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -40,7 +40,7 @@
* fd : File descriptor of the temp file containing the decompressed
* Image.
*/
-int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info)
+int zImage_arm64_probe(const char *kernel, off_t kernel_size, struct kexec_info *info)
{
int ret = -1;
int fd = 0;
@@ -49,7 +49,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_i
char *kernel_uncompressed_buf = NULL;
const struct arm64_image_header *h;
- if (!is_zlib_file(kernel_buf, &kernel_size)) {
+ if (!is_zlib_file(kernel, &kernel_size)) {
dbgprintf("%s: Not an zImage file (Image.gz).\n", __func__);
return -1;
}
@@ -69,7 +69,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_i
/* slurp in the input kernel */
dbgprintf("%s: ", __func__);
- kernel_uncompressed_buf = slurp_decompress_file(kernel_buf,
+ kernel_uncompressed_buf = slurp_decompress_file(kernel,
&kernel_size);
/* check for correct header magic */
@@ -108,13 +108,12 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_i
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 116fb4a..dbd24aa 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -720,12 +720,13 @@ 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);
dbgprintf("kernel: %p kernel_size: %#llx\n",
kernel_buf, (unsigned long long)kernel_size);
-
+#endif
if (get_memory_ranges(&info.memory_range, &info.memory_ranges,
info.kexec_flags) < 0 || info.memory_ranges == 0) {
fprintf(stderr, "Could not get memory layout\n");
@@ -742,13 +743,17 @@ 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 */
+
#ifndef __aarch64__
if (file_type[i].probe(kernel_buf, kernel_size) < 0)
guess_only = 1;
#else
- if (file_type[i].probe(kernel_buf, kernel_size, &info) < 0)
+ if (file_type[i].probe(kernel_buf, kernel_size, &info) < 0) {
guess_only = 1;
-
+ } else {
+ if (info.kernel_buf != NULL)
+ kernel_buf = info.kernel_buf;
+ }
#endif
}
}
@@ -758,8 +763,11 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
if (file_type[i].probe(kernel_buf, kernel_size) == 0)
break;
#else
- if (file_type[i].probe(kernel_buf, kernel_size, &info) == 0)
+ if (file_type[i].probe(kernel, kernel_size, &info) >= 0) {
+ if (info.kernel_buf != NULL)
+ kernel_buf = info.kernel_buf;
break;
+ }
#endif
}
if (i == file_types) {
@@ -1289,6 +1297,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;
@@ -1301,6 +1311,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,
@@ -1310,21 +1321,24 @@ 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);
+#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, &info)) >= 0) {
- kernel_fd = ret;
- break;
- }
- } else
- if (file_type[i].probe(kernel_buf, kernel_size, &info) >= 0)
+#ifndef __aarch64__
+ if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
break;
#else
- if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+ if (file_type[i].probe(kernel, 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;
+ }
break;
+ }
#endif
}
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 6e8430e..3349d16 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] 13+ messages in thread
* [PATCH 4/5] arm64: Scatter the reading of kernel file into each probe
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
` (3 preceding siblings ...)
2023-05-05 2:54 ` [PATCH 4/5] arm64: Scatter the logic of reading of kernel file into each probe Pingfan Liu
@ 2023-05-05 2:54 ` Pingfan Liu
2023-05-05 22:38 ` [PATCH 0/5] arm64: zboot support Jeremy Linton
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-05 2:54 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.
So reading in the kernel file in a probe file and decide how to unfold
the content by the method itself.
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-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 | 13 ++++-----
kexec/kexec.c | 42 ++++++++++++++++++---------
kexec/kexec.h | 2 ++
6 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/kexec/arch/arm64/kexec-elf-arm64.c b/kexec/arch/arm64/kexec-elf-arm64.c
index 9238dd5..cedf3c6 100644
--- a/kexec/arch/arm64/kexec-elf-arm64.c
+++ b/kexec/arch/arm64/kexec-elf-arm64.c
@@ -16,11 +16,13 @@
#include "kexec-elf.h"
#include "kexec-syscall.h"
-int elf_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info)
+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) {
@@ -34,8 +36,11 @@ int elf_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info
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 84aca72..90cd40a 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -14,10 +14,12 @@
#include "kexec-syscall.h"
#include "arch/options.h"
-int image_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info)
+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;
@@ -29,6 +31,8 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_in
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 7877741..450a915 100644
--- a/kexec/arch/arm64/kexec-zImage-arm64.c
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -40,7 +40,7 @@
* fd : File descriptor of the temp file containing the decompressed
* Image.
*/
-int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info)
+int zImage_arm64_probe(const char *kernel, off_t kernel_size, struct kexec_info *info)
{
int ret = -1;
int fd = 0;
@@ -49,7 +49,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_i
char *kernel_uncompressed_buf = NULL;
const struct arm64_image_header *h;
- if (!is_zlib_file(kernel_buf, &kernel_size)) {
+ if (!is_zlib_file(kernel, &kernel_size)) {
dbgprintf("%s: Not an zImage file (Image.gz).\n", __func__);
return -1;
}
@@ -69,7 +69,7 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_i
/* slurp in the input kernel */
dbgprintf("%s: ", __func__);
- kernel_uncompressed_buf = slurp_decompress_file(kernel_buf,
+ kernel_uncompressed_buf = slurp_decompress_file(kernel,
&kernel_size);
/* check for correct header magic */
@@ -108,13 +108,12 @@ int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_i
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 116fb4a..dbd24aa 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -720,12 +720,13 @@ 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);
dbgprintf("kernel: %p kernel_size: %#llx\n",
kernel_buf, (unsigned long long)kernel_size);
-
+#endif
if (get_memory_ranges(&info.memory_range, &info.memory_ranges,
info.kexec_flags) < 0 || info.memory_ranges == 0) {
fprintf(stderr, "Could not get memory layout\n");
@@ -742,13 +743,17 @@ 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 */
+
#ifndef __aarch64__
if (file_type[i].probe(kernel_buf, kernel_size) < 0)
guess_only = 1;
#else
- if (file_type[i].probe(kernel_buf, kernel_size, &info) < 0)
+ if (file_type[i].probe(kernel_buf, kernel_size, &info) < 0) {
guess_only = 1;
-
+ } else {
+ if (info.kernel_buf != NULL)
+ kernel_buf = info.kernel_buf;
+ }
#endif
}
}
@@ -758,8 +763,11 @@ static int my_load(const char *type, int fileind, int argc, char **argv,
if (file_type[i].probe(kernel_buf, kernel_size) == 0)
break;
#else
- if (file_type[i].probe(kernel_buf, kernel_size, &info) == 0)
+ if (file_type[i].probe(kernel, kernel_size, &info) >= 0) {
+ if (info.kernel_buf != NULL)
+ kernel_buf = info.kernel_buf;
break;
+ }
#endif
}
if (i == file_types) {
@@ -1289,6 +1297,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;
@@ -1301,6 +1311,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,
@@ -1310,21 +1321,24 @@ 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);
+#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, &info)) >= 0) {
- kernel_fd = ret;
- break;
- }
- } else
- if (file_type[i].probe(kernel_buf, kernel_size, &info) >= 0)
+#ifndef __aarch64__
+ if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
break;
#else
- if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+ if (file_type[i].probe(kernel, 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;
+ }
break;
+ }
#endif
}
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 6e8430e..3349d16 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] 13+ messages in thread
* Re: [PATCH 1/5] kexec: Adding missing free for kernel_buf
2023-05-05 2:54 ` [PATCH 1/5] kexec: Adding missing free for kernel_buf Pingfan Liu
@ 2023-05-05 15:32 ` Simon Horman
0 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2023-05-05 15:32 UTC (permalink / raw)
To: Pingfan Liu; +Cc: kexec, ardb, jeremy.linton
On Fri, May 05, 2023 at 10:54:33AM +0800, Pingfan Liu wrote:
> slurp_decompress_file() allocates memory but nowhere to free it.
> Adding that missing free.
Hi Pingfan,
There seem to be:
a) other places where slurp_decompress_file() is called and;
b) other places where do_kexec_file_load() returns.
I wonder if a more comprehensive fix appropriate.
>
> 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/kexec.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/kexec/kexec.c b/kexec/kexec.c
> index 36bb2ad..614cd1d 100644
> --- a/kexec/kexec.c
> +++ b/kexec/kexec.c
> @@ -1379,6 +1379,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
> }
> }
>
> + free(kernel_buf);
> close(kernel_fd);
> return ret;
> }
> --
> 2.31.1
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/5] arm64: change the prototype of image probe function
2023-05-05 2:54 ` [PATCH 3/5] arm64: change the prototype of image probe function Pingfan Liu
@ 2023-05-05 15:42 ` Simon Horman
2023-05-06 3:14 ` Pingfan Liu
0 siblings, 1 reply; 13+ messages in thread
From: Simon Horman @ 2023-05-05 15:42 UTC (permalink / raw)
To: Pingfan Liu; +Cc: kexec, horms, ardb, jeremy.linton
On Fri, May 05, 2023 at 10:54:35AM +0800, Pingfan Liu wrote:
> Changing the aarch64 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 parsed kernel
> buffer. The fd is passed to sys_kexec_file_load, and the parsed kernel
> buffer is used by image's load function.
>
> Signed-off-by: Pingfan Liu <piliu@redhat.com>
Hi Pingfan,
I am seeing a build failure on ARM (32bit).
138 | int zImage_arm_probe(const char *UNUSED(buf), off_t UNUSED(len))
| ^~~~~~~~~~~~~~~~
In file included from ../../kexec/arch/arm/kexec-zImage-arm.c:21:
../../kexec/arch/arm/kexec-arm.h:12:5: note: previous declaration of ‘zImage_arm_probe’ was here
12 | int zImage_arm_probe(const char *buf, off_t len, struct kexec_info *info);
| ^~~~~~~~~~~~~~~~
make[1]: *** [Makefile:124: kexec/arch/arm/kexec-zImage-arm.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: Leaving directory '/home/runner/work/kexec-tools/kexec-tools/kexec-tools-2.0.26.git/_build/sub'
make: *** [Makefile:276: distcheck] Error 2
Error: Process completed with exit code 2.
Link: https://github.com/horms/kexec-tools/actions/runs/4895124719/jobs/8740272103
...
> diff --git a/kexec/kexec.h b/kexec/kexec.h
> index 0d820ad..6e8430e 100644
> --- a/kexec/kexec.h
> +++ b/kexec/kexec.h
> @@ -191,7 +191,13 @@ unsigned long locate_hole(struct kexec_info *info,
> unsigned long hole_min, unsigned long hole_max,
> int hole_end);
>
> +#ifndef __aarch64__
> typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
> +#else
> +typedef int (probe_t)(const char *kern_fname, off_t kernel_size,
> + struct kexec_info *info);
> +#endif
> +
This seems kind of unfortunate.
Could we update the prototype for all architectures?
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/5] arm64: zboot support
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
` (4 preceding siblings ...)
2023-05-05 2:54 ` [PATCH 4/5] arm64: Scatter the " Pingfan Liu
@ 2023-05-05 22:38 ` Jeremy Linton
2023-05-06 3:12 ` Pingfan Liu
2023-05-06 3:05 ` [PATCH 5/5] arm64: add support for zboot image Pingfan Liu
2023-05-12 3:10 ` [PATCH 0/5] arm64: zboot support Pingfan Liu
7 siblings, 1 reply; 13+ messages in thread
From: Jeremy Linton @ 2023-05-05 22:38 UTC (permalink / raw)
To: Pingfan Liu, kexec; +Cc: horms, ardb
On 5/4/23 21:54, Pingfan Liu wrote:
> 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.
>
Well this is unfortunate. I pinged you a few days back but I guess it
must have gotten lost in the noise.
I'm ok with dropping my set, but I don't see your 5/5, and it doesn't
show up in the archive either. Which presumably is the core ZBOOT
functionality. From what I can tell without that, this set then is all
just cleanup. So did you do that on purpose, if so maybe its best then
to just rebase on top of my set?
Given I'm not a regular contributor here I'm not sure my opinion matters
much, but one of the things that bothered me when I was yak shaving my
set, were the #ifdef aarch64 bits in the common code. I considered
attempting to remove it but that was a bit more involved than I wanted
to get. But, as Ard correctly points out, the zboot is being used by
more than aarch64 at this point. So that is also a argument for assuring
whatever the probe()/etc interface is, that its not #ifdefed.
>
> To: kexec@lists.infradead.org
> Cc: horms@verge.net.au
> Cc: ardb@kernel.org
> Cc: jeremy.linton@arm.com
>
> Pingfan Liu (5):
> kexec: Adding missing free for kernel_buf
> arm64/zImage: Remove unnecessary allocation for
> kernel_uncompressed_buf
> arm64: change the prototype of image probe function
> arm64: Scatter the reading of kernel file into each probe
> arm64: add support for zboot image
>
> kexec/arch/arm/kexec-arm.h | 4 +-
> kexec/arch/arm/kexec-uImage-arm.c | 2 +-
> kexec/arch/arm64/Makefile | 3 +-
> kexec/arch/arm64/kexec-arm64.c | 1 +
> kexec/arch/arm64/kexec-arm64.h | 13 +-
> 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 | 23 +--
> kexec/arch/arm64/kexec-zboot-arm64.c | 261 ++++++++++++++++++++++++++
> kexec/arch/arm64/zboot.h | 26 +++
> kexec/kexec.c | 48 +++--
> kexec/kexec.h | 8 +
> 13 files changed, 377 insertions(+), 42 deletions(-)
> create mode 100644 kexec/arch/arm64/kexec-zboot-arm64.c
> create mode 100644 kexec/arch/arm64/zboot.h
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/5] arm64: add support for zboot image
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
` (5 preceding siblings ...)
2023-05-05 22:38 ` [PATCH 0/5] arm64: zboot support Jeremy Linton
@ 2023-05-06 3:05 ` Pingfan Liu
2023-05-12 3:10 ` [PATCH 0/5] arm64: zboot support Pingfan Liu
7 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-06 3:05 UTC (permalink / raw)
To: kexec; +Cc: Pingfan Liu, horms, ardb, jeremy.linton
zboot image consists of zboot_header and Image.gz. And the compressed
payload should be located and parsed with extra effort. Most of
important, the kernel can only work with Image, so the final fd should
point to a temporary file, which contains Image.
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 | 5 +
kexec/arch/arm64/kexec-zboot-arm64.c | 261 +++++++++++++++++++++++++++
kexec/arch/arm64/zboot.h | 26 +++
5 files changed, 295 insertions(+), 1 deletion(-)
create mode 100644 kexec/arch/arm64/kexec-zboot-arm64.c
create mode 100644 kexec/arch/arm64/zboot.h
diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index d27c8ee..7826a36 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-zboot-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..88b5f57 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -72,6 +72,7 @@ const struct arch_map_entry arches[] = {
struct file_type file_type[] = {
{"vmlinux", elf_arm64_probe, elf_arm64_load, elf_arm64_usage},
+ {"zboot", zboot_arm64_probe, zboot_arm64_load, zboot_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},
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 88bb508..98e1be9 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -50,6 +50,11 @@ int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
void zImage_arm64_usage(void);
+int zboot_arm64_probe(const char *kernel_buf, off_t kernel_size, struct kexec_info *info);
+int zboot_arm64_load(int argc, char **argv, const char *kernel_buf,
+ off_t kernel_size, struct kexec_info *info);
+void zboot_arm64_usage(void);
+
extern off_t initrd_base;
extern off_t initrd_size;
diff --git a/kexec/arch/arm64/kexec-zboot-arm64.c b/kexec/arch/arm64/kexec-zboot-arm64.c
new file mode 100644
index 0000000..b6c4fe3
--- /dev/null
+++ b/kexec/arch/arm64/kexec-zboot-arm64.c
@@ -0,0 +1,261 @@
+/*
+ * ARM64 kexec zboot Image support.
+ *
+ * Based on kexec-zImage-arm64.c
+ */
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "crashdump-arm64.h"
+#include "image-header.h"
+#include "kexec.h"
+#include "kexec-arm64.h"
+#include "kexec-syscall.h"
+#include "kexec-zlib.h"
+#include "zboot.h"
+#include "arch/options.h"
+
+#define MZ_MAGIC 0x5a4d /* "MZ" */
+#define FILENAME_IMAGE_GZ "/tmp/zboot_Image_gzXXXXXX"
+#define FILENAME_IMAGE "/tmp/zboot_ImageXXXXXX"
+
+
+static struct zboot_image_header *check_zboot_header(char *buf, off_t size)
+{
+
+ uint32_t magic = MZ_MAGIC;
+ struct zboot_image_header *zh =
+ (struct zboot_image_header *)(buf);
+
+ if (!zh || (size < sizeof(*zh)))
+ return NULL;
+
+ if (memcmp(&zh->magic, &magic, sizeof(zh->magic))) {
+ dbgprintf("%s: Not an zboot Image\n", __func__);
+ return NULL;
+ }
+ if (strncmp(zh->zimg, "zimg", 4)) {
+ dbgprintf("%s: Not an zboot Image\n", __func__);
+ return NULL;
+ }
+ return zh;
+}
+
+/* Returns:
+ * -1 : in case of error/invalid format.
+ */
+int zboot_arm64_probe(const char *kern_fname, off_t kernel_size, struct kexec_info *info)
+{
+ int ret = 0;
+ int fd = 0, gz_fd = 0;
+ int kernel_fd = 0;
+ char *fname = NULL, *gz_fname;
+ char *kernel_buf, *uncompressed_buf = NULL;
+ char *compressed_kernel;
+ const struct arm64_image_header *h;
+ struct zboot_image_header *zh;
+
+ kernel_buf = slurp_file(kern_fname, &kernel_size);
+ zh = check_zboot_header(kernel_buf, kernel_size);
+ if (!zh)
+ return -1;
+
+ if (!(gz_fname = strdup(FILENAME_IMAGE_GZ))) {
+ dbgprintf("%s: Can't duplicate strings %s\n", __func__,
+ gz_fname);
+ return -1;
+ }
+
+ if ((gz_fd = mkstemp(gz_fname)) < 0) {
+ dbgprintf("%s: Can't open file %s\n", __func__,
+ gz_fname);
+ ret = -1;
+ goto fail_mkstemp;
+ }
+
+ /* locate the Image.gz and copy it to a temp file */
+
+ /*
+ * zboot has SizeOfCode, SizeOfImage, SizeOfHeaders appended at the end. And
+ * each occupies 4 bytes.
+ */
+ compressed_kernel = (char *)kernel_buf + zh->gzdata_offset;
+ if (write(gz_fd, compressed_kernel, zh->gzdata_size) != zh->gzdata_size) {
+ dbgprintf("%s: Can't write the Image.gz %s\n",
+ __func__, gz_fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+ free(kernel_buf);
+ close(gz_fd);
+
+ /* slurp in the input kernel */
+ dbgprintf("%s: ", __func__);
+ /*
+ * If the kernel enables integrity check, the innermost Image should
+ * be signed.
+ */
+ uncompressed_buf = slurp_decompress_file(gz_fname,
+ &kernel_size);
+
+
+ /* double checking against internal Image */
+
+ if (kernel_size < sizeof(struct arm64_image_header)) {
+ dbgprintf("%s: No arm64 image header.\n", __func__);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ h = (const struct arm64_image_header *)(uncompressed_buf);
+
+ if (!arm64_header_check_magic(h)) {
+ dbgprintf("%s: Bad arm64 image header.\n", __func__);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ if (!(fname = strdup(FILENAME_IMAGE))) {
+ dbgprintf("%s: Can't duplicate strings %s\n", __func__,
+ fname);
+ 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, uncompressed_buf, kernel_size) != kernel_size) {
+ dbgprintf("%s: Can't write the uncompressed file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ close(fd);
+
+ /* Open the tmp file again, this time in O_RDONLY mode, as
+ * 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) {
+ dbgprintf("%s: Failed to open file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+ info->kernel_fd = kernel_fd;
+ info->kernel_buf = uncompressed_buf;
+
+ unlink(gz_fname);
+ free(gz_fname);
+ unlink(fname);
+ free(fname);
+
+ return ret;
+
+fail_bad_header:
+ free(uncompressed_buf);
+
+ if (fd >= 0)
+ close(fd);
+
+ unlink(fname);
+ unlink(gz_fname);
+
+fail_mkstemp:
+ free(fname);
+ free(gz_fname);
+
+ return ret;
+}
+
+int zboot_arm64_load(int argc, char **argv, const char *kernel_buf,
+ off_t kernel_size, struct kexec_info *info)
+{
+ const struct arm64_image_header *header;
+ unsigned long kernel_segment;
+ int result;
+
+ if (info->file_mode) {
+ if (arm64_opts.initrd) {
+ info->initrd_fd = open(arm64_opts.initrd, O_RDONLY);
+ if (info->initrd_fd == -1) {
+ fprintf(stderr,
+ "Could not open initrd file %s:%s\n",
+ arm64_opts.initrd, strerror(errno));
+ result = EFAILED;
+ goto exit;
+ }
+ }
+
+ if (arm64_opts.command_line) {
+ info->command_line = (char *)arm64_opts.command_line;
+ info->command_line_len =
+ strlen(arm64_opts.command_line) + 1;
+ }
+
+ return 0;
+ }
+
+ header = (const struct arm64_image_header *)(kernel_buf);
+
+ if (arm64_process_image_header(header))
+ return EFAILED;
+
+ kernel_segment = arm64_locate_kernel_segment(info);
+
+ if (kernel_segment == ULONG_MAX) {
+ dbgprintf("%s: Kernel segment is not allocated\n", __func__);
+ result = EFAILED;
+ goto exit;
+ }
+
+ dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment);
+ dbgprintf("%s: text_offset: %016lx\n", __func__,
+ arm64_mem.text_offset);
+ dbgprintf("%s: image_size: %016lx\n", __func__,
+ arm64_mem.image_size);
+ dbgprintf("%s: phys_offset: %016lx\n", __func__,
+ arm64_mem.phys_offset);
+ dbgprintf("%s: vp_offset: %016lx\n", __func__,
+ arm64_mem.vp_offset);
+ dbgprintf("%s: PE format: %s\n", __func__,
+ (arm64_header_check_pe_sig(header) ? "yes" : "no"));
+
+ /* create and initialize elf core header segment */
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ result = load_crashdump_segments(info);
+ if (result) {
+ dbgprintf("%s: Creating eflcorehdr failed.\n",
+ __func__);
+ goto exit;
+ }
+ }
+
+ /* load the kernel */
+ add_segment_phys_virt(info, kernel_buf, kernel_size,
+ kernel_segment + arm64_mem.text_offset,
+ arm64_mem.image_size, 0);
+
+ /* load additional data */
+ result = arm64_load_other_segments(info, kernel_segment
+ + arm64_mem.text_offset);
+
+exit:
+ if (result)
+ fprintf(stderr, "kexec: load failed.\n");
+ return result;
+}
+
+void zboot_arm64_usage(void)
+{
+ printf("An ARM64 zboot Image, compressed, big or little endian.\n");
+}
diff --git a/kexec/arch/arm64/zboot.h b/kexec/arch/arm64/zboot.h
new file mode 100644
index 0000000..fa97aa3
--- /dev/null
+++ b/kexec/arch/arm64/zboot.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ZBOOT_H
+#define ZBOOT_H
+
+struct zboot_image_header {
+ union {
+ struct {
+ uint32_t magic;
+ /* image type, .ascii "zimg" */
+ char zimg[4];
+ int32_t gzdata_offset;
+ int32_t gzdata_size;
+ int32_t reserved[2];
+ /* compression type, .asciz */
+ char comp_type[];
+ };
+ struct {
+ char pad[56];
+ };
+ };
+ /* 0x818223cd */
+ uint32_t linux_pe_magic;
+ int32_t pe_header_offset;
+} __packed;
+
+#endif
--
2.31.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 0/5] arm64: zboot support
2023-05-05 22:38 ` [PATCH 0/5] arm64: zboot support Jeremy Linton
@ 2023-05-06 3:12 ` Pingfan Liu
0 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-06 3:12 UTC (permalink / raw)
To: Jeremy Linton; +Cc: kexec, horms, ardb
On Sat, May 6, 2023 at 6:38 AM Jeremy Linton <jeremy.linton@arm.com> wrote:
>
> On 5/4/23 21:54, Pingfan Liu wrote:
> > 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.
> >
>
> Well this is unfortunate. I pinged you a few days back but I guess it
> must have gotten lost in the noise.
>
Sorry for that.
> I'm ok with dropping my set, but I don't see your 5/5, and it doesn't
> show up in the archive either. Which presumably is the core ZBOOT
> functionality. From what I can tell without that, this set then is all
> just cleanup. So did you do that on purpose, if so maybe its best then
> to just rebase on top of my set?
>
I forgot to add the CC in that patch, and it turns out to be sent to
myself only. I have re-sent it.
I am happy to rebase on your set with some adaptation to the new probe
interface.
>
> Given I'm not a regular contributor here I'm not sure my opinion matters
> much, but one of the things that bothered me when I was yak shaving my
> set, were the #ifdef aarch64 bits in the common code. I considered
> attempting to remove it but that was a bit more involved than I wanted
> to get. But, as Ard correctly points out, the zboot is being used by
> more than aarch64 at this point. So that is also a argument for assuring
> whatever the probe()/etc interface is, that its not #ifdefed.
>
Yes, it makes code look not neat. I have tried to tackle it with sed,
but failed. I will try to achieve it with coccinelle.
Thanks,
Pingfan
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/5] arm64: change the prototype of image probe function
2023-05-05 15:42 ` Simon Horman
@ 2023-05-06 3:14 ` Pingfan Liu
0 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-06 3:14 UTC (permalink / raw)
To: Simon Horman; +Cc: kexec, horms, ardb, jeremy.linton
On Fri, May 5, 2023 at 11:42 PM Simon Horman <horms@kernel.org> wrote:
>
> On Fri, May 05, 2023 at 10:54:35AM +0800, Pingfan Liu wrote:
> > Changing the aarch64 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 parsed kernel
> > buffer. The fd is passed to sys_kexec_file_load, and the parsed kernel
> > buffer is used by image's load function.
> >
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
>
> Hi Pingfan,
>
> I am seeing a build failure on ARM (32bit).
>
> 138 | int zImage_arm_probe(const char *UNUSED(buf), off_t UNUSED(len))
> | ^~~~~~~~~~~~~~~~
> In file included from ../../kexec/arch/arm/kexec-zImage-arm.c:21:
> ../../kexec/arch/arm/kexec-arm.h:12:5: note: previous declaration of ‘zImage_arm_probe’ was here
> 12 | int zImage_arm_probe(const char *buf, off_t len, struct kexec_info *info);
> | ^~~~~~~~~~~~~~~~
> make[1]: *** [Makefile:124: kexec/arch/arm/kexec-zImage-arm.o] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make[1]: Leaving directory '/home/runner/work/kexec-tools/kexec-tools/kexec-tools-2.0.26.git/_build/sub'
> make: *** [Makefile:276: distcheck] Error 2
> Error: Process completed with exit code 2.
>
Oops. I just tested on x86_64 and aarch64, and did not detect this bug.
> Link: https://github.com/horms/kexec-tools/actions/runs/4895124719/jobs/8740272103
>
> ...
>
> > diff --git a/kexec/kexec.h b/kexec/kexec.h
> > index 0d820ad..6e8430e 100644
> > --- a/kexec/kexec.h
> > +++ b/kexec/kexec.h
> > @@ -191,7 +191,13 @@ unsigned long locate_hole(struct kexec_info *info,
> > unsigned long hole_min, unsigned long hole_max,
> > int hole_end);
> >
> > +#ifndef __aarch64__
> > typedef int (probe_t)(const char *kernel_buf, off_t kernel_size);
> > +#else
> > +typedef int (probe_t)(const char *kern_fname, off_t kernel_size,
> > + struct kexec_info *info);
> > +#endif
> > +
>
> This seems kind of unfortunate.
> Could we update the prototype for all architectures?
>
I will have a try with coccinelle.
Thanks for your help.
Regards,
Pingfan
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/5] arm64: zboot support
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
` (6 preceding siblings ...)
2023-05-06 3:05 ` [PATCH 5/5] arm64: add support for zboot image Pingfan Liu
@ 2023-05-12 3:10 ` Pingfan Liu
7 siblings, 0 replies; 13+ messages in thread
From: Pingfan Liu @ 2023-05-12 3:10 UTC (permalink / raw)
To: kexec; +Cc: horms, ardb, jeremy.linton
I have rebased Jeremy's V2 (which is off-list) onto my new code.
The whole series since commit a8de94e:
LoongArch: kdump: Set up kernel image segment
is available in the Git repository
at https://github.com/pfliu/kexec-tools/tree/zboot
up to the head
I have compiled it on x86_64 and aarch64, and successfully booted the
zboot image on aarch64
@Simon, is there any instruction to do the cross-building for
kexec-tools, so I can verify the pattern substitution works well on
other arches. I think I can post it to the list with a cover-letter
after verification.
Thanks,
Pingfan
On Fri, May 5, 2023 at 10:54 AM Pingfan Liu <piliu@redhat.com> wrote:
>
> 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.
>
>
> To: kexec@lists.infradead.org
> Cc: horms@verge.net.au
> Cc: ardb@kernel.org
> Cc: jeremy.linton@arm.com
>
> Pingfan Liu (5):
> kexec: Adding missing free for kernel_buf
> arm64/zImage: Remove unnecessary allocation for
> kernel_uncompressed_buf
> arm64: change the prototype of image probe function
> arm64: Scatter the reading of kernel file into each probe
> arm64: add support for zboot image
>
> kexec/arch/arm/kexec-arm.h | 4 +-
> kexec/arch/arm/kexec-uImage-arm.c | 2 +-
> kexec/arch/arm64/Makefile | 3 +-
> kexec/arch/arm64/kexec-arm64.c | 1 +
> kexec/arch/arm64/kexec-arm64.h | 13 +-
> 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 | 23 +--
> kexec/arch/arm64/kexec-zboot-arm64.c | 261 ++++++++++++++++++++++++++
> kexec/arch/arm64/zboot.h | 26 +++
> kexec/kexec.c | 48 +++--
> kexec/kexec.h | 8 +
> 13 files changed, 377 insertions(+), 42 deletions(-)
> create mode 100644 kexec/arch/arm64/kexec-zboot-arm64.c
> create mode 100644 kexec/arch/arm64/zboot.h
>
> --
> 2.31.1
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-05-12 3:10 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-05 2:54 [PATCH 0/5] arm64: zboot support Pingfan Liu
2023-05-05 2:54 ` [PATCH 1/5] kexec: Adding missing free for kernel_buf Pingfan Liu
2023-05-05 15:32 ` Simon Horman
2023-05-05 2:54 ` [PATCH 2/5] arm64/zImage: Remove unnecessary allocation for kernel_uncompressed_buf Pingfan Liu
2023-05-05 2:54 ` [PATCH 3/5] arm64: change the prototype of image probe function Pingfan Liu
2023-05-05 15:42 ` Simon Horman
2023-05-06 3:14 ` Pingfan Liu
2023-05-05 2:54 ` [PATCH 4/5] arm64: Scatter the logic of reading of kernel file into each probe Pingfan Liu
2023-05-05 2:54 ` [PATCH 4/5] arm64: Scatter the " Pingfan Liu
2023-05-05 22:38 ` [PATCH 0/5] arm64: zboot support Jeremy Linton
2023-05-06 3:12 ` Pingfan Liu
2023-05-06 3:05 ` [PATCH 5/5] arm64: add support for zboot image Pingfan Liu
2023-05-12 3:10 ` [PATCH 0/5] arm64: zboot support Pingfan Liu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox