@@ -446,6 +446,15 @@ static int alignment_get_arm64(struct pt_regs *regs, __le64 __user *ip, u32 *ins
446
446
return 0 ;
447
447
}
448
448
449
+ int64_t extend_sign (int64_t in , int bits ){
450
+ bits -- ;
451
+ if (in & (1 << bits )){
452
+ // extend sign
453
+ return (0xffffffffffffffff << bits ) | in ;
454
+ }
455
+ return in ;
456
+ }
457
+
449
458
/*int ldpstp_offset_fixup(u32 instr, struct pt_regs *regs){
450
459
uint8_t load = (instr >> 22) & 1;
451
460
uint8_t simd = (instr >> 26) & 1;
@@ -513,10 +522,16 @@ int do_ls_fixup(u32 instr, struct pt_regs *regs, struct fixupDescription* desc){
513
522
if (desc -> simd ){
514
523
// At least currently, there aren't any simd instructions supported that use more than one data register
515
524
//__uint128_t tmp;
525
+
526
+ // probably better for performance to read both registers with one function to kernel_neon_* doesn't have to be called more than once
516
527
read_simd_reg (desc -> reg1 , data1 );
528
+ read_simd_reg (desc -> reg2 , data2 );
517
529
//data1[0] = tmp;
518
530
//data1[1] = *(((u64*)&tmp) + 1);
519
- printk ("SIMD: storing 0x%llx %llx (%d bits) at 0x%px" , data1 [1 ], data1 [0 ], desc -> width , desc -> addr );
531
+ ///printk("SIMD: storing 0x%llx %llx (%d bits) at 0x%px", data1[1], data1[0], desc->width, desc->addr);
532
+ if (desc -> width < 128 ){
533
+ return -1 ;
534
+ }
520
535
} else {
521
536
data1 [0 ] = regs -> regs [desc -> reg1 ];
522
537
data2 [0 ] = regs -> regs [desc -> reg2 ];
@@ -646,23 +661,29 @@ int ls_pair_fixup(u32 instr, struct pt_regs *regs, struct fixupDescription* desc
646
661
uint8_t Rn = (instr >> 5 ) & 0x1f ;
647
662
uint8_t Rt = instr & 0x1f ;
648
663
649
- int16_t imm = 0xffff & imm7 ;
650
-
664
+ int64_t imm = extend_sign ( imm7 , 7 ) ;
665
+ int immshift = 0 ;
651
666
desc -> load = load ;
652
667
desc -> simd = simd ;
653
668
654
669
// opc controls the width
655
- switch (opc ){
656
- case 0 :
657
- desc -> width = 32 ;
658
- imm <<= 2 ;
659
- break ;
660
- case 2 :
661
- desc -> width = 64 ;
662
- imm <<= 3 ;
663
- break ;
664
- default :
665
- return -1 ;
670
+ if (simd ){
671
+ desc -> width = 32 << opc ;
672
+ immshift = 4 << opc ;
673
+ imm <<= immshift ;
674
+ } else {
675
+ switch (opc ){
676
+ case 0 :
677
+ desc -> width = 32 ;
678
+ imm <<= 2 ;
679
+ break ;
680
+ case 2 :
681
+ desc -> width = 64 ;
682
+ imm <<= 3 ;
683
+ break ;
684
+ default :
685
+ return -1 ;
686
+ }
666
687
}
667
688
668
689
// op2 controls the indexing
@@ -687,15 +708,25 @@ int ls_reg_unsigned_imm(u32 instr, struct pt_regs *regs, struct fixupDescription
687
708
uint8_t size = (instr >> 30 ) & 3 ;
688
709
uint8_t simd = (instr >> 26 ) & 1 ;
689
710
uint8_t opc = (instr >> 22 ) & 3 ;
690
- uint16_t imm12 = (instr >> 10 ) & 0xfff ;
711
+ uint64_t imm12 = (instr >> 10 ) & 0xfff ;
691
712
uint8_t Rn = (instr >> 5 ) & 0x1f ;
692
713
uint8_t Rt = instr & 0x1f ;
693
714
694
715
uint8_t load = opc & 1 ;
695
- uint8_t extend_sign = ((opc & 2 ) >> 1 ) & !simd ;
696
- printk ("size: %d simd: %d opc: %d imm12: 0x%x Rn: %d Rt: %d\n" , size , simd , opc , imm12 , Rn , Rt );
716
+ uint8_t extend_sign = 0 ;// = ((opc & 2) >> 1 ) & !simd;
717
+ int width_shift = 0 ;
718
+
719
+ if (simd ){
720
+ extend_sign = 0 ;
721
+ width_shift = size | ((opc & 2 ) << 1 );
722
+ } else {
723
+ extend_sign = ((opc & 2 ) >> 1 );
724
+ width_shift = size ;
725
+ }
726
+
727
+ ///printk("size: %d simd: %d opc: %d imm12: 0x%x Rn: %d Rt: %d\n", size, simd, opc, imm12, Rn, Rt);
697
728
// when in simd mode, opc&2 is a third size bit. Otherwise, it's there for sign extension
698
- int width_shift = (size | (((opc & 2 ) & (simd << 1 )) << 1 ));
729
+ // width_shift = (size | (((opc & 2) & (simd << 1)) << 1));
699
730
desc -> width = 8 << width_shift ;
700
731
701
732
if ((size & 1 ) && simd && (opc & 2 )){
@@ -707,7 +738,7 @@ int ls_reg_unsigned_imm(u32 instr, struct pt_regs *regs, struct fixupDescription
707
738
desc -> extendSign = extend_sign ;
708
739
u64 addr = regs -> regs [Rn ];
709
740
desc -> addr = addr + (imm12 << width_shift );
710
- printk ("unsigned imm\n" );
741
+ /// printk("unsigned imm\n");
711
742
712
743
return do_ls_fixup (instr , regs , desc );
713
744
}
@@ -728,9 +759,14 @@ u64 extend_reg(u64 reg, int type, int shift){
728
759
int32_t stmpw = reg ;
729
760
int64_t stmpdw = stmpw ;
730
761
tmp = (u64 )stmpdw ;
762
+ } else {
763
+ printk ("Other branch I forgor about previously!\n" );
764
+ tmp = reg ; // since the size stays the same, I don't think this makes a difference
731
765
}
732
766
}
733
767
768
+ ///printk("extend_reg: reg 0x%lx out (before shift) 0x%lx signed: %x\n", reg, tmp, is_signed);
769
+
734
770
return tmp << shift ;
735
771
}
736
772
@@ -826,7 +862,7 @@ int lsr_unscaled_immediate_fixup(u32 instr, struct pt_regs *regs, struct fixupDe
826
862
desc->data1_simd = *(((u64*)&tmp) + 1);*/
827
863
return do_ls_fixup (instr , regs , desc );
828
864
}
829
- printk ("SIMD: %d\n" , simd );
865
+ /// printk("SIMD: %d\n", simd);
830
866
return 1 ;
831
867
}
832
868
@@ -876,6 +912,31 @@ int ls_fixup(u32 instr, struct pt_regs *regs, struct fixupDescription* desc){
876
912
return r ;
877
913
}
878
914
915
+ uint32_t * seenCMDs ;
916
+ size_t seenCMDCount = 0 ;
917
+ size_t seenCMDSize = 0 ;
918
+
919
+ void instrDBG (u32 instr ){
920
+ for (size_t i = 0 ; i < seenCMDCount ; i ++ ){
921
+ if (seenCMDs [i ] == instr ){
922
+ return ;
923
+ }
924
+ }
925
+ if (seenCMDSize == 0 ){
926
+ seenCMDs = krealloc (seenCMDs , 1 , GFP_KERNEL );
927
+ seenCMDSize = 1 ;
928
+ }
929
+
930
+ if (seenCMDCount >= seenCMDSize ){
931
+ seenCMDs = krealloc (seenCMDs , seenCMDSize * 2 , GFP_KERNEL );
932
+ seenCMDSize *= 2 ;
933
+ }
934
+
935
+ seenCMDs [seenCMDCount ] = instr ;
936
+ seenCMDCount ++ ;
937
+ printk ("New instruction: %x" , instr );
938
+ }
939
+
879
940
int do_alignment_fixup (unsigned long addr , struct pt_regs * regs ){
880
941
unsigned long long instrptr ;
881
942
u32 instr = 0 ;
@@ -893,6 +954,8 @@ int do_alignment_fixup(unsigned long addr, struct pt_regs *regs){
893
954
*
894
955
*/
895
956
957
+ instrDBG (instr );
958
+
896
959
uint8_t op0 ;
897
960
int r ;
898
961
struct fixupDescription desc = {0 };
0 commit comments