@@ -1113,10 +1113,13 @@ void text_poke_sync(void)
1113
1113
}
1114
1114
1115
1115
struct 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 ;
1118
1120
u8 opcode ;
1119
1121
const u8 text [POKE_MAX_OPCODE_SIZE ];
1122
+ /* see text_poke_bp_batch() */
1120
1123
u8 old ;
1121
1124
};
1122
1125
@@ -1131,7 +1134,8 @@ static struct bp_patching_desc *bp_desc;
1131
1134
static __always_inline
1132
1135
struct bp_patching_desc * try_get_desc (struct bp_patching_desc * * descp )
1133
1136
{
1134
- struct bp_patching_desc * desc = __READ_ONCE (* descp ); /* rcu_dereference */
1137
+ /* rcu_dereference */
1138
+ struct bp_patching_desc * desc = __READ_ONCE (* descp );
1135
1139
1136
1140
if (!desc || !arch_atomic_inc_not_zero (& desc -> refs ))
1137
1141
return NULL ;
@@ -1165,7 +1169,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
1165
1169
{
1166
1170
struct bp_patching_desc * desc ;
1167
1171
struct text_poke_loc * tp ;
1168
- int len , ret = 0 ;
1172
+ int ret = 0 ;
1169
1173
void * ip ;
1170
1174
1171
1175
if (user_mode (regs ))
@@ -1205,8 +1209,7 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
1205
1209
goto out_put ;
1206
1210
}
1207
1211
1208
- len = text_opcode_size (tp -> opcode );
1209
- ip += len ;
1212
+ ip += tp -> len ;
1210
1213
1211
1214
switch (tp -> opcode ) {
1212
1215
case INT3_INSN_OPCODE :
@@ -1221,12 +1224,12 @@ noinstr int poke_int3_handler(struct pt_regs *regs)
1221
1224
break ;
1222
1225
1223
1226
case CALL_INSN_OPCODE :
1224
- int3_emulate_call (regs , (long )ip + tp -> rel32 );
1227
+ int3_emulate_call (regs , (long )ip + tp -> disp );
1225
1228
break ;
1226
1229
1227
1230
case JMP32_INSN_OPCODE :
1228
1231
case JMP8_INSN_OPCODE :
1229
- int3_emulate_jmp (regs , (long )ip + tp -> rel32 );
1232
+ int3_emulate_jmp (regs , (long )ip + tp -> disp );
1230
1233
break ;
1231
1234
1232
1235
default :
@@ -1301,7 +1304,7 @@ static void text_poke_bp_batch(struct text_poke_loc *tp, unsigned int nr_entries
1301
1304
*/
1302
1305
for (do_sync = 0 , i = 0 ; i < nr_entries ; i ++ ) {
1303
1306
u8 old [POKE_MAX_OPCODE_SIZE ] = { tp [i ].old , };
1304
- int len = text_opcode_size ( tp [i ].opcode ) ;
1307
+ int len = tp [i ].len ;
1305
1308
1306
1309
if (len - INT3_INSN_SIZE > 0 ) {
1307
1310
memcpy (old + INT3_INSN_SIZE ,
@@ -1378,20 +1381,36 @@ static void text_poke_loc_init(struct text_poke_loc *tp, void *addr,
1378
1381
const void * opcode , size_t len , const void * emulate )
1379
1382
{
1380
1383
struct insn insn ;
1381
- int ret ;
1384
+ int ret , i ;
1382
1385
1383
1386
memcpy ((void * )tp -> text , opcode , len );
1384
1387
if (!emulate )
1385
1388
emulate = opcode ;
1386
1389
1387
1390
ret = insn_decode_kernel (& insn , emulate );
1388
-
1389
1391
BUG_ON (ret < 0 );
1390
- BUG_ON (len != insn .length );
1391
1392
1392
1393
tp -> rel_addr = addr - (void * )_stext ;
1394
+ tp -> len = len ;
1393
1395
tp -> opcode = insn .opcode .bytes [0 ];
1394
1396
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
+
1395
1414
switch (tp -> opcode ) {
1396
1415
case INT3_INSN_OPCODE :
1397
1416
case RET_INSN_OPCODE :
@@ -1400,21 +1419,21 @@ static void text_poke_loc_init(struct text_poke_loc *tp, void *addr,
1400
1419
case CALL_INSN_OPCODE :
1401
1420
case JMP32_INSN_OPCODE :
1402
1421
case JMP8_INSN_OPCODE :
1403
- tp -> rel32 = insn .immediate .value ;
1422
+ tp -> disp = insn .immediate .value ;
1404
1423
break ;
1405
1424
1406
1425
default : /* assume NOP */
1407
1426
switch (len ) {
1408
1427
case 2 : /* NOP2 -- emulate as JMP8+0 */
1409
1428
BUG_ON (memcmp (emulate , x86_nops [len ], len ));
1410
1429
tp -> opcode = JMP8_INSN_OPCODE ;
1411
- tp -> rel32 = 0 ;
1430
+ tp -> disp = 0 ;
1412
1431
break ;
1413
1432
1414
1433
case 5 : /* NOP5 -- emulate as JMP32+0 */
1415
1434
BUG_ON (memcmp (emulate , x86_nops [len ], len ));
1416
1435
tp -> opcode = JMP32_INSN_OPCODE ;
1417
- tp -> rel32 = 0 ;
1436
+ tp -> disp = 0 ;
1418
1437
break ;
1419
1438
1420
1439
default : /* unknown instruction */
0 commit comments