// SPDX-License-Identifier: GPL-2.0
/*
 * kdb helper for dumping the ftrace buffer
 *
 * Copyright (C) 2010 Jason Wessel <jason.wessel@windriver.com>
 *
 * ftrace_dump_buf based on ftrace_dump:
 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
 * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
 *
 */
#include <linux/init.h>
#include <linux/kgdb.h>
#include <linux/kdb.h>
#include <linux/ftrace.h>

#include "trace.h"
#include "trace_output.h"

static struct trace_iterator iter;
static struct ring_buffer_iter *buffer_iter[CONFIG_NR_CPUS];

static void ftrace_dump_buf(int skip_entries, long cpu_file)
{
	struct trace_array *tr;
	unsigned int old_userobj;
	int cnt = 0, cpu;

	tr = iter.tr;

	old_userobj = tr->trace_flags;

	/* don't look at user memory in panic mode */
	tr->trace_flags &= ~TRACE_ITER(SYM_USEROBJ);

	kdb_printf("Dumping ftrace buffer:\n");
	if (skip_entries)
		kdb_printf("(skipping %d entries)\n", skip_entries);

	trace_iterator_reset(&iter);
	iter.iter_flags |= TRACE_FILE_LAT_FMT;

	if (cpu_file == RING_BUFFER_ALL_CPUS) {
		for_each_tracing_cpu(cpu) {
			iter.buffer_iter[cpu] =
			ring_buffer_read_start(iter.array_buffer->buffer,
					       cpu, GFP_ATOMIC);
			tracing_iter_reset(&iter, cpu);
		}
	} else {
		iter.cpu_file = cpu_file;
		iter.buffer_iter[cpu_file] =
			ring_buffer_read_start(iter.array_buffer->buffer,
						 cpu_file, GFP_ATOMIC);
		tracing_iter_reset(&iter, cpu_file);
	}

	while (trace_find_next_entry_inc(&iter)) {
		if (!cnt)
			kdb_printf("---------------------------------\n");
		cnt++;

		if (!skip_entries) {
			print_trace_line(&iter);
			trace_printk_seq(&iter.seq);
		} else {
			skip_entries--;
		}

		if (KDB_FLAG(CMD_INTERRUPT))
			goto out;
	}

	if (!cnt)
		kdb_printf("   (ftrace buffer empty)\n");
	else
		kdb_printf("---------------------------------\n");

out:
	tr->trace_flags = old_userobj;

	for_each_tracing_cpu(cpu) {
		if (iter.buffer_iter[cpu]) {
			ring_buffer_read_finish(iter.buffer_iter[cpu]);
			iter.buffer_iter[cpu] = NULL;
		}
	}
}

/*
 * kdb_ftdump - Dump the ftrace log buffer
 */
static int kdb_ftdump(int argc, const char **argv)
{
	int skip_entries = 0;
	long cpu_file;
	int err;
	int cnt;

	if (argc > 2)
		return KDB_ARGCOUNT;

	if (argc && kstrtoint(argv[1], 0, &skip_entries))
		return KDB_BADINT;

	if (argc == 2) {
		err = kstrtol(argv[2], 0, &cpu_file);
		if (err || cpu_file >= NR_CPUS || cpu_file < 0 ||
		    !cpu_online(cpu_file))
			return KDB_BADINT;
	} else {
		cpu_file = RING_BUFFER_ALL_CPUS;
	}

	kdb_trap_printk++;

	trace_init_global_iter(&iter);
	iter.buffer_iter = buffer_iter;

	tracer_tracing_disable(iter.tr);

	/* A negative skip_entries means skip all but the last entries */
	if (skip_entries < 0) {
		if (cpu_file == RING_BUFFER_ALL_CPUS)
			cnt = trace_total_entries(NULL);
		else
			cnt = trace_total_entries_cpu(NULL, cpu_file);
		skip_entries = max(cnt + skip_entries, 0);
	}

	ftrace_dump_buf(skip_entries, cpu_file);

	tracer_tracing_enable(iter.tr);

	kdb_trap_printk--;

	return 0;
}

static kdbtab_t ftdump_cmd = {
	.name = "ftdump",
	.func = kdb_ftdump,
	.usage = "[skip_#entries] [cpu]",
	.help = "Dump ftrace log; -skip dumps last #entries",
	.flags = KDB_ENABLE_ALWAYS_SAFE,
};

static __init int kdb_ftrace_register(void)
{
	kdb_register(&ftdump_cmd);
	return 0;
}

late_initcall(kdb_ftrace_register);
