@@ -1113,10 +1113,13 @@ void text_poke_sync(void)
11131113}
11141114
11151115struct text_poke_loc {
1116- s32 rel_addr ; /* addr := _stext + rel_addr */
1117- s32 rel32 ;
1116+ /* addr := _stext + rel_addr */
1117+ s32 rel_addr ;
1118+ s32 disp ;
1119+ u8 len ;
11181120 u8 opcode ;
11191121 const u8 text [POKE_MAX_OPCODE_SIZE ];
1122+ /* see text_poke_bp_batch() */
11201123 u8 old ;
11211124};
11221125
@@ -1131,7 +1134,8 @@ static struct bp_patching_desc *bp_desc;
11311134static __always_inline
11321135struct bp_patching_desc * try_get_desc (struct bp_patching_desc * * descp )
11331136{
1134- struct bp_patching_desc * desc = __READ_ONCE (* descp ); /* rcu_dereference */
1137+ /* rcu_dereference */
1138+ struct bp_patching_desc * desc = __READ_ONCE (* descp );
11351139
11361140 if (!desc || !arch_atomic_inc_not_zero (& desc -> refs ))
11371141 return NULL ;
@@ -1165,7 +1169,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
11651169{
11661170 struct bp_patching_desc * desc ;
11671171 struct text_poke_loc * tp ;
1168- int len , ret = 0 ;
1172+ int ret = 0 ;
11691173 void * ip ;
11701174
11711175 if (user_mode (regs ))
@@ -1205,8 +1209,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
12051209 goto out_put ;
12061210 }
12071211
1208- len = text_opcode_size (tp -> opcode );
1209- ip += len ;
1212+ ip += tp -> len ;
12101213
12111214 switch (tp -> opcode ) {
12121215 case INT3_INSN_OPCODE :
@@ -1221,12 +1224,12 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
12211224 break ;
12221225
12231226 case CALL_INSN_OPCODE :
1224- int3_emulate_call (regs , (long )ip + tp -> rel32 );
1227+ int3_emulate_call (regs , (long )ip + tp -> disp );
12251228 break ;
12261229
12271230 case JMP32_INSN_OPCODE :
12281231 case JMP8_INSN_OPCODE :
1229- int3_emulate_jmp (regs , (long )ip + tp -> rel32 );
1232+ int3_emulate_jmp (regs , (long )ip + tp -> disp );
12301233 break ;
12311234
12321235 default :
@@ -1301,7 +1304,7 @@ static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries
13011304 */
13021305 for (do_sync = 0 , i = 0 ; i < nr_entries ; i ++ ) {
13031306 u8 old [POKE_MAX_OPCODE_SIZE ] = { tp [i ].old , };
1304- int len = text_opcode_size ( tp [i ].opcode ) ;
1307+ int len = tp [i ].len ;
13051308
13061309 if (len - INT3_INSN_SIZE > 0 ) {
13071310 memcpy (old + INT3_INSN_SIZE ,
@@ -1378,20 +1381,36 @@ static void text_poke_loc_init(struct text_poke_loc *tp, void *addr,
13781381 const void * opcode , size_t len , const void * emulate )
13791382{
13801383 struct insn insn ;
1381- int ret ;
1384+ int ret , i ;
13821385
13831386 memcpy ((void * )tp -> text , opcode , len );
13841387 if (!emulate )
13851388 emulate = opcode ;
13861389
13871390 ret = insn_decode_kernel (& insn , emulate );
1388-
13891391 BUG_ON (ret < 0 );
1390- BUG_ON (len != insn .length );
13911392
13921393 tp -> rel_addr = addr - (void * )_stext ;
1394+ tp -> len = len ;
13931395 tp -> opcode = insn .opcode .bytes [0 ];
13941396
1397+ switch (tp -> opcode ) {
1398+ case RET_INSN_OPCODE :
1399+ case JMP32_INSN_OPCODE :
1400+ case JMP8_INSN_OPCODE :
1401+ /*
1402+ * Control flow instructions without implied execution of the
1403+ * next instruction can be padded with INT3.
1404+ */
1405+ for (i = insn .length ; i < len ; i ++ )
1406+ BUG_ON (tp -> text [i ] != INT3_INSN_OPCODE );
1407+ break ;
1408+
1409+ default :
1410+ BUG_ON (len != insn .length );
1411+ };
1412+
1413+
13951414 switch (tp -> opcode ) {
13961415 case INT3_INSN_OPCODE :
13971416 case RET_INSN_OPCODE :
@@ -1400,21 +1419,21 @@ static void text_poke_loc_init(struct text_poke_loc *tp, void *addr,
14001419 case CALL_INSN_OPCODE :
14011420 case JMP32_INSN_OPCODE :
14021421 case JMP8_INSN_OPCODE :
1403- tp -> rel32 = insn .immediate .value ;
1422+ tp -> disp = insn .immediate .value ;
14041423 break ;
14051424
14061425 default : /* assume NOP */
14071426 switch (len ) {
14081427 case 2 : /* NOP2 -- emulate as JMP8+0 */
14091428 BUG_ON (memcmp (emulate , x86_nops [len ], len ));
14101429 tp -> opcode = JMP8_INSN_OPCODE ;
1411- tp -> rel32 = 0 ;
1430+ tp -> disp = 0 ;
14121431 break ;
14131432
14141433 case 5 : /* NOP5 -- emulate as JMP32+0 */
14151434 BUG_ON (memcmp (emulate , x86_nops [len ], len ));
14161435 tp -> opcode = JMP32_INSN_OPCODE ;
1417- tp -> rel32 = 0 ;
1436+ tp -> disp = 0 ;
14181437 break ;
14191438
14201439 default : /* unknown instruction */
0 commit comments