mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Remove EFI zboot's dependency on the decompression wrappers used by the legacy decompressor boot code, which can only process the input in one go, and this will not work for upcoming support for embedded ELF images. They also do some odd things like providing a barebones malloc() implementation, which is not needed in a hosted environment such as the EFI boot services. So instead, implement GZIP deflate and ZSTD decompression in terms of the underlying libraries. Support for other compression algoritms has already been dropped. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
49 lines
1.1 KiB
C
49 lines
1.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
#include <linux/efi.h>
|
|
#include <linux/zstd.h>
|
|
|
|
#include <asm/efi.h>
|
|
|
|
#include "decompress_sources.h"
|
|
#include "efistub.h"
|
|
|
|
extern unsigned char _gzdata_start[], _gzdata_end[];
|
|
extern u32 __aligned(1) payload_size;
|
|
|
|
static size_t wksp_size;
|
|
static void *wksp;
|
|
|
|
efi_status_t efi_zboot_decompress_init(unsigned long *alloc_size)
|
|
{
|
|
efi_status_t status;
|
|
|
|
wksp_size = zstd_dctx_workspace_bound();
|
|
status = efi_allocate_pages(wksp_size, (unsigned long *)&wksp, ULONG_MAX);
|
|
if (status != EFI_SUCCESS)
|
|
return status;
|
|
|
|
*alloc_size = payload_size;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
efi_status_t efi_zboot_decompress(u8 *out, unsigned long outlen)
|
|
{
|
|
zstd_dctx *dctx = zstd_init_dctx(wksp, wksp_size);
|
|
size_t ret;
|
|
int retval;
|
|
|
|
ret = zstd_decompress_dctx(dctx, out, outlen, _gzdata_start,
|
|
_gzdata_end - _gzdata_start - 4);
|
|
efi_free(wksp_size, (unsigned long)wksp);
|
|
|
|
retval = zstd_get_error_code(ret);
|
|
if (retval) {
|
|
efi_err("ZSTD-decompression failed with status %d\n", retval);
|
|
return EFI_LOAD_ERROR;
|
|
}
|
|
|
|
efi_cache_sync_image((unsigned long)out, outlen);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|