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 | |
| 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>
| -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)> */ |
