mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 16:16:15 -04:00
soc: qcom: Add module info registration to minidump
Add support for dumping active modules information, in minidump registered region. Change-Id: Id8e81ea7beae425a1a0f68f91a8cf9aa093b8011 Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
This commit is contained in:
parent
831a64e11d
commit
1f4340c001
1 changed files with 119 additions and 6 deletions
|
|
@ -42,6 +42,8 @@
|
|||
#include <asm/ptrace.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_QCOM_DYN_MINIDUMP_STACK
|
||||
|
|
@ -98,6 +100,24 @@ static md_align_offset;
|
|||
static int die_cpu = -1;
|
||||
static struct seq_buf *md_cntxt_seq_buf;
|
||||
#endif
|
||||
|
||||
/* Modules information */
|
||||
#ifdef CONFIG_MODULES
|
||||
#define NUM_MD_MODULES 200
|
||||
|
||||
static struct list_head md_mod_list_head;
|
||||
|
||||
struct md_module_data {
|
||||
struct list_head entry;
|
||||
char name[MODULE_NAME_LEN];
|
||||
void *base;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
static struct seq_buf *md_mod_info_seq_buf;
|
||||
static int mod_curr_count;
|
||||
static DEFINE_SPINLOCK(md_modules_lock);
|
||||
#endif /* CONFIG_MODULES */
|
||||
#endif
|
||||
|
||||
static void __init register_log_buf(void)
|
||||
|
|
@ -889,8 +909,10 @@ static int md_die_context_notify(struct notifier_block *self,
|
|||
if (md_in_oops_handler)
|
||||
return NOTIFY_DONE;
|
||||
md_in_oops_handler = true;
|
||||
if (!md_cntxt_seq_buf)
|
||||
if (!md_cntxt_seq_buf) {
|
||||
md_in_oops_handler = false;
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
die_cpu = raw_smp_processor_id();
|
||||
seq_buf_printf(md_cntxt_seq_buf, "\nDIE CPU : %d\n", die_cpu);
|
||||
md_reg_context_data(args->regs);
|
||||
|
|
@ -904,6 +926,23 @@ static struct notifier_block md_die_context_nb = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static void md_dump_module_data(void)
|
||||
{
|
||||
struct md_module_data *md_mod_data_p;
|
||||
|
||||
if (!md_mod_info_seq_buf)
|
||||
return;
|
||||
seq_buf_printf(md_mod_info_seq_buf, "=== MODULE INFO ===\n");
|
||||
list_for_each_entry(md_mod_data_p, &md_mod_list_head, entry) {
|
||||
seq_buf_printf(md_mod_info_seq_buf,
|
||||
"name: %s, base: %p size: %#x\n",
|
||||
md_mod_data_p->name, md_mod_data_p->base,
|
||||
md_mod_data_p->size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int md_panic_handler(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
|
|
@ -919,6 +958,9 @@ static int md_panic_handler(struct notifier_block *this,
|
|||
dump_rq:
|
||||
#endif
|
||||
md_dump_runqueues();
|
||||
#ifdef CONFIG_MODULES
|
||||
md_dump_module_data();
|
||||
#endif
|
||||
md_in_oops_handler = false;
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
|
@ -944,7 +986,7 @@ static int md_register_minidump_entry(char *name, u64 virt_addr,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void md_register_panic_entries(int num_pages, char *name,
|
||||
static int md_register_panic_entries(int num_pages, char *name,
|
||||
struct seq_buf **global_buf)
|
||||
{
|
||||
char *buf;
|
||||
|
|
@ -953,11 +995,13 @@ static void md_register_panic_entries(int num_pages, char *name,
|
|||
|
||||
buf = kzalloc(num_pages * PAGE_SIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
seq_buf_p = kzalloc(sizeof(*seq_buf_p), GFP_KERNEL);
|
||||
if (!seq_buf_p)
|
||||
if (!seq_buf_p) {
|
||||
ret = -EINVAL;
|
||||
goto err_seq_buf;
|
||||
}
|
||||
|
||||
ret = md_register_minidump_entry(name, (uintptr_t)buf,
|
||||
virt_to_phys(buf),
|
||||
|
|
@ -970,12 +1014,13 @@ static void md_register_panic_entries(int num_pages, char *name,
|
|||
/* Complete registration before populating data */
|
||||
smp_mb();
|
||||
WRITE_ONCE(*global_buf, seq_buf_p);
|
||||
return;
|
||||
return 0;
|
||||
|
||||
err_entry_reg:
|
||||
kfree(seq_buf_p);
|
||||
err_seq_buf:
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void md_register_panic_data(void)
|
||||
|
|
@ -988,7 +1033,71 @@ static void md_register_panic_data(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_MODULES
|
||||
static int md_module_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data)
|
||||
{
|
||||
struct module *mod = data;
|
||||
struct md_module_data *md_mod_data_p;
|
||||
struct md_module_data *md_mod_data_p_next;
|
||||
|
||||
spin_lock(&md_modules_lock);
|
||||
switch (val) {
|
||||
case MODULE_STATE_COMING:
|
||||
if (mod_curr_count >= NUM_MD_MODULES) {
|
||||
spin_unlock(&md_modules_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
md_mod_data_p = kzalloc(sizeof(*md_mod_data_p), GFP_ATOMIC);
|
||||
if (!md_mod_data_p) {
|
||||
spin_unlock(&md_modules_lock);
|
||||
return 0;
|
||||
}
|
||||
strlcpy(md_mod_data_p->name, mod->name,
|
||||
sizeof(md_mod_data_p->name));
|
||||
md_mod_data_p->base = mod->core_layout.base;
|
||||
md_mod_data_p->size = mod->core_layout.size;
|
||||
list_add(&md_mod_data_p->entry, &md_mod_list_head);
|
||||
mod_curr_count++;
|
||||
break;
|
||||
case MODULE_STATE_GOING:
|
||||
list_for_each_entry_safe(md_mod_data_p, md_mod_data_p_next,
|
||||
&md_mod_list_head, entry) {
|
||||
if (!strcmp(md_mod_data_p->name, mod->name)) {
|
||||
list_del(&md_mod_data_p->entry);
|
||||
kfree(md_mod_data_p);
|
||||
mod_curr_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
spin_unlock(&md_modules_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block md_module_nb = {
|
||||
.notifier_call = md_module_notify,
|
||||
};
|
||||
|
||||
static void md_register_module_data(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = register_module_notifier(&md_module_nb);
|
||||
if (ret) {
|
||||
pr_err("Failed to register minidump module notifier\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = md_register_panic_entries(1, "KMODULES",
|
||||
&md_mod_info_seq_buf);
|
||||
if (ret)
|
||||
unregister_module_notifier(&md_module_nb);
|
||||
}
|
||||
#endif /* CONFIG_MODULES */
|
||||
#endif /* CONFIG_QCOM_MINIDUMP_PANIC_DUMP */
|
||||
|
||||
static int __init msm_minidump_log_init(void)
|
||||
{
|
||||
|
|
@ -1004,6 +1113,10 @@ static int __init msm_minidump_log_init(void)
|
|||
md_register_trace_buf();
|
||||
#endif
|
||||
#ifdef CONFIG_QCOM_MINIDUMP_PANIC_DUMP
|
||||
#ifdef CONFIG_MODULES
|
||||
INIT_LIST_HEAD(&md_mod_list_head);
|
||||
md_register_module_data();
|
||||
#endif
|
||||
md_register_panic_data();
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &md_panic_blk);
|
||||
#ifdef CONFIG_QCOM_MINIDUMP_PANIC_CPU_CONTEXT
|
||||
|
|
|
|||
Loading…
Reference in a new issue