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"