Author: jkim
Date: Fri Oct 21 06:55:07 2016
New Revision: 307707
URL: https://svnweb.freebsd.org/changeset/base/307707

Log:
  Implement BPF_MOD and BPF_XOR instructions.
  
  These two ALU instructions first appeared on Linux.  Then, libpcap adopted
  and made them available since 1.6.2.  Now more platforms including NetBSD
  have them in kernel.  So do we.
   --이 줄 이하는 자동으로 제거됩니다--
  > Description of fields to fill in above:                     76 columns --|
  > PR:                       If and which Problem Report is related.
  > Submitted by:             If someone else sent in the change.
  > Reported by:              If someone else reported the issue.
  > Reviewed by:              If someone else reviewed your modification.
  > Approved by:              If you needed approval for this commit.
  > Obtained from:            If the change is from a third party.
  > MFC after:                N [day[s]|week[s]|month[s]].  Request a reminder 
email.
  > MFH:                      Ports tree branch name.  Request approval for 
merge.
  > Relnotes:                 Set to 'yes' for mention in release notes.
  > Security:                 Vulnerability reference (one per line) or 
description.
  > Sponsored by:             If the change was sponsored by an organization.
  > Differential Revision:    https://reviews.freebsd.org/D### (*full* phabric 
URL needed).
  > Empty fields above will be automatically removed.
  
  M    share/man/man4/bpf.4
  M    sys/amd64/amd64/bpf_jit_machdep.c
  M    sys/amd64/amd64/bpf_jit_machdep.h
  M    sys/i386/i386/bpf_jit_machdep.c
  M    sys/i386/i386/bpf_jit_machdep.h
  M    sys/net/bpf_filter.c

Modified:
  head/share/man/man4/bpf.4
  head/sys/amd64/amd64/bpf_jit_machdep.c
  head/sys/amd64/amd64/bpf_jit_machdep.h
  head/sys/i386/i386/bpf_jit_machdep.c
  head/sys/i386/i386/bpf_jit_machdep.h
  head/sys/net/bpf_filter.c

Modified: head/share/man/man4/bpf.4
==============================================================================
--- head/share/man/man4/bpf.4   Fri Oct 21 06:32:45 2016        (r307706)
+++ head/share/man/man4/bpf.4   Fri Oct 21 06:55:07 2016        (r307707)
@@ -49,7 +49,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 15, 2010
+.Dd October 21, 2016
 .Dt BPF 4
 .Os
 .Sh NAME
@@ -881,16 +881,20 @@ BPF_ALU+BPF_ADD+BPF_K     A <- A + k
 BPF_ALU+BPF_SUB+BPF_K  A <- A - k
 BPF_ALU+BPF_MUL+BPF_K  A <- A * k
 BPF_ALU+BPF_DIV+BPF_K  A <- A / k
+BPF_ALU+BPF_MOD+BPF_K  A <- A % k
 BPF_ALU+BPF_AND+BPF_K  A <- A & k
 BPF_ALU+BPF_OR+BPF_K   A <- A | k
+BPF_ALU+BPF_XOR+BPF_K  A <- A ^ k
 BPF_ALU+BPF_LSH+BPF_K  A <- A << k
 BPF_ALU+BPF_RSH+BPF_K  A <- A >> k
 BPF_ALU+BPF_ADD+BPF_X  A <- A + X
 BPF_ALU+BPF_SUB+BPF_X  A <- A - X
 BPF_ALU+BPF_MUL+BPF_X  A <- A * X
 BPF_ALU+BPF_DIV+BPF_X  A <- A / X
+BPF_ALU+BPF_MOD+BPF_X  A <- A % X
 BPF_ALU+BPF_AND+BPF_X  A <- A & X
 BPF_ALU+BPF_OR+BPF_X   A <- A | X
+BPF_ALU+BPF_XOR+BPF_X  A <- A ^ X
 BPF_ALU+BPF_LSH+BPF_X  A <- A << X
 BPF_ALU+BPF_RSH+BPF_X  A <- A >> X
 BPF_ALU+BPF_NEG                A <- -A

