* [PATCH] ppc: bpf_jit: support MOD operation
@ 2013-08-27 22:49 Vladimir Murzin
2013-09-02 17:48 ` Vladimir Murzin
0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Murzin @ 2013-08-27 22:49 UTC (permalink / raw)
To: linuxppc-dev; +Cc: dborkman, paulus, davem, Vladimir Murzin
commit b6069a9570 (filter: add MOD operation) added generic
support for modulus operation in BPF.
This patch brings JIT support for PPC64
Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
---
arch/powerpc/net/bpf_jit_comp.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index bf56e33..96f24dc 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -193,6 +193,28 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
PPC_MUL(r_A, r_A, r_scratch1);
}
break;
+ case BPF_S_ALU_MOD_X: /* A %= X; */
+ ctx->seen |= SEEN_XREG;
+ PPC_CMPWI(r_X, 0);
+ if (ctx->pc_ret0 != -1) {
+ PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
+ } else {
+ PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
+ PPC_LI(r_ret, 0);
+ PPC_JMP(exit_addr);
+ }
+ PPC_DIVWU(r_scratch1, r_A, r_X);
+ PPC_MUL(r_scratch1, r_X, r_scratch1);
+ PPC_SUB(r_A, r_A, r_scratch1);
+ break;
+ case BPF_S_ALU_MOD_K: /* A %= K; */
+#define r_scratch2 (r_scratch1 + 1)
+ PPC_LI32(r_scratch2, K);
+ PPC_DIVWU(r_scratch1, r_A, r_scratch2);
+ PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
+ PPC_SUB(r_A, r_A, r_scratch1);
+#undef r_scratch2
+ break;
case BPF_S_ALU_DIV_X: /* A /= X; */
ctx->seen |= SEEN_XREG;
PPC_CMPWI(r_X, 0);
--
1.8.1.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-08-27 22:49 [PATCH] ppc: bpf_jit: support MOD operation Vladimir Murzin
@ 2013-09-02 17:48 ` Vladimir Murzin
2013-09-02 20:45 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 9+ messages in thread
From: Vladimir Murzin @ 2013-09-02 17:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: dborkman, paulus, davem
Ping
On Wed, Aug 28, 2013 at 02:49:52AM +0400, Vladimir Murzin wrote:
> commit b6069a9570 (filter: add MOD operation) added generic
> support for modulus operation in BPF.
>
> This patch brings JIT support for PPC64
>
> Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
> ---
> arch/powerpc/net/bpf_jit_comp.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index bf56e33..96f24dc 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -193,6 +193,28 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
> PPC_MUL(r_A, r_A, r_scratch1);
> }
> break;
> + case BPF_S_ALU_MOD_X: /* A %= X; */
> + ctx->seen |= SEEN_XREG;
> + PPC_CMPWI(r_X, 0);
> + if (ctx->pc_ret0 != -1) {
> + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
> + } else {
> + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
> + PPC_LI(r_ret, 0);
> + PPC_JMP(exit_addr);
> + }
> + PPC_DIVWU(r_scratch1, r_A, r_X);
> + PPC_MUL(r_scratch1, r_X, r_scratch1);
> + PPC_SUB(r_A, r_A, r_scratch1);
> + break;
> + case BPF_S_ALU_MOD_K: /* A %= K; */
> +#define r_scratch2 (r_scratch1 + 1)
> + PPC_LI32(r_scratch2, K);
> + PPC_DIVWU(r_scratch1, r_A, r_scratch2);
> + PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
> + PPC_SUB(r_A, r_A, r_scratch1);
> +#undef r_scratch2
> + break;
> case BPF_S_ALU_DIV_X: /* A /= X; */
> ctx->seen |= SEEN_XREG;
> PPC_CMPWI(r_X, 0);
> --
> 1.8.1.5
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-02 17:48 ` Vladimir Murzin
@ 2013-09-02 20:45 ` Benjamin Herrenschmidt
2013-09-03 19:58 ` Vladimir Murzin
2013-09-12 1:18 ` Matt Evans
0 siblings, 2 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2013-09-02 20:45 UTC (permalink / raw)
To: Vladimir Murzin; +Cc: paulus, dborkman, linuxppc-dev, davem, Matt Evans
On Mon, 2013-09-02 at 19:48 +0200, Vladimir Murzin wrote:
> Ping
>
> On Wed, Aug 28, 2013 at 02:49:52AM +0400, Vladimir Murzin wrote:
> > commit b6069a9570 (filter: add MOD operation) added generic
> > support for modulus operation in BPF.
> >
Sorry, nobody got a chance to review that yet. Unfortunately Matt
doesn't work for us anymore and none of us has experience with the
BPF code, so somebody (possibly me) will need to spend a bit of time
figuring it out before verifying that is correct.
Do you have a test case/suite by any chance ?
Ben.
> > This patch brings JIT support for PPC64
> >
> > Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
> > ---
> > arch/powerpc/net/bpf_jit_comp.c | 22 ++++++++++++++++++++++
> > 1 file changed, 22 insertions(+)
> >
> > diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> > index bf56e33..96f24dc 100644
> > --- a/arch/powerpc/net/bpf_jit_comp.c
> > +++ b/arch/powerpc/net/bpf_jit_comp.c
> > @@ -193,6 +193,28 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
> > PPC_MUL(r_A, r_A, r_scratch1);
> > }
> > break;
> > + case BPF_S_ALU_MOD_X: /* A %= X; */
> > + ctx->seen |= SEEN_XREG;
> > + PPC_CMPWI(r_X, 0);
> > + if (ctx->pc_ret0 != -1) {
> > + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
> > + } else {
> > + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
> > + PPC_LI(r_ret, 0);
> > + PPC_JMP(exit_addr);
> > + }
> > + PPC_DIVWU(r_scratch1, r_A, r_X);
> > + PPC_MUL(r_scratch1, r_X, r_scratch1);
> > + PPC_SUB(r_A, r_A, r_scratch1);
> > + break;
> > + case BPF_S_ALU_MOD_K: /* A %= K; */
> > +#define r_scratch2 (r_scratch1 + 1)
> > + PPC_LI32(r_scratch2, K);
> > + PPC_DIVWU(r_scratch1, r_A, r_scratch2);
> > + PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
> > + PPC_SUB(r_A, r_A, r_scratch1);
> > +#undef r_scratch2
> > + break;
> > case BPF_S_ALU_DIV_X: /* A /= X; */
> > ctx->seen |= SEEN_XREG;
> > PPC_CMPWI(r_X, 0);
> > --
> > 1.8.1.5
> >
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-02 20:45 ` Benjamin Herrenschmidt
@ 2013-09-03 19:58 ` Vladimir Murzin
2013-09-03 20:52 ` Daniel Borkmann
2013-09-12 1:18 ` Matt Evans
1 sibling, 1 reply; 9+ messages in thread
From: Vladimir Murzin @ 2013-09-03 19:58 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: paulus, dborkman, linuxppc-dev, davem, Matt Evans
On Tue, Sep 03, 2013 at 06:45:50AM +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2013-09-02 at 19:48 +0200, Vladimir Murzin wrote:
> > Ping
> >
> > On Wed, Aug 28, 2013 at 02:49:52AM +0400, Vladimir Murzin wrote:
> > > commit b6069a9570 (filter: add MOD operation) added generic
> > > support for modulus operation in BPF.
> > >
> Sorry, nobody got a chance to review that yet. Unfortunately Matt
> doesn't work for us anymore and none of us has experience with the
> BPF code, so somebody (possibly me) will need to spend a bit of time
> figuring it out before verifying that is correct.
>
> Do you have a test case/suite by any chance ?
>
> Ben.
>
Hi Ben!
Thanks for your feedback.
This patch is only compile tested. I have no real hardware, but I'll
probably bring up qemu ppc64 till end of the week...
Meanwhile, I've made simple how-to for testing. You can use it if you wish.
It is mainly based on the [1] and rechecked on x86-64.
1. get the tcpdump utility (git clone git://bpf.tcpdump.org/tcpdump)
2. get the libcap library (git clone git://bpf.tcpdump.org/libpcap)
2.1. apply patch for libcap [2] (against libcap-1.3 branch)
2.2. build libcap (./configure && make && ln -s libcap.so.1.3.0 libcap.so)
3. build tcpdump (LDFLAGS="-L/path/to/libcap" ./configure && make)
4. run
# ./tcpdump -d "(ip[2:2] - 20) % 5 != 0 && ip[6] & 0x20 = 0x20"
(000) ldh [14]
(001) jeq #0x800 jt 2 jf 10
(002) ldh [18]
(003) sub #20
(004) mod #5
(005) jeq #0x0 jt 10 jf 6
(006) ldb [22]
(007) and #0x20
(008) jeq #0x20 jt 9 jf 10
(009) ret #65535
(010) ret #0
to get pseudo code (we are interested the most into line #4)
5. enable bpf jit compiler
# echo 2 > /proc/sys/net/core/bpf_jit_enable
6. run
./tcpdump -nv "(ip[2:2] - 20) % 5 != 0 && ip[6] & 0x20 = 0x20"
7. check dmesg for lines starting with (output for x86-64 is provided as an example)
[ 3768.329253] flen=11 proglen=99 pass=3 image=ffffffffa003c000
[ 3768.329254] JIT code: ffffffffa003c000: 55 48 89 e5 48 83 ec 60 48 89 5d f8 44 8b 4f 60
[ 3768.329255] JIT code: ffffffffa003c010: 44 2b 4f 64 4c 8b 87 c0 00 00 00 0f b7 47 76 86
[ 3768.329256] JIT code: ffffffffa003c020: c4 3d 00 08 00 00 75 37 be 02 00 00 00 e8 9f 3e
[ 3768.329257] JIT code: ffffffffa003c030: 02 e1 83 e8 14 31 d2 b9 05 00 00 00 f7 f1 89 d0
[ 3768.329258] JIT code: ffffffffa003c040: 85 c0 74 1b be 06 00 00 00 e8 9f 3e 02 e1 25 20
[ 3768.329259] JIT code: ffffffffa003c050: 00 00 00 83 f8 20 75 07 b8 ff ff 00 00 eb 02 31
[ 3768.329259] JIT code: ffffffffa003c060: c0 c9 c3
8. make sure generated opcodes (JIT code) implement pseudo code form step 4.
Reference
[1] http://comments.gmane.org/gmane.linux.network/242456
[2] http://permalink.gmane.org/gmane.network.tcpdump.devel/5973
P.S.
I hope net people will corect me if I'm wrong there
Cheers
Vladimir Murzin
> > > This patch brings JIT support for PPC64
> > >
> > > Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
> > > ---
> > > arch/powerpc/net/bpf_jit_comp.c | 22 ++++++++++++++++++++++
> > > 1 file changed, 22 insertions(+)
> > >
> > > diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> > > index bf56e33..96f24dc 100644
> > > --- a/arch/powerpc/net/bpf_jit_comp.c
> > > +++ b/arch/powerpc/net/bpf_jit_comp.c
> > > @@ -193,6 +193,28 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
> > > PPC_MUL(r_A, r_A, r_scratch1);
> > > }
> > > break;
> > > + case BPF_S_ALU_MOD_X: /* A %= X; */
> > > + ctx->seen |= SEEN_XREG;
> > > + PPC_CMPWI(r_X, 0);
> > > + if (ctx->pc_ret0 != -1) {
> > > + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
> > > + } else {
> > > + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
> > > + PPC_LI(r_ret, 0);
> > > + PPC_JMP(exit_addr);
> > > + }
> > > + PPC_DIVWU(r_scratch1, r_A, r_X);
> > > + PPC_MUL(r_scratch1, r_X, r_scratch1);
> > > + PPC_SUB(r_A, r_A, r_scratch1);
> > > + break;
> > > + case BPF_S_ALU_MOD_K: /* A %= K; */
> > > +#define r_scratch2 (r_scratch1 + 1)
> > > + PPC_LI32(r_scratch2, K);
> > > + PPC_DIVWU(r_scratch1, r_A, r_scratch2);
> > > + PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
> > > + PPC_SUB(r_A, r_A, r_scratch1);
> > > +#undef r_scratch2
> > > + break;
> > > case BPF_S_ALU_DIV_X: /* A /= X; */
> > > ctx->seen |= SEEN_XREG;
> > > PPC_CMPWI(r_X, 0);
> > > --
> > > 1.8.1.5
> > >
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-03 19:58 ` Vladimir Murzin
@ 2013-09-03 20:52 ` Daniel Borkmann
2013-09-04 7:04 ` Daniel Borkmann
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Borkmann @ 2013-09-03 20:52 UTC (permalink / raw)
To: Vladimir Murzin; +Cc: Matt Evans, paulus, netdev, linuxppc-dev, davem
On 09/03/2013 09:58 PM, Vladimir Murzin wrote:
> On Tue, Sep 03, 2013 at 06:45:50AM +1000, Benjamin Herrenschmidt wrote:
>> On Mon, 2013-09-02 at 19:48 +0200, Vladimir Murzin wrote:
>>> Ping
>>>
>>> On Wed, Aug 28, 2013 at 02:49:52AM +0400, Vladimir Murzin wrote:
>>>> commit b6069a9570 (filter: add MOD operation) added generic
>>>> support for modulus operation in BPF.
>>>>
>> Sorry, nobody got a chance to review that yet. Unfortunately Matt
>> doesn't work for us anymore and none of us has experience with the
>> BPF code, so somebody (possibly me) will need to spend a bit of time
>> figuring it out before verifying that is correct.
>>
>> Do you have a test case/suite by any chance ?
>>
>> Ben.
>>
>
> Hi Ben!
>
> Thanks for your feedback.
>
> This patch is only compile tested. I have no real hardware, but I'll
> probably bring up qemu ppc64 till end of the week...
> Meanwhile, I've made simple how-to for testing. You can use it if you wish.
> It is mainly based on the [1] and rechecked on x86-64.
Please also cc netdev on BPF related changes.
Actually, your test plan can be further simplified ...
For retrieving and disassembling the JIT image, we have bpf_jit_disasm [1].
1) echo 2 > /proc/sys/net/core/bpf_jit_enable
2) ... attach filter ...
3) bpf_jit_disasm -o
For generating a simple stupid test filter, you can use bpfc [2] (also
see its man page). E.g. ...
# cat blub
ldi #10
mod #8
ret a
# bpfc blub
{ 0x0, 0, 0, 0x0000000a },
{ 0x94, 0, 0, 0x00000008 },
{ 0x16, 0, 0, 0x00000000 },
And load this array e.g. either into a small C program that attaches this
as BPF filter, or simply do bpfc blub > blub2 and run netsniff-ng -f blub2\
-s -i eth0, that should also do it.
Then, when attached, the kernel should truncate incoming frames for pf_packet
into max length of 2, just as an example.
[1] kernel tree, tools/net/bpf_jit_disasm.c
[2] git clone git://github.com/borkmann/netsniff-ng.git
> 1. get the tcpdump utility (git clone git://bpf.tcpdump.org/tcpdump)
> 2. get the libcap library (git clone git://bpf.tcpdump.org/libpcap)
> 2.1. apply patch for libcap [2] (against libcap-1.3 branch)
> 2.2. build libcap (./configure && make && ln -s libcap.so.1.3.0 libcap.so)
> 3. build tcpdump (LDFLAGS="-L/path/to/libcap" ./configure && make)
> 4. run
>
> # ./tcpdump -d "(ip[2:2] - 20) % 5 != 0 && ip[6] & 0x20 = 0x20"
> (000) ldh [14]
> (001) jeq #0x800 jt 2 jf 10
> (002) ldh [18]
> (003) sub #20
> (004) mod #5
> (005) jeq #0x0 jt 10 jf 6
> (006) ldb [22]
> (007) and #0x20
> (008) jeq #0x20 jt 9 jf 10
> (009) ret #65535
> (010) ret #0
>
> to get pseudo code (we are interested the most into line #4)
>
> 5. enable bpf jit compiler
>
> # echo 2 > /proc/sys/net/core/bpf_jit_enable
>
> 6. run
>
> ./tcpdump -nv "(ip[2:2] - 20) % 5 != 0 && ip[6] & 0x20 = 0x20"
>
> 7. check dmesg for lines starting with (output for x86-64 is provided as an example)
>
> [ 3768.329253] flen=11 proglen=99 pass=3 image=ffffffffa003c000
> [ 3768.329254] JIT code: ffffffffa003c000: 55 48 89 e5 48 83 ec 60 48 89 5d f8 44 8b 4f 60
> [ 3768.329255] JIT code: ffffffffa003c010: 44 2b 4f 64 4c 8b 87 c0 00 00 00 0f b7 47 76 86
> [ 3768.329256] JIT code: ffffffffa003c020: c4 3d 00 08 00 00 75 37 be 02 00 00 00 e8 9f 3e
> [ 3768.329257] JIT code: ffffffffa003c030: 02 e1 83 e8 14 31 d2 b9 05 00 00 00 f7 f1 89 d0
> [ 3768.329258] JIT code: ffffffffa003c040: 85 c0 74 1b be 06 00 00 00 e8 9f 3e 02 e1 25 20
> [ 3768.329259] JIT code: ffffffffa003c050: 00 00 00 83 f8 20 75 07 b8 ff ff 00 00 eb 02 31
> [ 3768.329259] JIT code: ffffffffa003c060: c0 c9 c3
>
> 8. make sure generated opcodes (JIT code) implement pseudo code form step 4.
>
> Reference
> [1] http://comments.gmane.org/gmane.linux.network/242456
> [2] http://permalink.gmane.org/gmane.network.tcpdump.devel/5973
>
> P.S.
> I hope net people will corect me if I'm wrong there
>
> Cheers
> Vladimir Murzin
>
>>>> This patch brings JIT support for PPC64
>>>>
>>>> Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-03 20:52 ` Daniel Borkmann
@ 2013-09-04 7:04 ` Daniel Borkmann
2013-09-11 16:15 ` Vladimir Murzin
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Borkmann @ 2013-09-04 7:04 UTC (permalink / raw)
To: Vladimir Murzin; +Cc: Matt Evans, paulus, netdev, linuxppc-dev, davem
On 09/03/2013 10:52 PM, Daniel Borkmann wrote:
> On 09/03/2013 09:58 PM, Vladimir Murzin wrote:
[...]
>>> Do you have a test case/suite by any chance ?
>>>
>>> Ben.
>>>
>>
>> Hi Ben!
>>
>> Thanks for your feedback.
>>
>> This patch is only compile tested. I have no real hardware, but I'll
>> probably bring up qemu ppc64 till end of the week...
>> Meanwhile, I've made simple how-to for testing. You can use it if you wish.
>> It is mainly based on the [1] and rechecked on x86-64.
>
> Please also cc netdev on BPF related changes.
>
> Actually, your test plan can be further simplified ...
>
> For retrieving and disassembling the JIT image, we have bpf_jit_disasm [1].
>
> 1) echo 2 > /proc/sys/net/core/bpf_jit_enable
> 2) ... attach filter ...
> 3) bpf_jit_disasm -o
>
> For generating a simple stupid test filter, you can use bpfc [2] (also
> see its man page). E.g. ...
>
> # cat blub
> ldi #10
> mod #8
> ret a
> # bpfc blub
> { 0x0, 0, 0, 0x0000000a },
> { 0x94, 0, 0, 0x00000008 },
> { 0x16, 0, 0, 0x00000000 },
Plus something like ...
ldxi #0
mod x
ret a
For longer-term testing, also trinity has BPF support. ;)
> And load this array e.g. either into a small C program that attaches this
> as BPF filter, or simply do bpfc blub > blub2 and run netsniff-ng -f blub2\
> -s -i eth0, that should also do it.
>
> Then, when attached, the kernel should truncate incoming frames for pf_packet
> into max length of 2, just as an example.
>
> [1] kernel tree, tools/net/bpf_jit_disasm.c
> [2] git clone git://github.com/borkmann/netsniff-ng.git
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-04 7:04 ` Daniel Borkmann
@ 2013-09-11 16:15 ` Vladimir Murzin
0 siblings, 0 replies; 9+ messages in thread
From: Vladimir Murzin @ 2013-09-11 16:15 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Matt Evans, paulus, netdev, linuxppc-dev, davem
On Wed, Sep 04, 2013 at 09:04:04AM +0200, Daniel Borkmann wrote:
> On 09/03/2013 10:52 PM, Daniel Borkmann wrote:
> > On 09/03/2013 09:58 PM, Vladimir Murzin wrote:
> [...]
> >>> Do you have a test case/suite by any chance ?
> >>>
> >>> Ben.
> >>>
> >>
> >> Hi Ben!
> >>
> >> Thanks for your feedback.
> >>
> >> This patch is only compile tested. I have no real hardware, but I'll
> >> probably bring up qemu ppc64 till end of the week...
> >> Meanwhile, I've made simple how-to for testing. You can use it if you wish.
> >> It is mainly based on the [1] and rechecked on x86-64.
Finally I've managed to bring up qemu ppc64 and done simple testing. As a
result I could see difference in opcodes for divide instruction - I've just
sent the patch for that.
WRT mod instruction result is:
For BPF program
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 10
(002) ldh [16]
(003) sub #20
(004) mod #5
(005) jeq #0x0 jt 10 jf 6
(006) ldb [20]
(007) and #0x20
(008) jeq #0x20 jt 9 jf 10
(009) ret #65535
(010) ret #0
The following code is generated (with patch divw to divwu applied)
244 bytes emitted from JIT compiler (pass:3, flen:11)
d0000000015c0018 + <x>:
0: mflr r0
4: std r0,16(r1)
8: std r14,-144(r1)
c: std r15,-136(r1)
10: stdu r1,-288(r1)
14: lwz r7,108(r3)
18: lwz r15,104(r3)
1c: subf r15,r7,r15
20: ld r14,216(r3)
24: lis r7,-16384
28: rldicr r7,r7,32,31
2c: oris r7,r7,9
30: ori r7,r7,43428
34: mtlr r7
38: li r6,12
3c: blrl
40: blt- 0x00000000000000dc
44: nop
48: cmplwi r4,2048
4c: bne- 0x00000000000000d8
50: nop
54: lis r7,-16384
58: rldicr r7,r7,32,31
5c: oris r7,r7,9
60: ori r7,r7,43428
64: mtlr r7
68: li r6,16
6c: blrl
70: blt- 0x00000000000000dc
74: nop
78: addi r4,r4,-20
7c: li r8,5
80: divwu r7,r4,r8
84: mullw r7,r8,r7
88: subf r4,r7,r4
8c: cmplwi r4,0
90: beq- 0x00000000000000d8
94: nop
98: lis r7,-16384
9c: rldicr r7,r7,32,31
a0: oris r7,r7,9
a4: ori r7,r7,43456
a8: mtlr r7
ac: li r6,20
b0: blrl
b4: blt- 0x00000000000000dc
b8: nop
bc: andi. r4,r4,32
c0: cmplwi r4,32
c4: bne- 0x00000000000000d8
c8: nop
cc: li r3,-1
d0: addis r3,r3,1
d4: b 0x00000000000000dc
d8: li r3,0
dc: addi r1,r1,288
e0: ld r0,16(r1)
e4: mtlr r0
e8: ld r14,-144(r1)
ec: ld r15,-136(r1)
f0: blr
Raw codes are
flen=11 proglen=244 pass=3 image=d0000000015c0018
JIT code: 00000000: 7c 08 02 a6 f8 01 00 10 f9 c1 ff 70 f9 e1 ff 78
JIT code: 00000010: f8 21 fe e1 80 e3 00 6c 81 e3 00 68 7d e7 78 50
JIT code: 00000020: e9 c3 00 d8 3c e0 c0 00 78 e7 07 c6 64 e7 00 09
JIT code: 00000030: 60 e7 a9 a4 7c e8 03 a6 38 c0 00 0c 4e 80 00 21
JIT code: 00000040: 41 80 00 9c 60 00 00 00 28 04 08 00 40 82 00 8c
JIT code: 00000050: 60 00 00 00 3c e0 c0 00 78 e7 07 c6 64 e7 00 09
JIT code: 00000060: 60 e7 a9 a4 7c e8 03 a6 38 c0 00 10 4e 80 00 21
JIT code: 00000070: 41 80 00 6c 60 00 00 00 38 84 ff ec 39 00 00 05
JIT code: 00000080: 7c e4 43 96 7c e8 39 d6 7c 87 20 50 28 04 00 00
JIT code: 00000090: 41 82 00 48 60 00 00 00 3c e0 c0 00 78 e7 07 c6
JIT code: 000000a0: 64 e7 00 09 60 e7 a9 c0 7c e8 03 a6 38 c0 00 14
JIT code: 000000b0: 4e 80 00 21 41 80 00 28 60 00 00 00 70 84 00 20
JIT code: 000000c0: 28 04 00 20 40 82 00 14 60 00 00 00 38 60 ff ff
JIT code: 000000d0: 3c 63 00 01 48 00 00 08 38 60 00 00 38 21 01 20
JIT code: 000000e0: e8 01 00 10 7c 08 03 a6 e9 c1 ff 70 e9 e1 ff 78
JIT code: 000000f0: 4e 80 00 20
Ben,
How do you feel about it?
> >
> > Please also cc netdev on BPF related changes.
> >
> > Actually, your test plan can be further simplified ...
> >
> > For retrieving and disassembling the JIT image, we have bpf_jit_disasm [1].
> >
> > 1) echo 2 > /proc/sys/net/core/bpf_jit_enable
> > 2) ... attach filter ...
> > 3) bpf_jit_disasm -o
> >
> > For generating a simple stupid test filter, you can use bpfc [2] (also
> > see its man page). E.g. ...
> >
> > # cat blub
> > ldi #10
> > mod #8
> > ret a
> > # bpfc blub
> > { 0x0, 0, 0, 0x0000000a },
> > { 0x94, 0, 0, 0x00000008 },
> > { 0x16, 0, 0, 0x00000000 },
>
> Plus something like ...
>
> ldxi #0
> mod x
> ret a
>
Thanks Daniel!
Unfortunately, I couldn't trigger JIT compiler with the pair bpfc/netsniff-ng
(even for x86-64). I guess I missed something. I'd be very grateful if you
point at my mistakes.
> For longer-term testing, also trinity has BPF support. ;)
>
Wow! Could do give some hint how to run this for BPF only?
> > And load this array e.g. either into a small C program that attaches this
> > as BPF filter, or simply do bpfc blub > blub2 and run netsniff-ng -f blub2\
> > -s -i eth0, that should also do it.
> >
> > Then, when attached, the kernel should truncate incoming frames for pf_packet
> > into max length of 2, just as an example.
> >
> > [1] kernel tree, tools/net/bpf_jit_disasm.c
> > [2] git clone git://github.com/borkmann/netsniff-ng.git
Thanks
Vladimir
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-02 20:45 ` Benjamin Herrenschmidt
2013-09-03 19:58 ` Vladimir Murzin
@ 2013-09-12 1:18 ` Matt Evans
2013-09-12 2:56 ` Vladimir Murzin
1 sibling, 1 reply; 9+ messages in thread
From: Matt Evans @ 2013-09-12 1:18 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: paulus, Vladimir Murzin, linuxppc-dev, davem, dborkman
Hi Ben, Vladimir,
*dusts off very thick PPC cobwebs* Sorry for the delay as I'm =
travelling, didn't get to this until now.
On 02/09/2013, at 9:45 PM, Benjamin Herrenschmidt wrote:
> On Mon, 2013-09-02 at 19:48 +0200, Vladimir Murzin wrote:
>> Ping
>>=20
>> On Wed, Aug 28, 2013 at 02:49:52AM +0400, Vladimir Murzin wrote:
>>> commit b6069a9570 (filter: add MOD operation) added generic
>>> support for modulus operation in BPF.
>>>=20
> Sorry, nobody got a chance to review that yet. Unfortunately Matt
> doesn't work for us anymore and none of us has experience with the
> BPF code, so somebody (possibly me) will need to spend a bit of time
> figuring it out before verifying that is correct.
>=20
> Do you have a test case/suite by any chance ?
>=20
> Ben.
>=20
>>> This patch brings JIT support for PPC64
>>>=20
>>> Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
>>> ---
>>> arch/powerpc/net/bpf_jit_comp.c | 22 ++++++++++++++++++++++
>>> 1 file changed, 22 insertions(+)
>>>=20
>>> diff --git a/arch/powerpc/net/bpf_jit_comp.c =
b/arch/powerpc/net/bpf_jit_comp.c
>>> index bf56e33..96f24dc 100644
>>> --- a/arch/powerpc/net/bpf_jit_comp.c
>>> +++ b/arch/powerpc/net/bpf_jit_comp.c
>>> @@ -193,6 +193,28 @@ static int bpf_jit_build_body(struct sk_filter =
*fp, u32 *image,
>>> PPC_MUL(r_A, r_A, r_scratch1);
>>> }
>>> break;
>>> + case BPF_S_ALU_MOD_X: /* A %=3D X; */
>>> + ctx->seen |=3D SEEN_XREG;
>>> + PPC_CMPWI(r_X, 0);
>>> + if (ctx->pc_ret0 !=3D -1) {
>>> + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
>>> + } else {
>>> + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
>>> + PPC_LI(r_ret, 0);
>>> + PPC_JMP(exit_addr);
>>> + }
>>> + PPC_DIVWU(r_scratch1, r_A, r_X);
>>> + PPC_MUL(r_scratch1, r_X, r_scratch1);
>>> + PPC_SUB(r_A, r_A, r_scratch1);
>>> + break;
Without having compiled & tested this, it looks fine to me (especially =
with the corrected DIVWU opcode in the other patch, oops...).
>>> + case BPF_S_ALU_MOD_K: /* A %=3D K; */
>>> +#define r_scratch2 (r_scratch1 + 1)
>>> + PPC_LI32(r_scratch2, K);
>>> + PPC_DIVWU(r_scratch1, r_A, r_scratch2);
>>> + PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
>>> + PPC_SUB(r_A, r_A, r_scratch1);
>>> +#undef r_scratch2
>>> + break;
If you need another scratch register, it should really be defined in =
bpf_jit.h instead.
Once you define r_scratch2 in there,
Acked-by: Matt Evans <matt@ozlabs.org>
Thanks!
Matt
>>> case BPF_S_ALU_DIV_X: /* A /=3D X; */
>>> ctx->seen |=3D SEEN_XREG;
>>> PPC_CMPWI(r_X, 0);
>>> --=20
>>> 1.8.1.5
>>>=20
>=20
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ppc: bpf_jit: support MOD operation
2013-09-12 1:18 ` Matt Evans
@ 2013-09-12 2:56 ` Vladimir Murzin
0 siblings, 0 replies; 9+ messages in thread
From: Vladimir Murzin @ 2013-09-12 2:56 UTC (permalink / raw)
To: Matt Evans; +Cc: dborkman, linuxppc-dev, davem, paulus
On Thu, Sep 12, 2013 at 02:18:37AM +0100, Matt Evans wrote:
> Hi Ben, Vladimir,
>
>
> *dusts off very thick PPC cobwebs* Sorry for the delay as I'm travelling, didn't get to this until now.
>
> On 02/09/2013, at 9:45 PM, Benjamin Herrenschmidt wrote:
>
> > On Mon, 2013-09-02 at 19:48 +0200, Vladimir Murzin wrote:
> >> Ping
> >>
> >> On Wed, Aug 28, 2013 at 02:49:52AM +0400, Vladimir Murzin wrote:
> >>> commit b6069a9570 (filter: add MOD operation) added generic
> >>> support for modulus operation in BPF.
> >>>
> > Sorry, nobody got a chance to review that yet. Unfortunately Matt
> > doesn't work for us anymore and none of us has experience with the
> > BPF code, so somebody (possibly me) will need to spend a bit of time
> > figuring it out before verifying that is correct.
> >
> > Do you have a test case/suite by any chance ?
> >
> > Ben.
> >
> >>> This patch brings JIT support for PPC64
> >>>
> >>> Signed-off-by: Vladimir Murzin <murzin.v@gmail.com>
> >>> ---
> >>> arch/powerpc/net/bpf_jit_comp.c | 22 ++++++++++++++++++++++
> >>> 1 file changed, 22 insertions(+)
> >>>
> >>> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> >>> index bf56e33..96f24dc 100644
> >>> --- a/arch/powerpc/net/bpf_jit_comp.c
> >>> +++ b/arch/powerpc/net/bpf_jit_comp.c
> >>> @@ -193,6 +193,28 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
> >>> PPC_MUL(r_A, r_A, r_scratch1);
> >>> }
> >>> break;
> >>> + case BPF_S_ALU_MOD_X: /* A %= X; */
> >>> + ctx->seen |= SEEN_XREG;
> >>> + PPC_CMPWI(r_X, 0);
> >>> + if (ctx->pc_ret0 != -1) {
> >>> + PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
> >>> + } else {
> >>> + PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
> >>> + PPC_LI(r_ret, 0);
> >>> + PPC_JMP(exit_addr);
> >>> + }
> >>> + PPC_DIVWU(r_scratch1, r_A, r_X);
> >>> + PPC_MUL(r_scratch1, r_X, r_scratch1);
> >>> + PPC_SUB(r_A, r_A, r_scratch1);
> >>> + break;
>
> Without having compiled & tested this, it looks fine to me (especially with the corrected DIVWU opcode in the other patch, oops...).
>
> >>> + case BPF_S_ALU_MOD_K: /* A %= K; */
> >>> +#define r_scratch2 (r_scratch1 + 1)
> >>> + PPC_LI32(r_scratch2, K);
> >>> + PPC_DIVWU(r_scratch1, r_A, r_scratch2);
> >>> + PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
> >>> + PPC_SUB(r_A, r_A, r_scratch1);
> >>> +#undef r_scratch2
> >>> + break;
>
> If you need another scratch register, it should really be defined in bpf_jit.h instead.
>
> Once you define r_scratch2 in there,
>
> Acked-by: Matt Evans <matt@ozlabs.org>
>
>
> Thanks!
>
>
> Matt
>
Thanks!
Vladimir
>
>
>
> >>> case BPF_S_ALU_DIV_X: /* A /= X; */
> >>> ctx->seen |= SEEN_XREG;
> >>> PPC_CMPWI(r_X, 0);
> >>> --
> >>> 1.8.1.5
> >>>
> >
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-09-12 2:56 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-27 22:49 [PATCH] ppc: bpf_jit: support MOD operation Vladimir Murzin
2013-09-02 17:48 ` Vladimir Murzin
2013-09-02 20:45 ` Benjamin Herrenschmidt
2013-09-03 19:58 ` Vladimir Murzin
2013-09-03 20:52 ` Daniel Borkmann
2013-09-04 7:04 ` Daniel Borkmann
2013-09-11 16:15 ` Vladimir Murzin
2013-09-12 1:18 ` Matt Evans
2013-09-12 2:56 ` Vladimir Murzin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).