blob: 5b336a84bb596938c2ed4bf9da8e03737969c12f [file] [log] [blame]
/*
* Copyright (c) 2020 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Samsung TN debugging code
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/smp.h>
#include <linux/sched.h>
#include <linux/sec_debug.h>
#include <linux/stacktrace.h>
#include <linux/debug-snapshot.h>
#include <asm/stack_pointer.h>
#include <asm/stacktrace.h>
#include <linux/sched/debug.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include "../../../kernel/sched/sched.h"
#include <linux/sched/signal.h>
static call_single_data_t csd;
static struct task_struct *suspect;
static inline char get_state(struct task_struct *p)
{
char state_array[] = {'R', 'S', 'D', 'T', 't', 'X', 'Z', 'P', 'x', 'K', 'W', 'I', 'N'};
unsigned char idx = 0;
unsigned long state;
if (!p)
return 0;
state = (p->state | p->exit_state) & (TASK_STATE_MAX - 1);
while (state) {
idx++;
state >>= 1;
}
return state_array[idx];
}
static void show_callstack(void *dummy)
{
#ifdef CONFIG_SEC_DEBUG_AUTO_COMMENT
show_stack_auto_comment(NULL, NULL);
#else
show_stack(NULL, NULL);
#endif
}
static struct task_struct *secdbg_softdog_find_key_suspect(void)
{
struct task_struct *c, *g;
for_each_process(g) {
if (g->pid == 1)
suspect = g;
else if (!strcmp(g->comm, "system_server")) {
suspect = g;
for_each_thread(g, c) {
if (!strcmp(c->comm, "watchdog")) {
suspect = c;
goto out;
}
}
goto out;
}
}
out:
return suspect;
}
void secdbg_softdog_show_info(void)
{
struct task_struct *p = NULL;
p = secdbg_softdog_find_key_suspect();
if (p) {
pr_auto(ASL5, "[SOFTDOG] %s:%d %c(%d) exec:%lluns\n",
p->comm, p->pid, get_state(p), (int)p->state, p->se.exec_start);
if (task_running(task_rq(p), p)) {
csd.flags = 0;
csd.func = show_callstack;
csd.info = 0;
smp_call_function_single_async(task_cpu(p), &csd);
} else {
#ifdef CONFIG_SEC_DEBUG_AUTO_COMMENT
show_stack_auto_comment(p, NULL);
#else
show_stack(p, NULL);
#endif
}
} else {
pr_auto(ASL5, "[SOFTDOG] Init task not exist!\n");
}
}