util/cbfstool/cbfs-payload-linux: Add error handling

This adds some error handling to the code that adds the input segments
(e.g. kernel, cmdline, initrd...) to the output file.

Currently the compress function can fail and coreboot will still
build "successfully" leaving whoever build coreboot puzzled.

Change-Id: Ie36ad469c73cb3ff9360acc9bbe66c245e8b4a1e
Signed-off-by: Maximilian Brune <maximilian.brune@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83617
Reviewed-by: Elyes Haouas <ehaouas@noos.fr>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Maximilian Brune 2024-07-23 12:32:09 +02:00 committed by Elyes Haouas
parent 70d0fda89d
commit 888166e6ea

View File

@ -129,17 +129,19 @@ static int bzp_init_output(struct bzpayload *bzp, const char *name)
return 0; return 0;
} }
static void bzp_output_segment(struct bzpayload *bzp, struct buffer *b, static int bzp_output_segment(struct bzpayload *bzp, struct buffer *b,
uint32_t type, uint64_t load_addr, uint32_t type, uint64_t load_addr,
enum cbfs_compression algo) enum cbfs_compression algo)
{ {
struct buffer out; struct buffer out;
struct cbfs_payload_segment *seg; struct cbfs_payload_segment *seg;
int len = 0; int len = 0;
/* Don't process empty buffers. */ /* Don't process empty buffers. */
if (b != NULL && buffer_size(b) == 0) if (b != NULL && buffer_size(b) == 0) {
return; ERROR("%s(): Input buffer is empty\n", __func__);
return -1;
}
seg = bzp->out_seg; seg = bzp->out_seg;
seg->type = type; seg->type = type;
@ -147,8 +149,12 @@ static void bzp_output_segment(struct bzpayload *bzp, struct buffer *b,
bzp->out_seg++; bzp->out_seg++;
/* No buffer associated with segment. */ /* No buffer associated with segment. */
if (b == NULL) if (b == NULL) {
return; if (type == PAYLOAD_SEGMENT_ENTRY)
return 0; // entry segments don't have a buffer attached
else
return -1;
}
/* Use a temp buffer for easier management. */ /* Use a temp buffer for easier management. */
buffer_splice(&out, &bzp->output, bzp->offset, buffer_size(b)); buffer_splice(&out, &bzp->output, bzp->offset, buffer_size(b));
@ -157,13 +163,19 @@ static void bzp_output_segment(struct bzpayload *bzp, struct buffer *b,
seg->offset = bzp->offset; seg->offset = bzp->offset;
comp_func_ptr compress_func = compression_function(algo); comp_func_ptr compress_func = compression_function(algo);
compress_func(buffer_get(b), buffer_size(b), buffer_get(&out), &len); int ret = compress_func(buffer_get(b), buffer_size(b), buffer_get(&out), &len);
if (ret) {
ERROR("%s(): Compression failed\n", __func__);
return ret;
}
seg->compression = algo; seg->compression = algo;
seg->len = len; seg->len = len;
/* Update output offset. */ /* Update output offset. */
bzp->offset += len; bzp->offset += len;
return 0; // success
} }
/* TODO: /* TODO:
@ -291,31 +303,58 @@ int parse_bzImage_to_payload(const struct buffer *input,
if (bzp_init_output(&bzp, input->name) != 0) if (bzp_init_output(&bzp, input->name) != 0)
return -1; return -1;
/* parameter block */ int ret;
bzp_output_segment(&bzp, &bzp.parameters,
PAYLOAD_SEGMENT_DATA, LINUX_PARAM_LOC, algo);
/* /* parameter block */
* code block ret = bzp_output_segment(&bzp, &bzp.parameters,
* Note: There is no point in compressing the bzImage (it is already compressed) PAYLOAD_SEGMENT_DATA, LINUX_PARAM_LOC, algo);
*/ if (ret) {
bzp_output_segment(&bzp, &bzp.kernel, ERROR("%s(): Failed to write Linux zero page into segment\n", __func__);
PAYLOAD_SEGMENT_CODE, kernel_base, CBFS_COMPRESS_NONE); return ret;
}
/* code block: There is no point in compressing the bzImage (it is already compressed)*/
ret = bzp_output_segment(&bzp, &bzp.kernel,
PAYLOAD_SEGMENT_CODE, kernel_base, CBFS_COMPRESS_NONE);
if (ret) {
ERROR("%s(): Failed to write Linux kernel into segment\n", __func__);
return ret;
}
/* trampoline */ /* trampoline */
bzp_output_segment(&bzp, &bzp.trampoline, ret = bzp_output_segment(&bzp, &bzp.trampoline,
PAYLOAD_SEGMENT_CODE, TRAMPOLINE_ENTRY_LOC, algo); PAYLOAD_SEGMENT_CODE, TRAMPOLINE_ENTRY_LOC, algo);
if (ret) {
ERROR("%s(): Failed to write Linux trampoline into segment\n", __func__);
return ret;
}
/* cmdline */ /* cmdline */
bzp_output_segment(&bzp, &bzp.cmdline, if (buffer_size(&bzp.cmdline) != 0) {
PAYLOAD_SEGMENT_DATA, COMMAND_LINE_LOC, algo); ret = bzp_output_segment(&bzp, &bzp.cmdline,
PAYLOAD_SEGMENT_DATA, COMMAND_LINE_LOC, algo);
if (ret) {
ERROR("%s(): Failed to write Linux cmdline into segment\n", __func__);
return ret;
}
}
/* initrd */ if (buffer_size(&bzp.initrd) != 0) {
bzp_output_segment(&bzp, &bzp.initrd, /* initrd */
PAYLOAD_SEGMENT_DATA, initrd_base, algo); ret = bzp_output_segment(&bzp, &bzp.initrd,
PAYLOAD_SEGMENT_DATA, initrd_base, algo);
if (ret) {
ERROR("%s(): Failed to write Linux initrd into segment\n", __func__);
return ret;
}
}
/* Terminating entry segment. */ /* Terminating entry segment. */
bzp_output_segment(&bzp, NULL, PAYLOAD_SEGMENT_ENTRY, TRAMPOLINE_ENTRY_LOC, algo); ret = bzp_output_segment(&bzp, NULL, PAYLOAD_SEGMENT_ENTRY, TRAMPOLINE_ENTRY_LOC, algo);
if (ret) {
ERROR("%s(): Failed to write entry segment\n", __func__);
return ret;
}
/* Set size of buffer taking into account potential compression. */ /* Set size of buffer taking into account potential compression. */
buffer_set_size(&bzp.output, bzp.offset); buffer_set_size(&bzp.output, bzp.offset);