With "BloodTest: perf", we can get the address of kernel from "cpu0/page" without symbol. The application that call BloodTest need translate the address to symbol with itself. For normal address, just vmlinux is OK to get the right symbol. But for the address of kernel module, it also need the address of modules from /proc/modules.
Add /proc/modules_update_version will help the application to get if the kernel modules address is changed or not. Signed-off-by: Hui Zhu <zhu...@xiaomi.com> --- kernel/module.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index de66ec8..ed6f370 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -317,6 +317,8 @@ struct load_info { } index; }; +static atomic_t modules_update_version = ATOMIC_INIT(0); + /* * We require a truly strong try_module_get(): 0 means success. * Otherwise an error is returned due to ongoing or failed @@ -1020,6 +1022,9 @@ int module_refcount(struct module *mod) strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); free_module(mod); + + atomic_inc(&modules_update_version); + return 0; out: mutex_unlock(&module_mutex); @@ -3183,6 +3188,8 @@ static int move_module(struct module *mod, struct load_info *info) (long)shdr->sh_addr, info->secstrings + shdr->sh_name); } + atomic_inc(&modules_update_version); + return 0; } @@ -4196,9 +4203,21 @@ static int modules_open(struct inode *inode, struct file *file) .release = seq_release, }; +static int modules_update_version_get(void *data, u64 *val) +{ + *val = (u64)atomic_read(&modules_update_version); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(proc_modules_update_version_operations, + modules_update_version_get, NULL, "%llu\n"); + static int __init proc_modules_init(void) { proc_create("modules", 0, NULL, &proc_modules_operations); + proc_create("modules_update_version", 0, NULL, + &proc_modules_update_version_operations); return 0; } module_init(proc_modules_init); -- 1.9.1