Hi Ilya, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf-next/master] url: https://github.com/intel-lab-lkp/linux/commits/Ilya-Leoshkevich/bpf-Use-ARG_CONST_SIZE_OR_ZERO-for-3rd-argument-of-bpf_tcp_raw_gen_syncookie_ipv-4-6/20230128-143920 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master patch link: https://lore.kernel.org/r/20230128000650.1516334-30-iii%40linux.ibm.com patch subject: [PATCH bpf-next v2 29/31] s390/bpf: Implement arch_prepare_bpf_trampoline() config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20230128/202301281649.0881RcCr-lkp@xxxxxxxxx/config) compiler: s390-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/067ec74d790af1fd8c02b8d3571cf743d53e3656 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Ilya-Leoshkevich/bpf-Use-ARG_CONST_SIZE_OR_ZERO-for-3rd-argument-of-bpf_tcp_raw_gen_syncookie_ipv-4-6/20230128-143920 git checkout 067ec74d790af1fd8c02b8d3571cf743d53e3656 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash arch/s390/net/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@xxxxxxxxx> All warnings (new ones prefixed by >>): >> arch/s390/net/bpf_jit_comp.c:2158:5: warning: no previous prototype for '__arch_prepare_bpf_trampoline' [-Wmissing-prototypes] 2158 | int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vim +/__arch_prepare_bpf_trampoline +2158 arch/s390/net/bpf_jit_comp.c 2157 > 2158 int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, 2159 struct bpf_tramp_jit *tjit, 2160 const struct btf_func_model *m, 2161 u32 flags, struct bpf_tramp_links *tlinks, 2162 void *func_addr) 2163 { 2164 struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; 2165 struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; 2166 struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; 2167 int nr_bpf_args, nr_reg_args, nr_stack_args; 2168 struct bpf_jit *jit = &tjit->common; 2169 int arg, bpf_arg_off; 2170 int i, j; 2171 2172 /* Support as many stack arguments as "mvc" instruction can handle. */ 2173 nr_reg_args = min_t(int, m->nr_args, MAX_NR_REG_ARGS); 2174 nr_stack_args = m->nr_args - nr_reg_args; 2175 if (nr_stack_args > MAX_NR_STACK_ARGS) 2176 return -ENOTSUPP; 2177 2178 /* Return to %r14, since func_addr and %r0 are not available. */ 2179 if (!func_addr && !(flags & BPF_TRAMP_F_ORIG_STACK)) 2180 flags |= BPF_TRAMP_F_SKIP_FRAME; 2181 2182 /* 2183 * Compute how many arguments we need to pass to BPF programs. 2184 * BPF ABI mirrors that of x86_64: arguments that are 16 bytes or 2185 * smaller are packed into 1 or 2 registers; larger arguments are 2186 * passed via pointers. 2187 * In s390x ABI, arguments that are 8 bytes or smaller are packed into 2188 * a register; larger arguments are passed via pointers. 2189 * We need to deal with this difference. 2190 */ 2191 nr_bpf_args = 0; 2192 for (i = 0; i < m->nr_args; i++) { 2193 if (m->arg_size[i] <= 8) 2194 nr_bpf_args += 1; 2195 else if (m->arg_size[i] <= 16) 2196 nr_bpf_args += 2; 2197 else 2198 return -ENOTSUPP; 2199 } 2200 2201 /* 2202 * Calculate the stack layout. 2203 */ 2204 2205 /* Reserve STACK_FRAME_OVERHEAD bytes for the callees. */ 2206 tjit->stack_size = STACK_FRAME_OVERHEAD; 2207 tjit->stack_args_off = alloc_stack(tjit, nr_stack_args * sizeof(u64)); 2208 tjit->reg_args_off = alloc_stack(tjit, nr_reg_args * sizeof(u64)); 2209 tjit->ip_off = alloc_stack(tjit, sizeof(u64)); 2210 tjit->arg_cnt_off = alloc_stack(tjit, sizeof(u64)); 2211 tjit->bpf_args_off = alloc_stack(tjit, nr_bpf_args * sizeof(u64)); 2212 tjit->retval_off = alloc_stack(tjit, sizeof(u64)); 2213 tjit->r7_r8_off = alloc_stack(tjit, 2 * sizeof(u64)); 2214 tjit->r14_off = alloc_stack(tjit, sizeof(u64)); 2215 tjit->run_ctx_off = alloc_stack(tjit, 2216 sizeof(struct bpf_tramp_run_ctx)); 2217 /* The caller has already reserved STACK_FRAME_OVERHEAD bytes. */ 2218 tjit->stack_size -= STACK_FRAME_OVERHEAD; 2219 tjit->orig_stack_args_off = tjit->stack_size + STACK_FRAME_OVERHEAD; 2220 2221 /* aghi %r15,-stack_size */ 2222 EMIT4_IMM(0xa70b0000, REG_15, -tjit->stack_size); 2223 /* stmg %r2,%rN,fwd_reg_args_off(%r15) */ 2224 if (nr_reg_args) 2225 EMIT6_DISP_LH(0xeb000000, 0x0024, REG_2, 2226 REG_2 + (nr_reg_args - 1), REG_15, 2227 tjit->reg_args_off); 2228 for (i = 0, j = 0; i < m->nr_args; i++) { 2229 if (i < MAX_NR_REG_ARGS) 2230 arg = REG_2 + i; 2231 else 2232 arg = tjit->orig_stack_args_off + 2233 (i - MAX_NR_REG_ARGS) * sizeof(u64); 2234 bpf_arg_off = tjit->bpf_args_off + j * sizeof(u64); 2235 if (m->arg_size[i] <= 8) { 2236 if (i < MAX_NR_REG_ARGS) 2237 /* stg %arg,bpf_arg_off(%r15) */ 2238 EMIT6_DISP_LH(0xe3000000, 0x0024, arg, 2239 REG_0, REG_15, bpf_arg_off); 2240 else 2241 /* mvc bpf_arg_off(8,%r15),arg(%r15) */ 2242 _EMIT6(0xd207f000 | bpf_arg_off, 2243 0xf000 | arg); 2244 j += 1; 2245 } else { 2246 if (i < MAX_NR_REG_ARGS) { 2247 /* mvc bpf_arg_off(16,%r15),0(%arg) */ 2248 _EMIT6(0xd20ff000 | bpf_arg_off, 2249 reg2hex[arg] << 12); 2250 } else { 2251 /* lg %r1,arg(%r15) */ 2252 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, REG_0, 2253 REG_15, arg); 2254 /* mvc bpf_arg_off(16,%r15),0(%r1) */ 2255 _EMIT6(0xd20ff000 | bpf_arg_off, 0x1000); 2256 } 2257 j += 2; 2258 } 2259 } 2260 /* stmg %r7,%r8,r7_r8_off(%r15) */ 2261 EMIT6_DISP_LH(0xeb000000, 0x0024, REG_7, REG_8, REG_15, 2262 tjit->r7_r8_off); 2263 /* stg %r14,r14_off(%r15) */ 2264 EMIT6_DISP_LH(0xe3000000, 0x0024, REG_14, REG_0, REG_15, tjit->r14_off); 2265 2266 if (flags & BPF_TRAMP_F_ORIG_STACK) { 2267 /* 2268 * The ftrace trampoline puts the return address (which is the 2269 * address of the original function + S390X_PATCH_SIZE) into 2270 * %r0; see ftrace_shared_hotpatch_trampoline_br and 2271 * ftrace_init_nop() for details. 2272 */ 2273 2274 /* lgr %r8,%r0 */ 2275 EMIT4(0xb9040000, REG_8, REG_0); 2276 } else { 2277 /* %r8 = func_addr + S390X_PATCH_SIZE */ 2278 load_imm64(jit, REG_8, (u64)func_addr + S390X_PATCH_SIZE); 2279 } 2280 2281 /* 2282 * ip = func_addr; 2283 * arg_cnt = m->nr_args; 2284 */ 2285 2286 if (flags & BPF_TRAMP_F_IP_ARG) { 2287 /* %r0 = func_addr */ 2288 load_imm64(jit, REG_0, (u64)func_addr); 2289 /* stg %r0,ip_off(%r15) */ 2290 EMIT6_DISP_LH(0xe3000000, 0x0024, REG_0, REG_0, REG_15, 2291 tjit->ip_off); 2292 } 2293 /* lghi %r0,nr_bpf_args */ 2294 EMIT4_IMM(0xa7090000, REG_0, nr_bpf_args); 2295 /* stg %r0,arg_cnt_off(%r15) */ 2296 EMIT6_DISP_LH(0xe3000000, 0x0024, REG_0, REG_0, REG_15, 2297 tjit->arg_cnt_off); 2298 2299 if (flags & BPF_TRAMP_F_CALL_ORIG) { 2300 /* 2301 * __bpf_tramp_enter(im); 2302 */ 2303 2304 /* %r1 = __bpf_tramp_enter */ 2305 load_imm64(jit, REG_1, (u64)__bpf_tramp_enter); 2306 /* %r2 = im */ 2307 load_imm64(jit, REG_2, (u64)im); 2308 /* %r1() */ 2309 call_r1(jit); 2310 } 2311 2312 for (i = 0; i < fentry->nr_links; i++) 2313 if (invoke_bpf_prog(tjit, m, fentry->links[i], 2314 flags & BPF_TRAMP_F_RET_FENTRY_RET)) 2315 return -EINVAL; 2316 2317 if (fmod_ret->nr_links) { 2318 /* 2319 * retval = 0; 2320 */ 2321 2322 /* xc retval_off(8,%r15),retval_off(%r15) */ 2323 _EMIT6(0xd707f000 | tjit->retval_off, 2324 0xf000 | tjit->retval_off); 2325 2326 for (i = 0; i < fmod_ret->nr_links; i++) { 2327 if (invoke_bpf_prog(tjit, m, fmod_ret->links[i], true)) 2328 return -EINVAL; 2329 2330 /* 2331 * if (retval) 2332 * goto do_fexit; 2333 */ 2334 2335 /* ltg %r0,retval_off(%r15) */ 2336 EMIT6_DISP_LH(0xe3000000, 0x0002, REG_0, REG_0, REG_15, 2337 tjit->retval_off); 2338 /* brcl 7,do_fexit */ 2339 EMIT6_PCREL_RILC(0xc0040000, 7, tjit->do_fexit); 2340 } 2341 } 2342 2343 if (flags & BPF_TRAMP_F_CALL_ORIG) { 2344 /* 2345 * retval = func_addr(args); 2346 */ 2347 2348 /* lmg %r2,%rN,reg_args_off(%r15) */ 2349 if (nr_reg_args) 2350 EMIT6_DISP_LH(0xeb000000, 0x0004, REG_2, 2351 REG_2 + (nr_reg_args - 1), REG_15, 2352 tjit->reg_args_off); 2353 /* mvc stack_args_off(N,%r15),orig_stack_args_off(%r15) */ 2354 if (nr_stack_args) 2355 _EMIT6(0xd200f000 | 2356 (nr_stack_args * sizeof(u64) - 1) << 16 | 2357 tjit->stack_args_off, 2358 0xf000 | tjit->orig_stack_args_off); 2359 /* lgr %r1,%r8 */ 2360 EMIT4(0xb9040000, REG_1, REG_8); 2361 /* %r1() */ 2362 call_r1(jit); 2363 /* stg %r2,retval_off(%r15) */ 2364 EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15, 2365 tjit->retval_off); 2366 2367 im->ip_after_call = jit->prg_buf + jit->prg; 2368 2369 /* 2370 * The following nop will be patched by bpf_tramp_image_put(). 2371 */ 2372 2373 /* brcl 0,im->ip_epilogue */ 2374 EMIT6_PCREL_RILC(0xc0040000, 0, (u64)im->ip_epilogue); 2375 } 2376 2377 /* do_fexit: */ 2378 tjit->do_fexit = jit->prg; 2379 for (i = 0; i < fexit->nr_links; i++) 2380 if (invoke_bpf_prog(tjit, m, fexit->links[i], false)) 2381 return -EINVAL; 2382 2383 if (flags & BPF_TRAMP_F_CALL_ORIG) { 2384 im->ip_epilogue = jit->prg_buf + jit->prg; 2385 2386 /* 2387 * __bpf_tramp_exit(im); 2388 */ 2389 2390 /* %r1 = __bpf_tramp_exit */ 2391 load_imm64(jit, REG_1, (u64)__bpf_tramp_exit); 2392 /* %r2 = im */ 2393 load_imm64(jit, REG_2, (u64)im); 2394 /* %r1() */ 2395 call_r1(jit); 2396 } 2397 2398 /* lmg %r2,%rN,reg_args_off(%r15) */ 2399 if ((flags & BPF_TRAMP_F_RESTORE_REGS) && nr_reg_args) 2400 EMIT6_DISP_LH(0xeb000000, 0x0004, REG_2, 2401 REG_2 + (nr_reg_args - 1), REG_15, 2402 tjit->reg_args_off); 2403 /* lgr %r1,%r8 */ 2404 if (!(flags & BPF_TRAMP_F_SKIP_FRAME)) 2405 EMIT4(0xb9040000, REG_1, REG_8); 2406 /* lmg %r7,%r8,r7_r8_off(%r15) */ 2407 EMIT6_DISP_LH(0xeb000000, 0x0004, REG_7, REG_8, REG_15, 2408 tjit->r7_r8_off); 2409 /* lg %r14,r14_off(%r15) */ 2410 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_14, REG_0, REG_15, tjit->r14_off); 2411 /* lg %r2,retval_off(%r15) */ 2412 if (flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET)) 2413 EMIT6_DISP_LH(0xe3000000, 0x0004, REG_2, REG_0, REG_15, 2414 tjit->retval_off); 2415 /* aghi %r15,stack_size */ 2416 EMIT4_IMM(0xa70b0000, REG_15, tjit->stack_size); 2417 /* Emit an expoline for the following indirect jump. */ 2418 if (nospec_uses_trampoline()) 2419 emit_expoline(jit); 2420 if (flags & BPF_TRAMP_F_SKIP_FRAME) 2421 /* br %r14 */ 2422 _EMIT2(0x07fe); 2423 else 2424 /* br %r1 */ 2425 _EMIT2(0x07f1); 2426 2427 emit_r1_thunk(jit); 2428 2429 return 0; 2430 } 2431 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests