@@ -171,14 +171,17 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
171171 Elf_Shdr * symsec = & info -> sechdrs [info -> index .sym ];
172172
173173 /* Set up to point into init section. */
174- mod -> kallsyms = mod -> init_layout .base + info -> mod_kallsyms_init_off ;
174+ mod -> kallsyms = (void __rcu * )mod -> init_layout .base +
175+ info -> mod_kallsyms_init_off ;
175176
177+ preempt_disable ();
176178 /* The following is safe since this pointer cannot change */
177- mod -> kallsyms -> symtab = (void * )symsec -> sh_addr ;
178- mod -> kallsyms -> num_symtab = symsec -> sh_size / sizeof (Elf_Sym );
179+ rcu_dereference_sched ( mod -> kallsyms ) -> symtab = (void * )symsec -> sh_addr ;
180+ rcu_dereference_sched ( mod -> kallsyms ) -> num_symtab = symsec -> sh_size / sizeof (Elf_Sym );
179181 /* Make sure we get permanent strtab: don't use info->strtab. */
180- mod -> kallsyms -> strtab = (void * )info -> sechdrs [info -> index .str ].sh_addr ;
181- mod -> kallsyms -> typetab = mod -> init_layout .base + info -> init_typeoffs ;
182+ rcu_dereference_sched (mod -> kallsyms )-> strtab =
183+ (void * )info -> sechdrs [info -> index .str ].sh_addr ;
184+ rcu_dereference_sched (mod -> kallsyms )-> typetab = mod -> init_layout .base + info -> init_typeoffs ;
182185
183186 /*
184187 * Now populate the cut down core kallsyms for after init
@@ -187,20 +190,22 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
187190 mod -> core_kallsyms .symtab = dst = mod -> core_layout .base + info -> symoffs ;
188191 mod -> core_kallsyms .strtab = s = mod -> core_layout .base + info -> stroffs ;
189192 mod -> core_kallsyms .typetab = mod -> core_layout .base + info -> core_typeoffs ;
190- src = mod -> kallsyms -> symtab ;
191- for (ndst = i = 0 ; i < mod -> kallsyms -> num_symtab ; i ++ ) {
192- mod -> kallsyms -> typetab [i ] = elf_type (src + i , info );
193+ src = rcu_dereference_sched ( mod -> kallsyms ) -> symtab ;
194+ for (ndst = i = 0 ; i < rcu_dereference_sched ( mod -> kallsyms ) -> num_symtab ; i ++ ) {
195+ rcu_dereference_sched ( mod -> kallsyms ) -> typetab [i ] = elf_type (src + i , info );
193196 if (i == 0 || is_livepatch_module (mod ) ||
194197 is_core_symbol (src + i , info -> sechdrs , info -> hdr -> e_shnum ,
195198 info -> index .pcpu )) {
196199 mod -> core_kallsyms .typetab [ndst ] =
197- mod -> kallsyms -> typetab [i ];
200+ rcu_dereference_sched ( mod -> kallsyms ) -> typetab [i ];
198201 dst [ndst ] = src [i ];
199202 dst [ndst ++ ].st_name = s - mod -> core_kallsyms .strtab ;
200- s += strscpy (s , & mod -> kallsyms -> strtab [src [i ].st_name ],
203+ s += strscpy (s ,
204+ & rcu_dereference_sched (mod -> kallsyms )-> strtab [src [i ].st_name ],
201205 KSYM_NAME_LEN ) + 1 ;
202206 }
203207 }
208+ preempt_enable ();
204209 mod -> core_kallsyms .num_symtab = ndst ;
205210}
206211
@@ -478,11 +483,16 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
478483
479484 mutex_lock (& module_mutex );
480485 list_for_each_entry (mod , & modules , list ) {
481- /* We hold module_mutex: no need for rcu_dereference_sched */
482- struct mod_kallsyms * kallsyms = mod -> kallsyms ;
486+ struct mod_kallsyms * kallsyms ;
483487
484488 if (mod -> state == MODULE_STATE_UNFORMED )
485489 continue ;
490+
491+ /* Use rcu_dereference_sched() to remain compliant with the sparse tool */
492+ preempt_disable ();
493+ kallsyms = rcu_dereference_sched (mod -> kallsyms );
494+ preempt_enable ();
495+
486496 for (i = 0 ; i < kallsyms -> num_symtab ; i ++ ) {
487497 const Elf_Sym * sym = & kallsyms -> symtab [i ];
488498
0 commit comments