diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-07-17 08:26:50 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-07-18 06:44:38 -0400 |
commit | c9a7afa380ecaeb0fbeec2e82f86ec5548ad2963 (patch) | |
tree | bc9339eef58875e52265babad5caeb5e5f2b78fd /arch/s390/net | |
parent | aa2d2c73c21f22ce4c643128b671aa7e7bbff54f (diff) |
s390/bpf,jit: add pkt_type support
s390 version of 3b58908a "x86: bpf_jit_comp: add pkt_type support".
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/net')
-rw-r--r-- | arch/s390/net/bpf_jit_comp.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 788e22395acd..d5f10a43a58f 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/if_vlan.h> | 10 | #include <linux/if_vlan.h> |
11 | #include <linux/filter.h> | 11 | #include <linux/filter.h> |
12 | #include <linux/random.h> | 12 | #include <linux/random.h> |
13 | #include <linux/init.h> | ||
13 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
14 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
15 | #include <asm/facility.h> | 16 | #include <asm/facility.h> |
@@ -222,6 +223,37 @@ static void bpf_jit_epilogue(struct bpf_jit *jit) | |||
222 | EMIT2(0x07fe); | 223 | EMIT2(0x07fe); |
223 | } | 224 | } |
224 | 225 | ||
226 | /* Helper to find the offset of pkt_type in sk_buff | ||
227 | * Make sure its still a 3bit field starting at the MSBs within a byte. | ||
228 | */ | ||
229 | #define PKT_TYPE_MAX 0xe0 | ||
230 | static int pkt_type_offset; | ||
231 | |||
232 | static int __init bpf_pkt_type_offset_init(void) | ||
233 | { | ||
234 | struct sk_buff skb_probe = { | ||
235 | .pkt_type = ~0, | ||
236 | }; | ||
237 | char *ct = (char *)&skb_probe; | ||
238 | int off; | ||
239 | |||
240 | pkt_type_offset = -1; | ||
241 | for (off = 0; off < sizeof(struct sk_buff); off++) { | ||
242 | if (!ct[off]) | ||
243 | continue; | ||
244 | if (ct[off] == PKT_TYPE_MAX) | ||
245 | pkt_type_offset = off; | ||
246 | else { | ||
247 | /* Found non matching bit pattern, fix needed. */ | ||
248 | WARN_ON_ONCE(1); | ||
249 | pkt_type_offset = -1; | ||
250 | return -1; | ||
251 | } | ||
252 | } | ||
253 | return 0; | ||
254 | } | ||
255 | device_initcall(bpf_pkt_type_offset_init); | ||
256 | |||
225 | /* | 257 | /* |
226 | * make sure we dont leak kernel information to user | 258 | * make sure we dont leak kernel information to user |
227 | */ | 259 | */ |
@@ -721,6 +753,16 @@ call_fn: /* lg %r1,<d(function)>(%r13) */ | |||
721 | EMIT4_DISP(0x88500000, 12); | 753 | EMIT4_DISP(0x88500000, 12); |
722 | } | 754 | } |
723 | break; | 755 | break; |
756 | case BPF_S_ANC_PKTTYPE: | ||
757 | if (pkt_type_offset < 0) | ||
758 | goto out; | ||
759 | /* lhi %r5,0 */ | ||
760 | EMIT4(0xa7580000); | ||
761 | /* ic %r5,<d(pkt_type_offset)>(%r2) */ | ||
762 | EMIT4_DISP(0x43502000, pkt_type_offset); | ||
763 | /* srl %r5,5 */ | ||
764 | EMIT4_DISP(0x88500000, 5); | ||
765 | break; | ||
724 | case BPF_S_ANC_CPU: /* A = smp_processor_id() */ | 766 | case BPF_S_ANC_CPU: /* A = smp_processor_id() */ |
725 | #ifdef CONFIG_SMP | 767 | #ifdef CONFIG_SMP |
726 | /* l %r5,<d(cpu_nr)> */ | 768 | /* l %r5,<d(cpu_nr)> */ |