| .. | .. |
|---|
| 2 | 2 | #include <test_progs.h> |
|---|
| 3 | 3 | |
|---|
| 4 | 4 | #define MAX_INSNS 512 |
|---|
| 5 | | -#define MAX_MATCHES 16 |
|---|
| 5 | +#define MAX_MATCHES 24 |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | struct bpf_reg_match { |
|---|
| 8 | 8 | unsigned int line; |
|---|
| .. | .. |
|---|
| 267 | 267 | */ |
|---|
| 268 | 268 | BPF_MOV64_REG(BPF_REG_5, BPF_REG_2), |
|---|
| 269 | 269 | BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6), |
|---|
| 270 | + BPF_MOV64_REG(BPF_REG_4, BPF_REG_5), |
|---|
| 270 | 271 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14), |
|---|
| 271 | 272 | BPF_MOV64_REG(BPF_REG_4, BPF_REG_5), |
|---|
| 272 | 273 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4), |
|---|
| .. | .. |
|---|
| 280 | 281 | BPF_MOV64_REG(BPF_REG_5, BPF_REG_2), |
|---|
| 281 | 282 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14), |
|---|
| 282 | 283 | BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6), |
|---|
| 284 | + BPF_MOV64_REG(BPF_REG_4, BPF_REG_5), |
|---|
| 283 | 285 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 4), |
|---|
| 284 | 286 | BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6), |
|---|
| 285 | 287 | BPF_MOV64_REG(BPF_REG_4, BPF_REG_5), |
|---|
| .. | .. |
|---|
| 311 | 313 | {15, "R4=pkt(id=1,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 312 | 314 | {15, "R5=pkt(id=1,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 313 | 315 | /* Variable offset is added to R5 packet pointer, |
|---|
| 314 | | - * resulting in auxiliary alignment of 4. |
|---|
| 316 | + * resulting in auxiliary alignment of 4. To avoid BPF |
|---|
| 317 | + * verifier's precision backtracking logging |
|---|
| 318 | + * interfering we also have a no-op R4 = R5 |
|---|
| 319 | + * instruction to validate R5 state. We also check |
|---|
| 320 | + * that R4 is what it should be in such case. |
|---|
| 315 | 321 | */ |
|---|
| 316 | | - {18, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 322 | + {19, "R4_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 323 | + {19, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 317 | 324 | /* Constant offset is added to R5, resulting in |
|---|
| 318 | 325 | * reg->off of 14. |
|---|
| 319 | 326 | */ |
|---|
| 320 | | - {19, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 327 | + {20, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 321 | 328 | /* At the time the word size load is performed from R5, |
|---|
| 322 | 329 | * its total fixed offset is NET_IP_ALIGN + reg->off |
|---|
| 323 | 330 | * (14) which is 16. Then the variable offset is 4-byte |
|---|
| 324 | 331 | * aligned, so the total offset is 4-byte aligned and |
|---|
| 325 | 332 | * meets the load's requirements. |
|---|
| 326 | 333 | */ |
|---|
| 327 | | - {23, "R4=pkt(id=2,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 328 | | - {23, "R5=pkt(id=2,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 334 | + {24, "R4=pkt(id=2,off=18,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 335 | + {24, "R5=pkt(id=2,off=14,r=18,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 329 | 336 | /* Constant offset is added to R5 packet pointer, |
|---|
| 330 | 337 | * resulting in reg->off value of 14. |
|---|
| 331 | 338 | */ |
|---|
| 332 | | - {26, "R5_w=pkt(id=0,off=14,r=8"}, |
|---|
| 339 | + {27, "R5_w=pkt(id=0,off=14,r=8"}, |
|---|
| 333 | 340 | /* Variable offset is added to R5, resulting in a |
|---|
| 334 | | - * variable offset of (4n). |
|---|
| 341 | + * variable offset of (4n). See comment for insn #19 |
|---|
| 342 | + * for R4 = R5 trick. |
|---|
| 335 | 343 | */ |
|---|
| 336 | | - {27, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 344 | + {29, "R4_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 345 | + {29, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 337 | 346 | /* Constant is added to R5 again, setting reg->off to 18. */ |
|---|
| 338 | | - {28, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 347 | + {30, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, |
|---|
| 339 | 348 | /* And once more we add a variable; resulting var_off |
|---|
| 340 | 349 | * is still (4n), fixed offset is not changed. |
|---|
| 341 | 350 | * Also, we create a new reg->id. |
|---|
| 342 | 351 | */ |
|---|
| 343 | | - {29, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 352 | + {32, "R4_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 353 | + {32, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 344 | 354 | /* At the time the word size load is performed from R5, |
|---|
| 345 | 355 | * its total fixed offset is NET_IP_ALIGN + reg->off (18) |
|---|
| 346 | 356 | * which is 20. Then the variable offset is (4n), so |
|---|
| 347 | 357 | * the total offset is 4-byte aligned and meets the |
|---|
| 348 | 358 | * load's requirements. |
|---|
| 349 | 359 | */ |
|---|
| 350 | | - {33, "R4=pkt(id=4,off=22,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 351 | | - {33, "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 360 | + {35, "R4=pkt(id=4,off=22,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 361 | + {35, "R5=pkt(id=4,off=18,r=22,umax_value=2040,var_off=(0x0; 0x7fc)"}, |
|---|
| 352 | 362 | }, |
|---|
| 353 | 363 | }, |
|---|
| 354 | 364 | { |
|---|