@@ -1083,31 +1083,43 @@ static inline void emit_ldx_r(const s8 dst[], const s8 src,
1083
1083
1084
1084
/* Arithmatic Operation */
1085
1085
static inline void emit_ar_r (const u8 rd , const u8 rt , const u8 rm ,
1086
- const u8 rn , struct jit_ctx * ctx , u8 op ) {
1086
+ const u8 rn , struct jit_ctx * ctx , u8 op ,
1087
+ bool is_jmp64 ) {
1087
1088
switch (op ) {
1088
1089
case BPF_JSET :
1089
- emit (ARM_AND_R (ARM_IP , rt , rn ), ctx );
1090
- emit (ARM_AND_R (ARM_LR , rd , rm ), ctx );
1091
- emit (ARM_ORRS_R (ARM_IP , ARM_LR , ARM_IP ), ctx );
1090
+ if (is_jmp64 ) {
1091
+ emit (ARM_AND_R (ARM_IP , rt , rn ), ctx );
1092
+ emit (ARM_AND_R (ARM_LR , rd , rm ), ctx );
1093
+ emit (ARM_ORRS_R (ARM_IP , ARM_LR , ARM_IP ), ctx );
1094
+ } else {
1095
+ emit (ARM_ANDS_R (ARM_IP , rt , rn ), ctx );
1096
+ }
1092
1097
break ;
1093
1098
case BPF_JEQ :
1094
1099
case BPF_JNE :
1095
1100
case BPF_JGT :
1096
1101
case BPF_JGE :
1097
1102
case BPF_JLE :
1098
1103
case BPF_JLT :
1099
- emit (ARM_CMP_R (rd , rm ), ctx );
1100
- _emit (ARM_COND_EQ , ARM_CMP_R (rt , rn ), ctx );
1104
+ if (is_jmp64 ) {
1105
+ emit (ARM_CMP_R (rd , rm ), ctx );
1106
+ /* Only compare low halve if high halve are equal. */
1107
+ _emit (ARM_COND_EQ , ARM_CMP_R (rt , rn ), ctx );
1108
+ } else {
1109
+ emit (ARM_CMP_R (rt , rn ), ctx );
1110
+ }
1101
1111
break ;
1102
1112
case BPF_JSLE :
1103
1113
case BPF_JSGT :
1104
1114
emit (ARM_CMP_R (rn , rt ), ctx );
1105
- emit (ARM_SBCS_R (ARM_IP , rm , rd ), ctx );
1115
+ if (is_jmp64 )
1116
+ emit (ARM_SBCS_R (ARM_IP , rm , rd ), ctx );
1106
1117
break ;
1107
1118
case BPF_JSLT :
1108
1119
case BPF_JSGE :
1109
1120
emit (ARM_CMP_R (rt , rn ), ctx );
1110
- emit (ARM_SBCS_R (ARM_IP , rd , rm ), ctx );
1121
+ if (is_jmp64 )
1122
+ emit (ARM_SBCS_R (ARM_IP , rd , rm ), ctx );
1111
1123
break ;
1112
1124
}
1113
1125
}
@@ -1615,6 +1627,17 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1615
1627
case BPF_JMP | BPF_JLT | BPF_X :
1616
1628
case BPF_JMP | BPF_JSLT | BPF_X :
1617
1629
case BPF_JMP | BPF_JSLE | BPF_X :
1630
+ case BPF_JMP32 | BPF_JEQ | BPF_X :
1631
+ case BPF_JMP32 | BPF_JGT | BPF_X :
1632
+ case BPF_JMP32 | BPF_JGE | BPF_X :
1633
+ case BPF_JMP32 | BPF_JNE | BPF_X :
1634
+ case BPF_JMP32 | BPF_JSGT | BPF_X :
1635
+ case BPF_JMP32 | BPF_JSGE | BPF_X :
1636
+ case BPF_JMP32 | BPF_JSET | BPF_X :
1637
+ case BPF_JMP32 | BPF_JLE | BPF_X :
1638
+ case BPF_JMP32 | BPF_JLT | BPF_X :
1639
+ case BPF_JMP32 | BPF_JSLT | BPF_X :
1640
+ case BPF_JMP32 | BPF_JSLE | BPF_X :
1618
1641
/* Setup source registers */
1619
1642
rm = arm_bpf_get_reg32 (src_hi , tmp2 [0 ], ctx );
1620
1643
rn = arm_bpf_get_reg32 (src_lo , tmp2 [1 ], ctx );
@@ -1641,6 +1664,17 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1641
1664
case BPF_JMP | BPF_JLE | BPF_K :
1642
1665
case BPF_JMP | BPF_JSLT | BPF_K :
1643
1666
case BPF_JMP | BPF_JSLE | BPF_K :
1667
+ case BPF_JMP32 | BPF_JEQ | BPF_K :
1668
+ case BPF_JMP32 | BPF_JGT | BPF_K :
1669
+ case BPF_JMP32 | BPF_JGE | BPF_K :
1670
+ case BPF_JMP32 | BPF_JNE | BPF_K :
1671
+ case BPF_JMP32 | BPF_JSGT | BPF_K :
1672
+ case BPF_JMP32 | BPF_JSGE | BPF_K :
1673
+ case BPF_JMP32 | BPF_JSET | BPF_K :
1674
+ case BPF_JMP32 | BPF_JLT | BPF_K :
1675
+ case BPF_JMP32 | BPF_JLE | BPF_K :
1676
+ case BPF_JMP32 | BPF_JSLT | BPF_K :
1677
+ case BPF_JMP32 | BPF_JSLE | BPF_K :
1644
1678
if (off == 0 )
1645
1679
break ;
1646
1680
rm = tmp2 [0 ];
@@ -1652,7 +1686,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1652
1686
rd = arm_bpf_get_reg64 (dst , tmp , ctx );
1653
1687
1654
1688
/* Check for the condition */
1655
- emit_ar_r (rd [0 ], rd [1 ], rm , rn , ctx , BPF_OP (code ));
1689
+ emit_ar_r (rd [0 ], rd [1 ], rm , rn , ctx , BPF_OP (code ),
1690
+ BPF_CLASS (code ) == BPF_JMP );
1656
1691
1657
1692
/* Setup JUMP instruction */
1658
1693
jmp_offset = bpf2a32_offset (i + off , i , ctx );
0 commit comments