Modified: head/sys/amd64/amd64/bpf_jit_machdep.c
==============================================================================
--- head/sys/amd64/amd64/bpf_jit_machdep.c      Fri Oct 21 06:32:45 2016        
(r307706)
+++ head/sys/amd64/amd64/bpf_jit_machdep.c      Fri Oct 21 06:55:07 2016        
(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <j...@freebsd.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <j...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -494,6 +494,7 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                break;
 
                        case BPF_ALU|BPF_DIV|BPF_X:
+                       case BPF_ALU|BPF_MOD|BPF_X:
                                TESTrd(EDX, EDX);
                                if (fmem) {
                                        JNEb(4);
@@ -507,6 +508,8 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                MOVrd(EDX, ECX);
                                ZEROrd(EDX);
                                DIVrd(ECX);
+                               if (BPF_OP(ins->code) == BPF_MOD)
+                                       MOVrd(EDX, EAX);
                                MOVrd(ECX, EDX);
                                break;
 
@@ -518,6 +521,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                ORrd(EDX, EAX);
                                break;
 
+                       case BPF_ALU|BPF_XOR|BPF_X:
+                               XORrd(EDX, EAX);
+                               break;
+
                        case BPF_ALU|BPF_LSH|BPF_X:
                                MOVrd(EDX, ECX);
                                SHL_CLrb(EAX);
@@ -544,10 +551,13 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                break;
 
                        case BPF_ALU|BPF_DIV|BPF_K:
+                       case BPF_ALU|BPF_MOD|BPF_K:
                                MOVrd(EDX, ECX);
                                ZEROrd(EDX);
                                MOVid(ins->k, ESI);
                                DIVrd(ESI);
+                               if (BPF_OP(ins->code) == BPF_MOD)
+                                       MOVrd(EDX, EAX);
                                MOVrd(ECX, EDX);
                                break;
 
@@ -559,6 +569,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                ORid(ins->k, EAX);
                                break;
 
+                       case BPF_ALU|BPF_XOR|BPF_K:
+                               XORid(ins->k, EAX);
+                               break;
+
                        case BPF_ALU|BPF_LSH|BPF_K:
                                SHLib((ins->k) & 0xff, EAX);
                                break;

Modified: head/sys/amd64/amd64/bpf_jit_machdep.h
==============================================================================
--- head/sys/amd64/amd64/bpf_jit_machdep.h      Fri Oct 21 06:32:45 2016        
(r307706)
+++ head/sys/amd64/amd64/bpf_jit_machdep.h      Fri Oct 21 06:55:07 2016        
(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <j...@freebsd.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <j...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -357,6 +357,24 @@ typedef void (*emit_func)(bpf_bin_stream
        emitm(&stream, i32, 4);                                         \
 } while (0)
 
+/* xorl sr32,dr32 */
+#define XORrd(sr32, dr32) do {                                         \
+       emitm(&stream, 0x31, 1);                                        \
+       emitm(&stream,                                                  \
+           (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1);          \
+} while (0)
+
+/* xorl i32,r32 */
+#define XORid(i32, r32) do {                                           \
+       if (r32 == EAX) {                                               \
+               emitm(&stream, 0x35, 1);                                \
+       } else {                                                        \
+               emitm(&stream, 0x81, 1);                                \
+               emitm(&stream, (25 << 3) | r32, 1);                     \
+       }                                                               \
+       emitm(&stream, i32, 4);                                         \
+} while (0)
+
 /* shll i8,r32 */
 #define SHLib(i8, r32) do {                                            \
        emitm(&stream, 0xc1, 1);                                        \

Modified: head/sys/i386/i386/bpf_jit_machdep.c
==============================================================================
--- head/sys/i386/i386/bpf_jit_machdep.c        Fri Oct 21 06:32:45 2016        
(r307706)
+++ head/sys/i386/i386/bpf_jit_machdep.c        Fri Oct 21 06:55:07 2016        
(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <j...@freebsd.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <j...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -139,6 +139,7 @@ bpf_jit_optimize(struct bpf_insn *prog, 
                        flags |= BPF_JIT_FJMP;
                        break;
                case BPF_ALU|BPF_DIV|BPF_K:
+               case BPF_ALU|BPF_MOD|BPF_K:
                        flags |= BPF_JIT_FADK;
                        break;
                }
@@ -515,6 +516,7 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                break;
 
                        case BPF_ALU|BPF_DIV|BPF_X:
+                       case BPF_ALU|BPF_MOD|BPF_X:
                                TESTrd(EDX, EDX);
                                if (save_esp) {
                                        if (fpkt) {
@@ -536,6 +538,8 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                MOVrd(EDX, ECX);
                                ZEROrd(EDX);
                                DIVrd(ECX);
+                               if (BPF_OP(ins->code) == BPF_MOD)
+                                       MOVrd(EDX, EAX);
                                MOVrd(ECX, EDX);
                                break;
 
@@ -547,6 +551,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                ORrd(EDX, EAX);
                                break;
 
+                       case BPF_ALU|BPF_XOR|BPF_X:
+                               XORrd(EDX, EAX);
+                               break;
+
                        case BPF_ALU|BPF_LSH|BPF_X:
                                MOVrd(EDX, ECX);
                                SHL_CLrb(EAX);
@@ -573,10 +581,13 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                break;
 
                        case BPF_ALU|BPF_DIV|BPF_K:
+                       case BPF_ALU|BPF_MOD|BPF_K:
                                MOVrd(EDX, ECX);
                                ZEROrd(EDX);
                                MOVid(ins->k, ESI);
                                DIVrd(ESI);
+                               if (BPF_OP(ins->code) == BPF_MOD)
+                                       MOVrd(EDX, EAX);
                                MOVrd(ECX, EDX);
                                break;
 
@@ -588,6 +599,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
                                ORid(ins->k, EAX);
                                break;
 
+                       case BPF_ALU|BPF_XOR|BPF_K:
+                               XORid(ins->k, EAX);
+                               break;
+
                        case BPF_ALU|BPF_LSH|BPF_K:
                                SHLib((ins->k) & 0xff, EAX);
                                break;

Modified: head/sys/i386/i386/bpf_jit_machdep.h
==============================================================================
--- head/sys/i386/i386/bpf_jit_machdep.h        Fri Oct 21 06:32:45 2016        
(r307706)
+++ head/sys/i386/i386/bpf_jit_machdep.h        Fri Oct 21 06:55:07 2016        
(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <j...@freebsd.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <j...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -302,6 +302,24 @@ typedef void (*emit_func)(bpf_bin_stream
        emitm(&stream, i32, 4);                                         \
 } while (0)
 
+/* xorl sr32,dr32 */
+#define XORrd(sr32, dr32) do {                                         \
+       emitm(&stream, 0x31, 1);                                        \
+       emitm(&stream,                                                  \
+           (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1);          \
+} while (0)
+
+/* xorl i32,r32 */
+#define XORid(i32, r32) do {                                           \
+       if (r32 == EAX) {                                               \
+               emitm(&stream, 0x35, 1);                                \
+       } else {                                                        \
+               emitm(&stream, 0x81, 1);                                \
+               emitm(&stream, (25 << 3) | r32, 1);                     \
+       }                                                               \
+       emitm(&stream, i32, 4);                                         \
+} while (0)
+
 /* shll i8,r32 */
 #define SHLib(i8, r32) do {                                            \
        emitm(&stream, 0xc1, 1);                                        \

Modified: head/sys/net/bpf_filter.c
==============================================================================
--- head/sys/net/bpf_filter.c   Fri Oct 21 06:32:45 2016        (r307706)
+++ head/sys/net/bpf_filter.c   Fri Oct 21 06:55:07 2016        (r307707)
@@ -434,6 +434,12 @@ bpf_filter(const struct bpf_insn *pc, u_
                        A /= X;
                        continue;
 
+               case BPF_ALU|BPF_MOD|BPF_X:
+                       if (X == 0)
+                               return (0);
+                       A %= X;
+                       continue;
+
                case BPF_ALU|BPF_AND|BPF_X:
                        A &= X;
                        continue;
@@ -442,6 +448,10 @@ bpf_filter(const struct bpf_insn *pc, u_
                        A |= X;
                        continue;
 
+               case BPF_ALU|BPF_XOR|BPF_X:
+                       A ^= X;
+                       continue;
+
                case BPF_ALU|BPF_LSH|BPF_X:
                        A <<= X;
                        continue;
@@ -466,6 +476,10 @@ bpf_filter(const struct bpf_insn *pc, u_
                        A /= pc->k;
                        continue;
 
+               case BPF_ALU|BPF_MOD|BPF_K:
+                       A %= pc->k;
+                       continue;
+
                case BPF_ALU|BPF_AND|BPF_K:
                        A &= pc->k;
                        continue;
@@ -474,6 +488,10 @@ bpf_filter(const struct bpf_insn *pc, u_
                        A |= pc->k;
                        continue;
 
+               case BPF_ALU|BPF_XOR|BPF_K:
+                       A ^= pc->k;
+                       continue;
+
                case BPF_ALU|BPF_LSH|BPF_K:
                        A <<= pc->k;
                        continue;
@@ -508,8 +526,8 @@ static const u_short        bpf_code_map[] = {
        0x1013, /* 0x60-0x6f: 1100100000001000 */
        0x1010, /* 0x70-0x7f: 0000100000001000 */
        0x0093, /* 0x80-0x8f: 1100100100000000 */
-       0x0000, /* 0x90-0x9f: 0000000000000000 */
-       0x0000, /* 0xa0-0xaf: 0000000000000000 */
+       0x1010, /* 0x90-0x9f: 0000100000001000 */
+       0x1010, /* 0xa0-0xaf: 0000100000001000 */
        0x0002, /* 0xb0-0xbf: 0100000000000000 */
        0x0000, /* 0xc0-0xcf: 0000000000000000 */
        0x0000, /* 0xd0-0xdf: 0000000000000000 */
@@ -577,7 +595,8 @@ bpf_validate(const struct bpf_insn *f, i
                /*
                 * Check for constant division by 0.
                 */
-               if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
+               if ((p->code == (BPF_ALU|BPF_DIV|BPF_K) ||
+                   p->code == (BPF_ALU|BPF_MOD|BPF_K)) && p->k == 0)
                        return (0);
        }
        return (BPF_CLASS(f[len - 1].code) == BPF_RET);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to