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>