[RFCv2 4/7] bpf/kexec: Introduce three bpf kfunc for kexec
Alexei Starovoitov
alexei.starovoitov at gmail.com
Tue Apr 29 17:03:59 PDT 2025
On Mon, Apr 28, 2025 at 9:13 PM Pingfan Liu <piliu at redhat.com> wrote:
+__bpf_kfunc struct mem_range_result *bpf_kexec_decompress(char
*image_gz_payload, int image_gz_sz,
> + unsigned int expected_decompressed_sz)
> +{
> + decompress_fn decompressor;
> + //todo, use flush to cap the memory size used by decompression
> + long (*flush)(void*, unsigned long) = NULL;
> + struct mem_range_result *range;
> + const char *name;
> + void *output_buf;
> + char *input_buf;
> + int ret;
> +
> + range = kmalloc(sizeof(struct mem_range_result), GFP_KERNEL);
> + if (!range) {
> + pr_err("fail to allocate mem_range_result\n");
> + return NULL;
> + }
> + refcount_set(&range->usage, 1);
> +
> + input_buf = vmalloc(image_gz_sz);
> + if (!input_buf) {
> + pr_err("fail to allocate input buffer\n");
> + kfree(range);
> + return NULL;
> + }
> +
> + ret = copy_from_kernel_nofault(input_buf, image_gz_payload, image_gz_sz);
> + if (ret < 0) {
> + pr_err("Error when copying from 0x%px, size:0x%x\n",
> + image_gz_payload, image_gz_sz);
> + kfree(range);
> + vfree(input_buf);
> + return NULL;
> + }
> +
> + output_buf = vmalloc(expected_decompressed_sz);
> + if (!output_buf) {
> + pr_err("fail to allocate output buffer\n");
> + kfree(range);
> + vfree(input_buf);
> + return NULL;
> + }
> +
> + decompressor = decompress_method(input_buf, image_gz_sz, &name);
> + if (!decompressor) {
> + pr_err("Can not find decompress method\n");
> + kfree(range);
> + vfree(input_buf);
> + vfree(output_buf);
> + return NULL;
> + }
> + //to do, use flush
> + ret = decompressor(image_gz_payload, image_gz_sz, NULL, NULL,
> + output_buf, NULL, NULL);
> +
> + /* Update the range map */
> + if (ret == 0) {
> + range->buf = output_buf;
> + range->size = expected_decompressed_sz;
> + range->status = 0;
> + } else {
> + pr_err("Decompress error\n");
> + vfree(output_buf);
> + kfree(range);
> + return NULL;
> + }
> + pr_info("%s, return range 0x%lx\n", __func__, range);
> + return range;
> +}
These kfuncs look like generic decompress routines.
They're not related to kexec and probably should be in kernel/bpf/helpers.c
or kernel/bpf/compression.c instead of kernel/kexec_pe_image.c.
They also must be KF_SLEEPABLE.
Please test your patches with all kernel debugs enabled.
Otherwise you would have seen all these "sleeping while atomic"
issues yourself.
More information about the kexec
mailing list