Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2012  Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/ftrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/barrier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /* This doesn't need to be atomic: speed is chosen over correctness here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static u64 pstore_ftrace_stamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static void notrace pstore_ftrace_call(unsigned long ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 				       unsigned long parent_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 				       struct ftrace_ops *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 				       struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct pstore_ftrace_record rec = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct pstore_record record = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		.type = PSTORE_TYPE_FTRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		.buf = (char *)&rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		.size = sizeof(rec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		.psi = psinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (unlikely(oops_in_progress))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	rec.ip = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	rec.parent_ip = parent_ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	pstore_ftrace_write_timestamp(&rec, pstore_ftrace_stamp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	psinfo->write(&record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	.func	= pstore_ftrace_call,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static DEFINE_MUTEX(pstore_ftrace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static bool pstore_ftrace_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 					size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	u8 on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	ret = kstrtou8_from_user(buf, count, 2, &on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	mutex_lock(&pstore_ftrace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	if (!on ^ pstore_ftrace_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		ftrace_ops_set_global_filter(&pstore_ftrace_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		ret = register_ftrace_function(&pstore_ftrace_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		ret = unregister_ftrace_function(&pstore_ftrace_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		pr_err("%s: unable to %sregister ftrace ops: %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		       __func__, on ? "" : "un", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	pstore_ftrace_enabled = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	mutex_unlock(&pstore_ftrace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static ssize_t pstore_ftrace_knob_read(struct file *f, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	char val[] = { '0' + pstore_ftrace_enabled, '\n' };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return simple_read_from_buffer(buf, count, ppos, val, sizeof(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static const struct file_operations pstore_knob_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	.open	= simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.read	= pstore_ftrace_knob_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.write	= pstore_ftrace_knob_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static struct dentry *pstore_ftrace_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) void pstore_register_ftrace(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (!psinfo->write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	pstore_ftrace_dir = debugfs_create_dir("pstore", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	debugfs_create_file("record_ftrace", 0600, pstore_ftrace_dir, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			    &pstore_knob_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void pstore_unregister_ftrace(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	mutex_lock(&pstore_ftrace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	if (pstore_ftrace_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		unregister_ftrace_function(&pstore_ftrace_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		pstore_ftrace_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	mutex_unlock(&pstore_ftrace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	debugfs_remove_recursive(pstore_ftrace_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ssize_t pstore_ftrace_combine_log(char **dest_log, size_t *dest_log_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				  const char *src_log, size_t src_log_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	size_t dest_size, src_size, total, dest_off, src_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	size_t dest_idx = 0, src_idx = 0, merged_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	void *merged_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct pstore_ftrace_record *drec, *srec, *mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	size_t record_size = sizeof(struct pstore_ftrace_record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	dest_off = *dest_log_size % record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	dest_size = *dest_log_size - dest_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	src_off = src_log_size % record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	src_size = src_log_size - src_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	total = dest_size + src_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	merged_buf = kmalloc(total, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (!merged_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	drec = (struct pstore_ftrace_record *)(*dest_log + dest_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	srec = (struct pstore_ftrace_record *)(src_log + src_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	mrec = (struct pstore_ftrace_record *)(merged_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	while (dest_size > 0 && src_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		if (pstore_ftrace_read_timestamp(&drec[dest_idx]) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		    pstore_ftrace_read_timestamp(&srec[src_idx])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			mrec[merged_idx++] = drec[dest_idx++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			dest_size -= record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			mrec[merged_idx++] = srec[src_idx++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			src_size -= record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	while (dest_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		mrec[merged_idx++] = drec[dest_idx++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		dest_size -= record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	while (src_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		mrec[merged_idx++] = srec[src_idx++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		src_size -= record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	kfree(*dest_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	*dest_log = merged_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	*dest_log_size = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) EXPORT_SYMBOL_GPL(pstore_ftrace_combine_log);