Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/firmware/efi/libstub/zboot-decompress-gzip.c
26483 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
#include <linux/efi.h>
4
#include <linux/zlib.h>
5
6
#include <asm/efi.h>
7
8
#include "efistub.h"
9
10
#include "inftrees.c"
11
#include "inffast.c"
12
#include "inflate.c"
13
14
extern unsigned char _gzdata_start[], _gzdata_end[];
15
extern u32 __aligned(1) payload_size;
16
17
static struct z_stream_s stream;
18
19
efi_status_t efi_zboot_decompress_init(unsigned long *alloc_size)
20
{
21
efi_status_t status;
22
int rc;
23
24
/* skip the 10 byte header, assume no recorded filename */
25
stream.next_in = _gzdata_start + 10;
26
stream.avail_in = _gzdata_end - stream.next_in;
27
28
status = efi_allocate_pages(zlib_inflate_workspacesize(),
29
(unsigned long *)&stream.workspace,
30
ULONG_MAX);
31
if (status != EFI_SUCCESS)
32
return status;
33
34
rc = zlib_inflateInit2(&stream, -MAX_WBITS);
35
if (rc != Z_OK) {
36
efi_err("failed to initialize GZIP decompressor: %d\n", rc);
37
status = EFI_LOAD_ERROR;
38
goto out;
39
}
40
41
*alloc_size = payload_size;
42
return EFI_SUCCESS;
43
out:
44
efi_free(zlib_inflate_workspacesize(), (unsigned long)stream.workspace);
45
return status;
46
}
47
48
efi_status_t efi_zboot_decompress(u8 *out, unsigned long outlen)
49
{
50
int rc;
51
52
stream.next_out = out;
53
stream.avail_out = outlen;
54
55
rc = zlib_inflate(&stream, 0);
56
zlib_inflateEnd(&stream);
57
58
efi_free(zlib_inflate_workspacesize(), (unsigned long)stream.workspace);
59
60
if (rc != Z_STREAM_END) {
61
efi_err("GZIP decompression failed with status %d\n", rc);
62
return EFI_LOAD_ERROR;
63
}
64
65
efi_cache_sync_image((unsigned long)out, outlen);
66
67
return EFI_SUCCESS;
68
}
69
70