Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Oct 2016 06:55:07 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r307707 - in head: share/man/man4 sys/amd64/amd64 sys/i386/i386 sys/net
Message-ID:  <201610210655.u9L6t71c020639@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <jkim@FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim@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 <jkim@FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim@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 <jkim@FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim@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 <jkim@FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim@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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610210655.u9L6t71c020639>