bpf: Support doubleword alignment in bpf_jit_binary_alloc
authorIlya Leoshkevich <iii@linux.ibm.com>
Fri, 15 Nov 2019 12:37:22 +0000 (13:37 +0100)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 15 Nov 2019 21:25:00 +0000 (22:25 +0100)
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.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20191115123722.58462-1-iii@linux.ibm.com
include/linux/filter.h
kernel/bpf/core.c

index 7a6f8f6f1da4ede123c0850a1631608ac8fe1f92..ad80e9c6111c9f6cb4c152e45e985fca56a15faf 100644 (file)
@@ -515,10 +515,12 @@ struct sock_fprog_kern {
        struct sock_filter      *filter;
 };
 
+/* Some arches need doubleword alignment for their instructions and/or data */
+#define BPF_IMAGE_ALIGNMENT 8
+
 struct bpf_binary_header {
        u32 pages;
-       /* Some arches need word alignment for their instructions */
-       u8 image[] __aligned(4);
+       u8 image[] __aligned(BPF_IMAGE_ALIGNMENT);
 };
 
 struct bpf_prog {
index c1fde030328037e32b9fe7af309fccb156b030d7..99693f3c4e99c9cc75a95d081da7c601d6bad0b1 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/rcupdate.h>
 #include <linux/perf_event.h>
 #include <linux/extable.h>
+#include <linux/log2.h>
 #include <asm/unaligned.h>
 
 /* Registers */
@@ -815,6 +816,9 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
        struct bpf_binary_header *hdr;
        u32 size, hole, start, pages;
 
+       WARN_ON_ONCE(!is_power_of_2(alignment) ||
+                    alignment > BPF_IMAGE_ALIGNMENT);
+
        /* Most of BPF filters are really small, but if some of them
         * fill a page, allow at least 128 extra bytes to insert a
         * random section of illegal instructions.