49
49
#include <linux/fsnotify.h>
50
50
#include <linux/irq_work.h>
51
51
#include <linux/workqueue.h>
52
+ #include <linux/sort.h>
52
53
53
54
#include <asm/setup.h> /* COMMAND_LINE_SIZE and kaslr_offset() */
54
55
@@ -6001,6 +6002,59 @@ struct trace_scratch {
6001
6002
6002
6003
static DEFINE_MUTEX (scratch_mutex );
6003
6004
6005
+ static int cmp_mod_entry (const void * key , const void * pivot )
6006
+ {
6007
+ unsigned long addr = (unsigned long )key ;
6008
+ const struct trace_mod_entry * ent = pivot ;
6009
+
6010
+ if (addr >= ent [0 ].mod_addr && addr < ent [1 ].mod_addr )
6011
+ return 0 ;
6012
+ else
6013
+ return addr - ent -> mod_addr ;
6014
+ }
6015
+
6016
+ /**
6017
+ * trace_adjust_address() - Adjust prev boot address to current address.
6018
+ * @tr: Persistent ring buffer's trace_array.
6019
+ * @addr: Address in @tr which is adjusted.
6020
+ */
6021
+ unsigned long trace_adjust_address (struct trace_array * tr , unsigned long addr )
6022
+ {
6023
+ struct trace_module_delta * module_delta ;
6024
+ struct trace_scratch * tscratch ;
6025
+ struct trace_mod_entry * entry ;
6026
+ int idx = 0 , nr_entries ;
6027
+
6028
+ /* If we don't have last boot delta, return the address */
6029
+ if (!(tr -> flags & TRACE_ARRAY_FL_LAST_BOOT ))
6030
+ return addr ;
6031
+
6032
+ /* tr->module_delta must be protected by rcu. */
6033
+ guard (rcu )();
6034
+ tscratch = tr -> scratch ;
6035
+ /* if there is no tscrach, module_delta must be NULL. */
6036
+ module_delta = READ_ONCE (tr -> module_delta );
6037
+ if (!module_delta || tscratch -> entries [0 ].mod_addr > addr )
6038
+ return addr + tr -> text_delta ;
6039
+
6040
+ /* Note that entries must be sorted. */
6041
+ nr_entries = tscratch -> nr_entries ;
6042
+ if (nr_entries == 1 ||
6043
+ tscratch -> entries [nr_entries - 1 ].mod_addr < addr )
6044
+ idx = nr_entries - 1 ;
6045
+ else {
6046
+ entry = __inline_bsearch ((void * )addr ,
6047
+ tscratch -> entries ,
6048
+ nr_entries - 1 ,
6049
+ sizeof (tscratch -> entries [0 ]),
6050
+ cmp_mod_entry );
6051
+ if (entry )
6052
+ idx = entry - tscratch -> entries ;
6053
+ }
6054
+
6055
+ return addr + module_delta -> delta [idx ];
6056
+ }
6057
+
6004
6058
#ifdef CONFIG_MODULES
6005
6059
static int save_mod (struct module * mod , void * data )
6006
6060
{
@@ -6035,6 +6089,7 @@ static int save_mod(struct module *mod, void *data)
6035
6089
6036
6090
static void update_last_data (struct trace_array * tr )
6037
6091
{
6092
+ struct trace_module_delta * module_delta ;
6038
6093
struct trace_scratch * tscratch ;
6039
6094
6040
6095
if (!(tr -> flags & TRACE_ARRAY_FL_BOOT ))
@@ -6073,6 +6128,9 @@ static void update_last_data(struct trace_array *tr)
6073
6128
return ;
6074
6129
6075
6130
tscratch = tr -> scratch ;
6131
+ module_delta = READ_ONCE (tr -> module_delta );
6132
+ WRITE_ONCE (tr -> module_delta , NULL );
6133
+ kfree_rcu (module_delta , rcu );
6076
6134
6077
6135
/* Set the persistent ring buffer meta data to this address */
6078
6136
#ifdef CONFIG_RANDOMIZE_BASE
@@ -9355,10 +9413,51 @@ static struct dentry *trace_instance_dir;
9355
9413
static void
9356
9414
init_tracer_tracefs (struct trace_array * tr , struct dentry * d_tracer );
9357
9415
9416
+ #ifdef CONFIG_MODULES
9417
+ static int make_mod_delta (struct module * mod , void * data )
9418
+ {
9419
+ struct trace_module_delta * module_delta ;
9420
+ struct trace_scratch * tscratch ;
9421
+ struct trace_mod_entry * entry ;
9422
+ struct trace_array * tr = data ;
9423
+ int i ;
9424
+
9425
+ tscratch = tr -> scratch ;
9426
+ module_delta = READ_ONCE (tr -> module_delta );
9427
+ for (i = 0 ; i < tscratch -> nr_entries ; i ++ ) {
9428
+ entry = & tscratch -> entries [i ];
9429
+ if (strcmp (mod -> name , entry -> mod_name ))
9430
+ continue ;
9431
+ if (mod -> state == MODULE_STATE_GOING )
9432
+ module_delta -> delta [i ] = 0 ;
9433
+ else
9434
+ module_delta -> delta [i ] = (unsigned long )mod -> mem [MOD_TEXT ].base
9435
+ - entry -> mod_addr ;
9436
+ break ;
9437
+ }
9438
+ return 0 ;
9439
+ }
9440
+ #else
9441
+ static int make_mod_delta (struct module * mod , void * data )
9442
+ {
9443
+ return 0 ;
9444
+ }
9445
+ #endif
9446
+
9447
+ static int mod_addr_comp (const void * a , const void * b , const void * data )
9448
+ {
9449
+ const struct trace_mod_entry * e1 = a ;
9450
+ const struct trace_mod_entry * e2 = b ;
9451
+
9452
+ return e1 -> mod_addr > e2 -> mod_addr ? 1 : -1 ;
9453
+ }
9454
+
9358
9455
static void setup_trace_scratch (struct trace_array * tr ,
9359
9456
struct trace_scratch * tscratch , unsigned int size )
9360
9457
{
9458
+ struct trace_module_delta * module_delta ;
9361
9459
struct trace_mod_entry * entry ;
9460
+ int i , nr_entries ;
9362
9461
9363
9462
if (!tscratch )
9364
9463
return ;
@@ -9375,7 +9474,7 @@ static void setup_trace_scratch(struct trace_array *tr,
9375
9474
goto reset ;
9376
9475
9377
9476
/* Check if each module name is a valid string */
9378
- for (int i = 0 ; i < tscratch -> nr_entries ; i ++ ) {
9477
+ for (i = 0 ; i < tscratch -> nr_entries ; i ++ ) {
9379
9478
int n ;
9380
9479
9381
9480
entry = & tscratch -> entries [i ];
@@ -9389,6 +9488,25 @@ static void setup_trace_scratch(struct trace_array *tr,
9389
9488
if (n == MODULE_NAME_LEN )
9390
9489
goto reset ;
9391
9490
}
9491
+
9492
+ /* Sort the entries so that we can find appropriate module from address. */
9493
+ nr_entries = tscratch -> nr_entries ;
9494
+ sort_r (tscratch -> entries , nr_entries , sizeof (struct trace_mod_entry ),
9495
+ mod_addr_comp , NULL , NULL );
9496
+
9497
+ if (IS_ENABLED (CONFIG_MODULES )) {
9498
+ module_delta = kzalloc (struct_size (module_delta , delta , nr_entries ), GFP_KERNEL );
9499
+ if (!module_delta ) {
9500
+ pr_info ("module_delta allocation failed. Not able to decode module address." );
9501
+ goto reset ;
9502
+ }
9503
+ init_rcu_head (& module_delta -> rcu );
9504
+ } else
9505
+ module_delta = NULL ;
9506
+ WRITE_ONCE (tr -> module_delta , module_delta );
9507
+
9508
+ /* Scan modules to make text delta for modules. */
9509
+ module_for_each_mod (make_mod_delta , tr );
9392
9510
return ;
9393
9511
reset :
9394
9512
/* Invalid trace modules */
@@ -10105,16 +10223,20 @@ static void trace_module_remove_evals(struct module *mod)
10105
10223
static inline void trace_module_remove_evals (struct module * mod ) { }
10106
10224
#endif /* CONFIG_TRACE_EVAL_MAP_FILE */
10107
10225
10108
- static void trace_module_record (struct module * mod )
10226
+ static void trace_module_record (struct module * mod , bool add )
10109
10227
{
10110
10228
struct trace_array * tr ;
10229
+ unsigned long flags ;
10111
10230
10112
10231
list_for_each_entry (tr , & ftrace_trace_arrays , list ) {
10232
+ flags = tr -> flags & (TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT );
10113
10233
/* Update any persistent trace array that has already been started */
10114
- if ((tr -> flags & (TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT )) ==
10115
- TRACE_ARRAY_FL_BOOT ) {
10234
+ if (flags == TRACE_ARRAY_FL_BOOT && add ) {
10116
10235
guard (mutex )(& scratch_mutex );
10117
10236
save_mod (mod , tr );
10237
+ } else if (flags & TRACE_ARRAY_FL_LAST_BOOT ) {
10238
+ /* Update delta if the module loaded in previous boot */
10239
+ make_mod_delta (mod , tr );
10118
10240
}
10119
10241
}
10120
10242
}
@@ -10127,10 +10249,11 @@ static int trace_module_notify(struct notifier_block *self,
10127
10249
switch (val ) {
10128
10250
case MODULE_STATE_COMING :
10129
10251
trace_module_add_evals (mod );
10130
- trace_module_record (mod );
10252
+ trace_module_record (mod , true );
10131
10253
break ;
10132
10254
case MODULE_STATE_GOING :
10133
10255
trace_module_remove_evals (mod );
10256
+ trace_module_record (mod , false);
10134
10257
break ;
10135
10258
}
10136
10259
0 commit comments