1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <linux/efi.h>
4 #include <linux/zstd.h>
5
6 #include <asm/efi.h>
7
8 #include "decompress_sources.h"
9 #include "efistub.h"
10
11 extern unsigned char _gzdata_start[], _gzdata_end[];
12 extern u32 __aligned(1) payload_size;
13
14 static size_t wksp_size;
15 static void *wksp;
16
efi_zboot_decompress_init(unsigned long * alloc_size)17 efi_status_t efi_zboot_decompress_init(unsigned long *alloc_size)
18 {
19 efi_status_t status;
20
21 wksp_size = zstd_dctx_workspace_bound();
22 status = efi_allocate_pages(wksp_size, (unsigned long *)&wksp, ULONG_MAX);
23 if (status != EFI_SUCCESS)
24 return status;
25
26 *alloc_size = payload_size;
27 return EFI_SUCCESS;
28 }
29
efi_zboot_decompress(u8 * out,unsigned long outlen)30 efi_status_t efi_zboot_decompress(u8 *out, unsigned long outlen)
31 {
32 zstd_dctx *dctx = zstd_init_dctx(wksp, wksp_size);
33 size_t ret;
34 int retval;
35
36 ret = zstd_decompress_dctx(dctx, out, outlen, _gzdata_start,
37 _gzdata_end - _gzdata_start - 4);
38 efi_free(wksp_size, (unsigned long)wksp);
39
40 retval = zstd_get_error_code(ret);
41 if (retval) {
42 efi_err("ZSTD-decompression failed with status %d\n", retval);
43 return EFI_LOAD_ERROR;
44 }
45
46 efi_cache_sync_image((unsigned long)out, outlen);
47
48 return EFI_SUCCESS;
49 }
50