aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/kernel/module.c b/kernel/module.c
index e7a6e53fc73e..9f8d23d8b3a8 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -415,6 +415,40 @@ static void percpu_modcopy(struct module *mod,
415 memcpy(per_cpu_ptr(mod->percpu, cpu), from, size); 415 memcpy(per_cpu_ptr(mod->percpu, cpu), from, size);
416} 416}
417 417
418/**
419 * is_module_percpu_address - test whether address is from module static percpu
420 * @addr: address to test
421 *
422 * Test whether @addr belongs to module static percpu area.
423 *
424 * RETURNS:
425 * %true if @addr is from module static percpu area
426 */
427bool is_module_percpu_address(unsigned long addr)
428{
429 struct module *mod;
430 unsigned int cpu;
431
432 preempt_disable();
433
434 list_for_each_entry_rcu(mod, &modules, list) {
435 if (!mod->percpu_size)
436 continue;
437 for_each_possible_cpu(cpu) {
438 void *start = per_cpu_ptr(mod->percpu, cpu);
439
440 if ((void *)addr >= start &&
441 (void *)addr < start + mod->percpu_size) {
442 preempt_enable();
443 return true;
444 }
445 }
446 }
447
448 preempt_enable();
449 return false;
450}
451
418#else /* ... !CONFIG_SMP */ 452#else /* ... !CONFIG_SMP */
419 453
420static inline void __percpu *mod_percpu(struct module *mod) 454static inline void __percpu *mod_percpu(struct module *mod)
@@ -441,6 +475,10 @@ static inline void percpu_modcopy(struct module *mod,
441 /* pcpusec should be 0, and size of that section should be 0. */ 475 /* pcpusec should be 0, and size of that section should be 0. */
442 BUG_ON(size != 0); 476 BUG_ON(size != 0);
443} 477}
478bool is_module_percpu_address(unsigned long addr)
479{
480 return false;
481}
444 482
445#endif /* CONFIG_SMP */ 483#endif /* CONFIG_SMP */
446 484