Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52281b38 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull pstore updates from Kees Cook:
 "Improvements and fixes to pstore subsystem:

   - add additional checks for bad platform data

   - remove bounce buffer in console writer

   - protect read/unlink race with a mutex

   - correctly give up during dump locking failures

   - increase ftrace bandwidth by splitting ftrace buffers per CPU"

* tag 'pstore-v4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  ramoops: add pdata NULL check to ramoops_probe
  pstore: Convert console write to use ->write_buf
  pstore: Protect unlink with read_mutex
  pstore: Use global ftrace filters for function trace filtering
  ftrace: Provide API to use global filtering for ftrace ops
  pstore: Clarify context field przs as dprzs
  pstore: improve error report for failed setup
  pstore: Merge per-CPU ftrace records into one
  pstore: Add ftrace timestamp counter
  ramoops: Split ftrace buffer space into per-CPU zones
  pstore: Make ramoops_init_przs generic for other prz arrays
  pstore: Allow prz to control need for locking
  pstore: Warn on PSTORE_TYPE_PMSG using deprecated function
  pstore: Make spinlock per zone instead of global
  pstore: Actually give up during locking failure
parents daf34710 fc46d4e4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -46,3 +46,6 @@ Optional properties:
  (defaults to buffered mappings)

- no-dump-oops: if present, only dump panics (defaults to panics and oops)

- flags: if present, pass ramoops behavioral flags (defaults to 0,
  see include/linux/pstore_ram.h RAMOOPS_FLAG_* for flag values).
+9 −2
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@
#include <asm/barrier.h>
#include "internal.h"

/* This doesn't need to be atomic: speed is chosen over correctness here. */
static u64 pstore_ftrace_stamp;

static void notrace pstore_ftrace_call(unsigned long ip,
				       unsigned long parent_ip,
				       struct ftrace_ops *op,
@@ -42,6 +45,7 @@ static void notrace pstore_ftrace_call(unsigned long ip,

	rec.ip = ip;
	rec.parent_ip = parent_ip;
	pstore_ftrace_write_timestamp(&rec, pstore_ftrace_stamp++);
	pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id());
	psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)&rec,
			  0, sizeof(rec), psinfo);
@@ -71,10 +75,13 @@ static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
	if (!on ^ pstore_ftrace_enabled)
		goto out;

	if (on)
	if (on) {
		ftrace_ops_set_global_filter(&pstore_ftrace_ops);
		ret = register_ftrace_function(&pstore_ftrace_ops);
	else
	} else {
		ret = unregister_ftrace_function(&pstore_ftrace_ops);
	}

	if (ret) {
		pr_err("%s: unable to %sregister ftrace ops: %zd\n",
		       __func__, on ? "" : "un", ret);
+10 −5
Original line number Diff line number Diff line
@@ -107,9 +107,11 @@ static int pstore_ftrace_seq_show(struct seq_file *s, void *v)
	struct pstore_ftrace_seq_data *data = v;
	struct pstore_ftrace_record *rec = (void *)(ps->data + data->off);

	seq_printf(s, "%d %08lx  %08lx  %pf <- %pF\n",
		pstore_ftrace_decode_cpu(rec), rec->ip, rec->parent_ip,
		(void *)rec->ip, (void *)rec->parent_ip);
	seq_printf(s, "CPU:%d ts:%llu %08lx  %08lx  %pf <- %pF\n",
		   pstore_ftrace_decode_cpu(rec),
		   pstore_ftrace_read_timestamp(rec),
		   rec->ip, rec->parent_ip, (void *)rec->ip,
		   (void *)rec->parent_ip);

	return 0;
}
@@ -197,11 +199,14 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
	if (err)
		return err;

	if (p->psi->erase)
	if (p->psi->erase) {
		mutex_lock(&p->psi->read_mutex);
		p->psi->erase(p->type, p->id, p->count,
			      d_inode(dentry)->i_ctime, p->psi);
	else
		mutex_unlock(&p->psi->read_mutex);
	} else {
		return -EPERM;
	}

	return simple_unlink(dir, dentry);
}
+0 −34
Original line number Diff line number Diff line
@@ -5,40 +5,6 @@
#include <linux/time.h>
#include <linux/pstore.h>

#if NR_CPUS <= 2 && defined(CONFIG_ARM_THUMB)
#define PSTORE_CPU_IN_IP 0x1
#elif NR_CPUS <= 4 && defined(CONFIG_ARM)
#define PSTORE_CPU_IN_IP 0x3
#endif

struct pstore_ftrace_record {
	unsigned long ip;
	unsigned long parent_ip;
#ifndef PSTORE_CPU_IN_IP
	unsigned int cpu;
#endif
};

static inline void
pstore_ftrace_encode_cpu(struct pstore_ftrace_record *rec, unsigned int cpu)
{
#ifndef PSTORE_CPU_IN_IP
	rec->cpu = cpu;
#else
	rec->ip |= cpu;
#endif
}

static inline unsigned int
pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
{
#ifndef PSTORE_CPU_IN_IP
	return rec->cpu;
#else
	return rec->ip & PSTORE_CPU_IN_IP;
#endif
}

#ifdef CONFIG_PSTORE_FTRACE
extern void pstore_register_ftrace(void);
extern void pstore_unregister_ftrace(void);
+3 −2
Original line number Diff line number Diff line
@@ -493,6 +493,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
		if (!is_locked) {
			pr_err("pstore dump routine blocked in %s path, may corrupt error record\n"
				       , in_nmi() ? "NMI" : why);
			return;
		}
	} else {
		spin_lock_irqsave(&psinfo->buf_lock, flags);
@@ -584,8 +585,8 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
		} else {
			spin_lock_irqsave(&psinfo->buf_lock, flags);
		}
		memcpy(psinfo->buf, s, c);
		psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, 0, c, psinfo);
		psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &id, 0,
				  s, 0, c, psinfo);
		spin_unlock_irqrestore(&psinfo->buf_lock, flags);
		s += c;
		c = e - s;
Loading