On Mon, Apr 28, 2025 at 9:13 PM Pingfan Liu <piliu@xxxxxxxxxx> 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.