bpf: interpreter support for JMP32
This patch implements interpreting new JMP32 instructions. Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Jiong Wang <jiong.wang@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
df791dc167
Коммит
503a8865a4
|
@ -1145,6 +1145,31 @@ EXPORT_SYMBOL_GPL(__bpf_call_base);
|
|||
INSN_2(JMP, CALL), \
|
||||
/* Exit instruction. */ \
|
||||
INSN_2(JMP, EXIT), \
|
||||
/* 32-bit Jump instructions. */ \
|
||||
/* Register based. */ \
|
||||
INSN_3(JMP32, JEQ, X), \
|
||||
INSN_3(JMP32, JNE, X), \
|
||||
INSN_3(JMP32, JGT, X), \
|
||||
INSN_3(JMP32, JLT, X), \
|
||||
INSN_3(JMP32, JGE, X), \
|
||||
INSN_3(JMP32, JLE, X), \
|
||||
INSN_3(JMP32, JSGT, X), \
|
||||
INSN_3(JMP32, JSLT, X), \
|
||||
INSN_3(JMP32, JSGE, X), \
|
||||
INSN_3(JMP32, JSLE, X), \
|
||||
INSN_3(JMP32, JSET, X), \
|
||||
/* Immediate based. */ \
|
||||
INSN_3(JMP32, JEQ, K), \
|
||||
INSN_3(JMP32, JNE, K), \
|
||||
INSN_3(JMP32, JGT, K), \
|
||||
INSN_3(JMP32, JLT, K), \
|
||||
INSN_3(JMP32, JGE, K), \
|
||||
INSN_3(JMP32, JLE, K), \
|
||||
INSN_3(JMP32, JSGT, K), \
|
||||
INSN_3(JMP32, JSLT, K), \
|
||||
INSN_3(JMP32, JSGE, K), \
|
||||
INSN_3(JMP32, JSLE, K), \
|
||||
INSN_3(JMP32, JSET, K), \
|
||||
/* Jump instructions. */ \
|
||||
/* Register based. */ \
|
||||
INSN_3(JMP, JEQ, X), \
|
||||
|
@ -1405,145 +1430,49 @@ select_insn:
|
|||
out:
|
||||
CONT;
|
||||
}
|
||||
/* JMP */
|
||||
JMP_JA:
|
||||
insn += insn->off;
|
||||
CONT;
|
||||
JMP_JEQ_X:
|
||||
if (DST == SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JEQ_K:
|
||||
if (DST == IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JNE_X:
|
||||
if (DST != SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JNE_K:
|
||||
if (DST != IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JGT_X:
|
||||
if (DST > SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JGT_K:
|
||||
if (DST > IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JLT_X:
|
||||
if (DST < SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JLT_K:
|
||||
if (DST < IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JGE_X:
|
||||
if (DST >= SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JGE_K:
|
||||
if (DST >= IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JLE_X:
|
||||
if (DST <= SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JLE_K:
|
||||
if (DST <= IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSGT_X:
|
||||
if (((s64) DST) > ((s64) SRC)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSGT_K:
|
||||
if (((s64) DST) > ((s64) IMM)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSLT_X:
|
||||
if (((s64) DST) < ((s64) SRC)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSLT_K:
|
||||
if (((s64) DST) < ((s64) IMM)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSGE_X:
|
||||
if (((s64) DST) >= ((s64) SRC)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSGE_K:
|
||||
if (((s64) DST) >= ((s64) IMM)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSLE_X:
|
||||
if (((s64) DST) <= ((s64) SRC)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSLE_K:
|
||||
if (((s64) DST) <= ((s64) IMM)) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSET_X:
|
||||
if (DST & SRC) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_JSET_K:
|
||||
if (DST & IMM) {
|
||||
insn += insn->off;
|
||||
CONT_JMP;
|
||||
}
|
||||
CONT;
|
||||
JMP_EXIT:
|
||||
return BPF_R0;
|
||||
|
||||
/* JMP */
|
||||
#define COND_JMP(SIGN, OPCODE, CMP_OP) \
|
||||
JMP_##OPCODE##_X: \
|
||||
if ((SIGN##64) DST CMP_OP (SIGN##64) SRC) { \
|
||||
insn += insn->off; \
|
||||
CONT_JMP; \
|
||||
} \
|
||||
CONT; \
|
||||
JMP32_##OPCODE##_X: \
|
||||
if ((SIGN##32) DST CMP_OP (SIGN##32) SRC) { \
|
||||
insn += insn->off; \
|
||||
CONT_JMP; \
|
||||
} \
|
||||
CONT; \
|
||||
JMP_##OPCODE##_K: \
|
||||
if ((SIGN##64) DST CMP_OP (SIGN##64) IMM) { \
|
||||
insn += insn->off; \
|
||||
CONT_JMP; \
|
||||
} \
|
||||
CONT; \
|
||||
JMP32_##OPCODE##_K: \
|
||||
if ((SIGN##32) DST CMP_OP (SIGN##32) IMM) { \
|
||||
insn += insn->off; \
|
||||
CONT_JMP; \
|
||||
} \
|
||||
CONT;
|
||||
COND_JMP(u, JEQ, ==)
|
||||
COND_JMP(u, JNE, !=)
|
||||
COND_JMP(u, JGT, >)
|
||||
COND_JMP(u, JLT, <)
|
||||
COND_JMP(u, JGE, >=)
|
||||
COND_JMP(u, JLE, <=)
|
||||
COND_JMP(u, JSET, &)
|
||||
COND_JMP(s, JSGT, >)
|
||||
COND_JMP(s, JSLT, <)
|
||||
COND_JMP(s, JSGE, >=)
|
||||
COND_JMP(s, JSLE, <=)
|
||||
#undef COND_JMP
|
||||
/* STX and ST and LDX*/
|
||||
#define LDST(SIZEOP, SIZE) \
|
||||
STX_MEM_##SIZEOP: \
|
||||
|
|
Загрузка…
Ссылка в новой задаче