@@ -38,6 +38,51 @@ static struct kexec_res parsed_resource[3] = {
3838 { KEXEC_RES_CMDLINE_NAME , },
3939};
4040
41+ /*
42+ * @name should be one of : kernel, initrd, cmdline
43+ */
44+ static int bpf_kexec_carrier (const char * name , struct mem_range_result * r )
45+ {
46+ struct kexec_res * res ;
47+ int i ;
48+
49+ if (!r || !name )
50+ return - EINVAL ;
51+
52+ for (i = 0 ; i < 3 ; i ++ ) {
53+ if (!strcmp (parsed_resource [i ].name , name ))
54+ break ;
55+ }
56+ if (i >= 3 )
57+ return - EINVAL ;
58+
59+ res = & parsed_resource [i ];
60+ /*
61+ * Replace the intermediate resource generated by the previous step.
62+ */
63+ if (!!res -> r )
64+ mem_range_result_put (res -> r );
65+ mem_range_result_get (r );
66+ res -> r = r ;
67+ return 0 ;
68+ }
69+
70+ static struct carrier_listener kexec_res_listener [3 ] = {
71+ { .name = KEXEC_RES_KERNEL_NAME ,
72+ .alloc_type = 1 ,
73+ .handler = bpf_kexec_carrier ,
74+ },
75+ { .name = KEXEC_RES_INITRD_NAME ,
76+ .alloc_type = 1 ,
77+ .handler = bpf_kexec_carrier ,
78+ },
79+ { .name = KEXEC_RES_CMDLINE_NAME ,
80+ /* kmalloc-ed */
81+ .alloc_type = 0 ,
82+ .handler = bpf_kexec_carrier ,
83+ },
84+ };
85+
4186static bool pe_has_bpf_section (const char * file_buf , unsigned long pe_sz );
4287
4388static bool is_valid_pe (const char * kernel_buf , unsigned long kernel_len )
@@ -159,6 +204,22 @@ __attribute__((used, optimize("O0"))) void bpf_post_handle_pefile(struct kexec_c
159204 dummy += 2 ;
160205}
161206
207+ BTF_KFUNCS_START (kexec_modify_return_ids )
208+ BTF_ID_FLAGS (func , bpf_handle_pefile , KF_SLEEPABLE )
209+ BTF_ID_FLAGS (func , bpf_post_handle_pefile , KF_SLEEPABLE )
210+ BTF_KFUNCS_END (kexec_modify_return_ids )
211+
212+ static const struct btf_kfunc_id_set kexec_modify_return_set = {
213+ .owner = THIS_MODULE ,
214+ .set = & kexec_modify_return_ids ,
215+ };
216+
217+ static int __init kexec_bpf_prog_run_init (void )
218+ {
219+ return register_btf_fmodret_id_set (& kexec_modify_return_set );
220+ }
221+ late_initcall (kexec_bpf_prog_run_init );
222+
162223/*
163224 * PE file may be nested and should be unfold one by one.
164225 * Query 'kernel', 'initrd', 'cmdline' in cur_phase, as they are inputs for the
@@ -213,6 +274,9 @@ static void *pe_image_load(struct kimage *image,
213274 cmdline_start = cmdline ;
214275 cmdline_sz = cmdline_len ;
215276
277+ for (int i = 0 ; i < ARRAY_SIZE (kexec_res_listener ); i ++ )
278+ register_carrier_listener (& kexec_res_listener [i ]);
279+
216280 while (is_valid_format (linux_start , linux_sz ) &&
217281 pe_has_bpf_section (linux_start , linux_sz )) {
218282 struct kexec_context context ;
@@ -250,6 +314,9 @@ static void *pe_image_load(struct kimage *image,
250314 disarm_bpf_prog ();
251315 }
252316
317+ for (int i = 0 ; i < ARRAY_SIZE (kexec_res_listener ); i ++ )
318+ unregister_carrier_listener (kexec_res_listener [i ].name );
319+
253320 /*
254321 * image's kernel_buf, initrd_buf, cmdline_buf are set. Now they should
255322 * be updated to the new content.
0 commit comments