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 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 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