@@ -450,10 +450,16 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
450
450
}
451
451
break ;
452
452
case BPF_ALU | BPF_DIV | BPF_X : /* (u32) dst /= (u32) src */
453
- EMIT (PPC_RAW_DIVWU (dst_reg , src2_reg , src_reg ));
453
+ if (off )
454
+ EMIT (PPC_RAW_DIVW (dst_reg , src2_reg , src_reg ));
455
+ else
456
+ EMIT (PPC_RAW_DIVWU (dst_reg , src2_reg , src_reg ));
454
457
break ;
455
458
case BPF_ALU | BPF_MOD | BPF_X : /* (u32) dst %= (u32) src */
456
- EMIT (PPC_RAW_DIVWU (_R0 , src2_reg , src_reg ));
459
+ if (off )
460
+ EMIT (PPC_RAW_DIVW (_R0 , src2_reg , src_reg ));
461
+ else
462
+ EMIT (PPC_RAW_DIVWU (_R0 , src2_reg , src_reg ));
457
463
EMIT (PPC_RAW_MULW (_R0 , src_reg , _R0 ));
458
464
EMIT (PPC_RAW_SUB (dst_reg , src2_reg , _R0 ));
459
465
break ;
@@ -467,10 +473,16 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
467
473
if (imm == 1 ) {
468
474
EMIT (PPC_RAW_MR (dst_reg , src2_reg ));
469
475
} else if (is_power_of_2 ((u32 )imm )) {
470
- EMIT (PPC_RAW_SRWI (dst_reg , src2_reg , ilog2 (imm )));
476
+ if (off )
477
+ EMIT (PPC_RAW_SRAWI (dst_reg , src2_reg , ilog2 (imm )));
478
+ else
479
+ EMIT (PPC_RAW_SRWI (dst_reg , src2_reg , ilog2 (imm )));
471
480
} else {
472
481
PPC_LI32 (_R0 , imm );
473
- EMIT (PPC_RAW_DIVWU (dst_reg , src2_reg , _R0 ));
482
+ if (off )
483
+ EMIT (PPC_RAW_DIVW (dst_reg , src2_reg , _R0 ));
484
+ else
485
+ EMIT (PPC_RAW_DIVWU (dst_reg , src2_reg , _R0 ));
474
486
}
475
487
break ;
476
488
case BPF_ALU | BPF_MOD | BPF_K : /* (u32) dst %= (u32) imm */
@@ -480,11 +492,19 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
480
492
if (!is_power_of_2 ((u32 )imm )) {
481
493
bpf_set_seen_register (ctx , tmp_reg );
482
494
PPC_LI32 (tmp_reg , imm );
483
- EMIT (PPC_RAW_DIVWU (_R0 , src2_reg , tmp_reg ));
495
+ if (off )
496
+ EMIT (PPC_RAW_DIVW (_R0 , src2_reg , tmp_reg ));
497
+ else
498
+ EMIT (PPC_RAW_DIVWU (_R0 , src2_reg , tmp_reg ));
484
499
EMIT (PPC_RAW_MULW (_R0 , tmp_reg , _R0 ));
485
500
EMIT (PPC_RAW_SUB (dst_reg , src2_reg , _R0 ));
486
501
} else if (imm == 1 ) {
487
502
EMIT (PPC_RAW_LI (dst_reg , 0 ));
503
+ } else if (off ) {
504
+ EMIT (PPC_RAW_SRAWI (_R0 , src2_reg , ilog2 (imm )));
505
+ EMIT (PPC_RAW_ADDZE (_R0 , _R0 ));
506
+ EMIT (PPC_RAW_SLWI (_R0 , _R0 , ilog2 (imm )));
507
+ EMIT (PPC_RAW_SUB (dst_reg , src2_reg , _R0 ));
488
508
} else {
489
509
imm = ilog2 ((u32 )imm );
490
510
EMIT (PPC_RAW_RLWINM (dst_reg , src2_reg , 0 , 32 - imm , 31 ));
@@ -497,11 +517,21 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
497
517
imm = - imm ;
498
518
if (!is_power_of_2 (imm ))
499
519
return - EOPNOTSUPP ;
500
- if (imm == 1 )
520
+ if (imm == 1 ) {
501
521
EMIT (PPC_RAW_LI (dst_reg , 0 ));
502
- else
522
+ EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
523
+ } else if (off ) {
524
+ EMIT (PPC_RAW_SRAWI (dst_reg_h , src2_reg_h , 31 ));
525
+ EMIT (PPC_RAW_XOR (dst_reg , src2_reg , dst_reg_h ));
526
+ EMIT (PPC_RAW_SUBFC (dst_reg , dst_reg_h , dst_reg ));
527
+ EMIT (PPC_RAW_RLWINM (dst_reg , dst_reg , 0 , 32 - ilog2 (imm ), 31 ));
528
+ EMIT (PPC_RAW_XOR (dst_reg , dst_reg , dst_reg_h ));
529
+ EMIT (PPC_RAW_SUBFC (dst_reg , dst_reg_h , dst_reg ));
530
+ EMIT (PPC_RAW_SUBFE (dst_reg_h , dst_reg_h , dst_reg_h ));
531
+ } else {
503
532
EMIT (PPC_RAW_RLWINM (dst_reg , src2_reg , 0 , 32 - ilog2 (imm ), 31 ));
504
- EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
533
+ EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
534
+ }
505
535
break ;
506
536
case BPF_ALU64 | BPF_DIV | BPF_K : /* dst /= imm */
507
537
if (!imm )
@@ -727,15 +757,30 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
727
757
* MOV
728
758
*/
729
759
case BPF_ALU64 | BPF_MOV | BPF_X : /* dst = src */
730
- if (dst_reg == src_reg )
731
- break ;
732
- EMIT (PPC_RAW_MR (dst_reg , src_reg ));
733
- EMIT (PPC_RAW_MR (dst_reg_h , src_reg_h ));
760
+ if (off == 8 ) {
761
+ EMIT (PPC_RAW_EXTSB (dst_reg , src_reg ));
762
+ EMIT (PPC_RAW_SRAWI (dst_reg_h , dst_reg , 31 ));
763
+ } else if (off == 16 ) {
764
+ EMIT (PPC_RAW_EXTSH (dst_reg , src_reg ));
765
+ EMIT (PPC_RAW_SRAWI (dst_reg_h , dst_reg , 31 ));
766
+ } else if (off == 32 && dst_reg == src_reg ) {
767
+ EMIT (PPC_RAW_SRAWI (dst_reg_h , src_reg , 31 ));
768
+ } else if (off == 32 ) {
769
+ EMIT (PPC_RAW_MR (dst_reg , src_reg ));
770
+ EMIT (PPC_RAW_SRAWI (dst_reg_h , src_reg , 31 ));
771
+ } else if (dst_reg != src_reg ) {
772
+ EMIT (PPC_RAW_MR (dst_reg , src_reg ));
773
+ EMIT (PPC_RAW_MR (dst_reg_h , src_reg_h ));
774
+ }
734
775
break ;
735
776
case BPF_ALU | BPF_MOV | BPF_X : /* (u32) dst = src */
736
777
/* special mov32 for zext */
737
778
if (imm == 1 )
738
779
EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
780
+ else if (off == 8 )
781
+ EMIT (PPC_RAW_EXTSB (dst_reg , src_reg ));
782
+ else if (off == 16 )
783
+ EMIT (PPC_RAW_EXTSH (dst_reg , src_reg ));
739
784
else if (dst_reg != src_reg )
740
785
EMIT (PPC_RAW_MR (dst_reg , src_reg ));
741
786
break ;
@@ -751,6 +796,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
751
796
* BPF_FROM_BE/LE
752
797
*/
753
798
case BPF_ALU | BPF_END | BPF_FROM_LE :
799
+ case BPF_ALU64 | BPF_END | BPF_FROM_LE :
754
800
switch (imm ) {
755
801
case 16 :
756
802
/* Copy 16 bits to upper part */
@@ -785,6 +831,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
785
831
EMIT (PPC_RAW_MR (dst_reg_h , tmp_reg ));
786
832
break ;
787
833
}
834
+ if (BPF_CLASS (code ) == BPF_ALU64 && imm != 64 )
835
+ EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
788
836
break ;
789
837
case BPF_ALU | BPF_END | BPF_FROM_BE :
790
838
switch (imm ) {
@@ -918,11 +966,17 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
918
966
* BPF_LDX
919
967
*/
920
968
case BPF_LDX | BPF_MEM | BPF_B : /* dst = *(u8 *)(ul) (src + off) */
969
+ case BPF_LDX | BPF_MEMSX | BPF_B :
921
970
case BPF_LDX | BPF_PROBE_MEM | BPF_B :
971
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_B :
922
972
case BPF_LDX | BPF_MEM | BPF_H : /* dst = *(u16 *)(ul) (src + off) */
973
+ case BPF_LDX | BPF_MEMSX | BPF_H :
923
974
case BPF_LDX | BPF_PROBE_MEM | BPF_H :
975
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_H :
924
976
case BPF_LDX | BPF_MEM | BPF_W : /* dst = *(u32 *)(ul) (src + off) */
977
+ case BPF_LDX | BPF_MEMSX | BPF_W :
925
978
case BPF_LDX | BPF_PROBE_MEM | BPF_W :
979
+ case BPF_LDX | BPF_PROBE_MEMSX | BPF_W :
926
980
case BPF_LDX | BPF_MEM | BPF_DW : /* dst = *(u64 *)(ul) (src + off) */
927
981
case BPF_LDX | BPF_PROBE_MEM | BPF_DW :
928
982
/*
@@ -931,7 +985,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
931
985
* load only if addr is kernel address (see is_kernel_addr()), otherwise
932
986
* set dst_reg=0 and move on.
933
987
*/
934
- if (BPF_MODE (code ) == BPF_PROBE_MEM ) {
988
+ if (BPF_MODE (code ) == BPF_PROBE_MEM || BPF_MODE ( code ) == BPF_PROBE_MEMSX ) {
935
989
PPC_LI32 (_R0 , TASK_SIZE - off );
936
990
EMIT (PPC_RAW_CMPLW (src_reg , _R0 ));
937
991
PPC_BCC_SHORT (COND_GT , (ctx -> idx + 4 ) * 4 );
@@ -953,30 +1007,48 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
953
1007
* as there are two load instructions for dst_reg_h & dst_reg
954
1008
* respectively.
955
1009
*/
956
- if (size == BPF_DW )
1010
+ if (size == BPF_DW ||
1011
+ (size == BPF_B && BPF_MODE (code ) == BPF_PROBE_MEMSX ))
957
1012
PPC_JMP ((ctx -> idx + 3 ) * 4 );
958
1013
else
959
1014
PPC_JMP ((ctx -> idx + 2 ) * 4 );
960
1015
}
961
1016
962
- switch ( size ) {
963
- case BPF_B :
964
- EMIT ( PPC_RAW_LBZ ( dst_reg , src_reg , off ));
965
- break ;
966
- case BPF_H :
967
- EMIT ( PPC_RAW_LHZ ( dst_reg , src_reg , off )) ;
968
- break ;
969
- case BPF_W :
970
- EMIT ( PPC_RAW_LWZ ( dst_reg , src_reg , off )) ;
971
- break ;
972
- case BPF_DW :
973
- EMIT ( PPC_RAW_LWZ ( dst_reg_h , src_reg , off )) ;
974
- EMIT ( PPC_RAW_LWZ ( dst_reg , src_reg , off + 4 ));
975
- break ;
976
- }
1017
+ if ( BPF_MODE ( code ) == BPF_MEMSX || BPF_MODE ( code ) == BPF_PROBE_MEMSX ) {
1018
+ switch ( size ) {
1019
+ case BPF_B :
1020
+ EMIT ( PPC_RAW_LBZ ( dst_reg , src_reg , off )) ;
1021
+ EMIT ( PPC_RAW_EXTSB ( dst_reg , dst_reg ));
1022
+ break ;
1023
+ case BPF_H :
1024
+ EMIT ( PPC_RAW_LHA ( dst_reg , src_reg , off ));
1025
+ break ;
1026
+ case BPF_W :
1027
+ EMIT ( PPC_RAW_LWZ ( dst_reg , src_reg , off ));
1028
+ break ;
1029
+ }
1030
+ if (! fp -> aux -> verifier_zext )
1031
+ EMIT ( PPC_RAW_SRAWI ( dst_reg_h , dst_reg , 31 ));
977
1032
978
- if (size != BPF_DW && !fp -> aux -> verifier_zext )
979
- EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
1033
+ } else {
1034
+ switch (size ) {
1035
+ case BPF_B :
1036
+ EMIT (PPC_RAW_LBZ (dst_reg , src_reg , off ));
1037
+ break ;
1038
+ case BPF_H :
1039
+ EMIT (PPC_RAW_LHZ (dst_reg , src_reg , off ));
1040
+ break ;
1041
+ case BPF_W :
1042
+ EMIT (PPC_RAW_LWZ (dst_reg , src_reg , off ));
1043
+ break ;
1044
+ case BPF_DW :
1045
+ EMIT (PPC_RAW_LWZ (dst_reg_h , src_reg , off ));
1046
+ EMIT (PPC_RAW_LWZ (dst_reg , src_reg , off + 4 ));
1047
+ break ;
1048
+ }
1049
+ if (size != BPF_DW && !fp -> aux -> verifier_zext )
1050
+ EMIT (PPC_RAW_LI (dst_reg_h , 0 ));
1051
+ }
980
1052
981
1053
if (BPF_MODE (code ) == BPF_PROBE_MEM ) {
982
1054
int insn_idx = ctx -> idx - 1 ;
@@ -1068,6 +1140,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
1068
1140
case BPF_JMP | BPF_JA :
1069
1141
PPC_JMP (addrs [i + 1 + off ]);
1070
1142
break ;
1143
+ case BPF_JMP32 | BPF_JA :
1144
+ PPC_JMP (addrs [i + 1 + imm ]);
1145
+ break ;
1071
1146
1072
1147
case BPF_JMP | BPF_JGT | BPF_K :
1073
1148
case BPF_JMP | BPF_JGT | BPF_X :
0 commit comments