Currently passing alignment greater than 4 to bpf_jit_binary_alloc does not work: in such cases it silently aligns only to 4 bytes. On s390, in order to load a constant from memory in a large (>512k) BPF program, one must use lgrl instruction, whose memory operand must be aligned on an 8-byte boundary. This patch makes it possible to request 8-byte alignment from bpf_jit_binary_alloc, and also makes it issue a warning when an unsupported alignment is requested.
Unified · Split
| @@ -515,10 +515,12 @@ struct sock_fprog_kern { · 514 unmodified lines | ||
| 515 | 515 | struct sock_filter *filter; |
| 516 | 516 | }; |
| 517 | 517 | |
| 518 | +/* Some arches need doubleword alignment for their instructions and/or data */ | |
| 519 | +#define BPF_IMAGE_ALIGNMENT 8 | |
| 520 | + | |
| 518 | 521 | struct bpf_binary_header { |
| 519 | 522 | u32 pages; |
| 520 | − /* Some arches need word alignment for their instructions */ | |
| 521 | − u8 image[] __aligned(4); | |
| 523 | + u8 image[] __aligned(BPF_IMAGE_ALIGNMENT); | |
| 522 | 524 | }; |
| 523 | 525 | |
| 524 | 526 | struct bpf_prog { |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <linux/rcupdate.h> |
| 32 | 32 | #include <linux/perf_event.h> |
| 33 | 33 | #include <linux/extable.h> |
| 34 | +#include <linux/log2.h> | |
| 34 | 35 | #include <asm/unaligned.h> |
| 35 | 36 | |
| 36 | 37 | /* Registers */ |
| @@ -815,6 +816,9 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, · 778 unmodified lines | ||
| 815 | 816 | struct bpf_binary_header *hdr; |
| 816 | 817 | u32 size, hole, start, pages; |
| 817 | 818 | |
| 819 | + WARN_ON_ONCE(!is_power_of_2(alignment) || | |
| 820 | + alignment > BPF_IMAGE_ALIGNMENT); | |
| 821 | + | |
| 818 | 822 | /* Most of BPF filters are really small, but if some of them |
| 819 | 823 | * fill a page, allow at least 128 extra bytes to insert a |
| 820 | 824 | * random section of illegal instructions. |