diff options
| author | Jiong Wang <jiong.wang@netronome.com> | 2019-01-26 12:26:04 -0500 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2019-01-26 16:33:01 -0500 |
| commit | 503a8865a47752d0ac2ff642f07e96e8b2103178 (patch) | |
| tree | 619fad24fc9a7affc983d41dfe05f250c808a2c7 /kernel | |
| parent | df791dc167603efb676447a2d7b769a19e8fd722 (diff) | |
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>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/core.c | 197 |
1 files changed, 63 insertions, 134 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 1e443ba97310..bba11c2565ee 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
| @@ -1145,6 +1145,31 @@ EXPORT_SYMBOL_GPL(__bpf_call_base); | |||
| 1145 | INSN_2(JMP, CALL), \ | 1145 | INSN_2(JMP, CALL), \ |
| 1146 | /* Exit instruction. */ \ | 1146 | /* Exit instruction. */ \ |
| 1147 | INSN_2(JMP, EXIT), \ | 1147 | INSN_2(JMP, EXIT), \ |
| 1148 | /* 32-bit Jump instructions. */ \ | ||
| 1149 | /* Register based. */ \ | ||
| 1150 | INSN_3(JMP32, JEQ, X), \ | ||
| 1151 | INSN_3(JMP32, JNE, X), \ | ||
| 1152 | INSN_3(JMP32, JGT, X), \ | ||
| 1153 | INSN_3(JMP32, JLT, X), \ | ||
| 1154 | INSN_3(JMP32, JGE, X), \ | ||
| 1155 | INSN_3(JMP32, JLE, X), \ | ||
| 1156 | INSN_3(JMP32, JSGT, X), \ | ||
| 1157 | INSN_3(JMP32, JSLT, X), \ | ||
| 1158 | INSN_3(JMP32, JSGE, X), \ | ||
| 1159 | INSN_3(JMP32, JSLE, X), \ | ||
| 1160 | INSN_3(JMP32, JSET, X), \ | ||
| 1161 | /* Immediate based. */ \ | ||
| 1162 | INSN_3(JMP32, JEQ, K), \ | ||
| 1163 | INSN_3(JMP32, JNE, K), \ | ||
| 1164 | INSN_3(JMP32, JGT, K), \ | ||
| 1165 | INSN_3(JMP32, JLT, K), \ | ||
| 1166 | INSN_3(JMP32, JGE, K), \ | ||
| 1167 | INSN_3(JMP32, JLE, K), \ | ||
| 1168 | INSN_3(JMP32, JSGT, K), \ | ||
| 1169 | INSN_3(JMP32, JSLT, K), \ | ||
| 1170 | INSN_3(JMP32, JSGE, K), \ | ||
| 1171 | INSN_3(JMP32, JSLE, K), \ | ||
| 1172 | INSN_3(JMP32, JSET, K), \ | ||
| 1148 | /* Jump instructions. */ \ | 1173 | /* Jump instructions. */ \ |
| 1149 | /* Register based. */ \ | 1174 | /* Register based. */ \ |
| 1150 | INSN_3(JMP, JEQ, X), \ | 1175 | INSN_3(JMP, JEQ, X), \ |
| @@ -1405,145 +1430,49 @@ select_insn: | |||
| 1405 | out: | 1430 | out: |
| 1406 | CONT; | 1431 | CONT; |
| 1407 | } | 1432 | } |
| 1408 | /* JMP */ | ||
| 1409 | JMP_JA: | 1433 | JMP_JA: |
| 1410 | insn += insn->off; | 1434 | insn += insn->off; |
| 1411 | CONT; | 1435 | CONT; |
| 1412 | JMP_JEQ_X: | ||
| 1413 | if (DST == SRC) { | ||
| 1414 | insn += insn->off; | ||
| 1415 | CONT_JMP; | ||
| 1416 | } | ||
| 1417 | CONT; | ||
| 1418 | JMP_JEQ_K: | ||
| 1419 | if (DST == IMM) { | ||
| 1420 | insn += insn->off; | ||
| 1421 | CONT_JMP; | ||
| 1422 | } | ||
| 1423 | CONT; | ||
| 1424 | JMP_JNE_X: | ||
| 1425 | if (DST != SRC) { | ||
| 1426 | insn += insn->off; | ||
| 1427 | CONT_JMP; | ||
| 1428 | } | ||
| 1429 | CONT; | ||
| 1430 | JMP_JNE_K: | ||
| 1431 | if (DST != IMM) { | ||
| 1432 | insn += insn->off; | ||
| 1433 | CONT_JMP; | ||
| 1434 | } | ||
| 1435 | CONT; | ||
| 1436 | JMP_JGT_X: | ||
| 1437 | if (DST > SRC) { | ||
| 1438 | insn += insn->off; | ||
| 1439 | CONT_JMP; | ||
| 1440 | } | ||
| 1441 | CONT; | ||
| 1442 | JMP_JGT_K: | ||
| 1443 | if (DST > IMM) { | ||
| 1444 | insn += insn->off; | ||
| 1445 | CONT_JMP; | ||
| 1446 | } | ||
| 1447 | CONT; | ||
| 1448 | JMP_JLT_X: | ||
| 1449 | if (DST < SRC) { | ||
| 1450 | insn += insn->off; | ||
| 1451 | CONT_JMP; | ||
| 1452 | } | ||
| 1453 | CONT; | ||
| 1454 | JMP_JLT_K: | ||
| 1455 | if (DST < IMM) { | ||
| 1456 | insn += insn->off; | ||
| 1457 | CONT_JMP; | ||
| 1458 | } | ||
| 1459 | CONT; | ||
| 1460 | JMP_JGE_X: | ||
| 1461 | if (DST >= SRC) { | ||
| 1462 | insn += insn->off; | ||
| 1463 | CONT_JMP; | ||
| 1464 | } | ||
| 1465 | CONT; | ||
| 1466 | JMP_JGE_K: | ||
| 1467 | if (DST >= IMM) { | ||
| 1468 | insn += insn->off; | ||
| 1469 | CONT_JMP; | ||
| 1470 | } | ||
| 1471 | CONT; | ||
| 1472 | JMP_JLE_X: | ||
| 1473 | if (DST <= SRC) { | ||
| 1474 | insn += insn->off; | ||
| 1475 | CONT_JMP; | ||
| 1476 | } | ||
| 1477 | CONT; | ||
| 1478 | JMP_JLE_K: | ||
| 1479 | if (DST <= IMM) { | ||
| 1480 | insn += insn->off; | ||
| 1481 | CONT_JMP; | ||
| 1482 | } | ||
| 1483 | CONT; | ||
| 1484 | JMP_JSGT_X: | ||
| 1485 | if (((s64) DST) > ((s64) SRC)) { | ||
| 1486 | insn += insn->off; | ||
| 1487 | CONT_JMP; | ||
| 1488 | } | ||
| 1489 | CONT; | ||
| 1490 | JMP_JSGT_K: | ||
| 1491 | if (((s64) DST) > ((s64) IMM)) { | ||
| 1492 | insn += insn->off; | ||
| 1493 | CONT_JMP; | ||
| 1494 | } | ||
| 1495 | CONT; | ||
| 1496 | JMP_JSLT_X: | ||
| 1497 | if (((s64) DST) < ((s64) SRC)) { | ||
| 1498 | insn += insn->off; | ||
| 1499 | CONT_JMP; | ||
| 1500 | } | ||
| 1501 | CONT; | ||
| 1502 | JMP_JSLT_K: | ||
| 1503 | if (((s64) DST) < ((s64) IMM)) { | ||
| 1504 | insn += insn->off; | ||
| 1505 | CONT_JMP; | ||
| 1506 | } | ||
| 1507 | CONT; | ||
| 1508 | JMP_JSGE_X: | ||
| 1509 | if (((s64) DST) >= ((s64) SRC)) { | ||
| 1510 | insn += insn->off; | ||
| 1511 | CONT_JMP; | ||
| 1512 | } | ||
| 1513 | CONT; | ||
| 1514 | JMP_JSGE_K: | ||
| 1515 | if (((s64) DST) >= ((s64) IMM)) { | ||
| 1516 | insn += insn->off; | ||
| 1517 | CONT_JMP; | ||
| 1518 | } | ||
| 1519 | CONT; | ||
| 1520 | JMP_JSLE_X: | ||
| 1521 | if (((s64) DST) <= ((s64) SRC)) { | ||
| 1522 | insn += insn->off; | ||
| 1523 | CONT_JMP; | ||
| 1524 | } | ||
| 1525 | CONT; | ||
| 1526 | JMP_JSLE_K: | ||
| 1527 | if (((s64) DST) <= ((s64) IMM)) { | ||
| 1528 | insn += insn->off; | ||
| 1529 | CONT_JMP; | ||
| 1530 | } | ||
| 1531 | CONT; | ||
| 1532 | JMP_JSET_X: | ||
| 1533 | if (DST & SRC) { | ||
| 1534 | insn += insn->off; | ||
| 1535 | CONT_JMP; | ||
| 1536 | } | ||
| 1537 | CONT; | ||
| 1538 | JMP_JSET_K: | ||
| 1539 | if (DST & IMM) { | ||
| 1540 | insn += insn->off; | ||
| 1541 | CONT_JMP; | ||
| 1542 | } | ||
| 1543 | CONT; | ||
| 1544 | JMP_EXIT: | 1436 | JMP_EXIT: |
| 1545 | return BPF_R0; | 1437 | return BPF_R0; |
| 1546 | 1438 | /* JMP */ | |
| 1439 | #define COND_JMP(SIGN, OPCODE, CMP_OP) \ | ||
| 1440 | JMP_##OPCODE##_X: \ | ||
| 1441 | if ((SIGN##64) DST CMP_OP (SIGN##64) SRC) { \ | ||
| 1442 | insn += insn->off; \ | ||
| 1443 | CONT_JMP; \ | ||
| 1444 | } \ | ||
| 1445 | CONT; \ | ||
| 1446 | JMP32_##OPCODE##_X: \ | ||
| 1447 | if ((SIGN##32) DST CMP_OP (SIGN##32) SRC) { \ | ||
| 1448 | insn += insn->off; \ | ||
| 1449 | CONT_JMP; \ | ||
| 1450 | } \ | ||
| 1451 | CONT; \ | ||
| 1452 | JMP_##OPCODE##_K: \ | ||
| 1453 | if ((SIGN##64) DST CMP_OP (SIGN##64) IMM) { \ | ||
| 1454 | insn += insn->off; \ | ||
| 1455 | CONT_JMP; \ | ||
| 1456 | } \ | ||
| 1457 | CONT; \ | ||
| 1458 | JMP32_##OPCODE##_K: \ | ||
| 1459 | if ((SIGN##32) DST CMP_OP (SIGN##32) IMM) { \ | ||
| 1460 | insn += insn->off; \ | ||
| 1461 | CONT_JMP; \ | ||
| 1462 | } \ | ||
| 1463 | CONT; | ||
| 1464 | COND_JMP(u, JEQ, ==) | ||
| 1465 | COND_JMP(u, JNE, !=) | ||
| 1466 | COND_JMP(u, JGT, >) | ||
| 1467 | COND_JMP(u, JLT, <) | ||
| 1468 | COND_JMP(u, JGE, >=) | ||
| 1469 | COND_JMP(u, JLE, <=) | ||
| 1470 | COND_JMP(u, JSET, &) | ||
| 1471 | COND_JMP(s, JSGT, >) | ||
| 1472 | COND_JMP(s, JSLT, <) | ||
| 1473 | COND_JMP(s, JSGE, >=) | ||
| 1474 | COND_JMP(s, JSLE, <=) | ||
| 1475 | #undef COND_JMP | ||
| 1547 | /* STX and ST and LDX*/ | 1476 | /* STX and ST and LDX*/ |
| 1548 | #define LDST(SIZEOP, SIZE) \ | 1477 | #define LDST(SIZEOP, SIZE) \ |
| 1549 | STX_MEM_##SIZEOP: \ | 1478 | STX_MEM_##SIZEOP: \ |
