aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 20:36:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 20:36:52 -0500
commit07f80d41cf24b7e6e76cd97d420167932c9a7f82 (patch)
tree86ee28ad0e085d96a94986c1efdada11d5457139
parent6f83e5bd3e96228ee0caff0b103addb5f4e95459 (diff)
parenta6b8978c54b771308f6f1692b9735ac0bb087cc2 (diff)
Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux
Pull pstore update from Tony Luck: "Miscellaneous fs/pstore fixes" * tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux: pstore: Fix sprintf format specifier in pstore_dump() pstore: Add pmsg - user-space accessible pstore object pstore: Handle zero-sized prz in series pstore: Remove superfluous memory size check pstore: Use scnprintf() in pstore_mkfile()
-rw-r--r--fs/pstore/Kconfig10
-rw-r--r--fs/pstore/Makefile2
-rw-r--r--fs/pstore/inode.c26
-rw-r--r--fs/pstore/internal.h6
-rw-r--r--fs/pstore/platform.c5
-rw-r--r--fs/pstore/pmsg.c114
-rw-r--r--fs/pstore/ram.c53
-rw-r--r--include/linux/pstore.h1
-rw-r--r--include/linux/pstore_ram.h1
9 files changed, 193 insertions, 25 deletions
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 983d9510becc..916b8e23d968 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -21,6 +21,16 @@ config PSTORE_CONSOLE
21 When the option is enabled, pstore will log all kernel 21 When the option is enabled, pstore will log all kernel
22 messages, even if no oops or panic happened. 22 messages, even if no oops or panic happened.
23 23
24config PSTORE_PMSG
25 bool "Log user space messages"
26 depends on PSTORE
27 help
28 When the option is enabled, pstore will export a character
29 interface /dev/pmsg0 to log user space messages. On reboot
30 data can be retrieved from /sys/fs/pstore/pmsg-ramoops-[ID].
31
32 If unsure, say N.
33
24config PSTORE_FTRACE 34config PSTORE_FTRACE
25 bool "Persistent function tracer" 35 bool "Persistent function tracer"
26 depends on PSTORE 36 depends on PSTORE
diff --git a/fs/pstore/Makefile b/fs/pstore/Makefile
index 4c9095c2781e..e647d8e81712 100644
--- a/fs/pstore/Makefile
+++ b/fs/pstore/Makefile
@@ -7,5 +7,7 @@ obj-y += pstore.o
7pstore-objs += inode.o platform.o 7pstore-objs += inode.o platform.o
8obj-$(CONFIG_PSTORE_FTRACE) += ftrace.o 8obj-$(CONFIG_PSTORE_FTRACE) += ftrace.o
9 9
10obj-$(CONFIG_PSTORE_PMSG) += pmsg.o
11
10ramoops-objs += ram.o ram_core.o 12ramoops-objs += ram.o ram_core.o
11obj-$(CONFIG_PSTORE_RAM) += ramoops.o 13obj-$(CONFIG_PSTORE_RAM) += ramoops.o
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 50416602774d..b32ce53d24ee 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -338,32 +338,38 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, int count,
338 338
339 switch (type) { 339 switch (type) {
340 case PSTORE_TYPE_DMESG: 340 case PSTORE_TYPE_DMESG:
341 sprintf(name, "dmesg-%s-%lld%s", psname, id, 341 scnprintf(name, sizeof(name), "dmesg-%s-%lld%s",
342 compressed ? ".enc.z" : ""); 342 psname, id, compressed ? ".enc.z" : "");
343 break; 343 break;
344 case PSTORE_TYPE_CONSOLE: 344 case PSTORE_TYPE_CONSOLE:
345 sprintf(name, "console-%s-%lld", psname, id); 345 scnprintf(name, sizeof(name), "console-%s-%lld", psname, id);
346 break; 346 break;
347 case PSTORE_TYPE_FTRACE: 347 case PSTORE_TYPE_FTRACE:
348 sprintf(name, "ftrace-%s-%lld", psname, id); 348 scnprintf(name, sizeof(name), "ftrace-%s-%lld", psname, id);
349 break; 349 break;
350 case PSTORE_TYPE_MCE: 350 case PSTORE_TYPE_MCE:
351 sprintf(name, "mce-%s-%lld", psname, id); 351 scnprintf(name, sizeof(name), "mce-%s-%lld", psname, id);
352 break; 352 break;
353 case PSTORE_TYPE_PPC_RTAS: 353 case PSTORE_TYPE_PPC_RTAS:
354 sprintf(name, "rtas-%s-%lld", psname, id); 354 scnprintf(name, sizeof(name), "rtas-%s-%lld", psname, id);
355 break; 355 break;
356 case PSTORE_TYPE_PPC_OF: 356 case PSTORE_TYPE_PPC_OF:
357 sprintf(name, "powerpc-ofw-%s-%lld", psname, id); 357 scnprintf(name, sizeof(name), "powerpc-ofw-%s-%lld",
358 psname, id);
358 break; 359 break;
359 case PSTORE_TYPE_PPC_COMMON: 360 case PSTORE_TYPE_PPC_COMMON:
360 sprintf(name, "powerpc-common-%s-%lld", psname, id); 361 scnprintf(name, sizeof(name), "powerpc-common-%s-%lld",
362 psname, id);
363 break;
364 case PSTORE_TYPE_PMSG:
365 scnprintf(name, sizeof(name), "pmsg-%s-%lld", psname, id);
361 break; 366 break;
362 case PSTORE_TYPE_UNKNOWN: 367 case PSTORE_TYPE_UNKNOWN:
363 sprintf(name, "unknown-%s-%lld", psname, id); 368 scnprintf(name, sizeof(name), "unknown-%s-%lld", psname, id);
364 break; 369 break;
365 default: 370 default:
366 sprintf(name, "type%d-%s-%lld", type, psname, id); 371 scnprintf(name, sizeof(name), "type%d-%s-%lld",
372 type, psname, id);
367 break; 373 break;
368 } 374 }
369 375
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
index 3b3d305277c4..c36ba2cd0b5d 100644
--- a/fs/pstore/internal.h
+++ b/fs/pstore/internal.h
@@ -45,6 +45,12 @@ extern void pstore_register_ftrace(void);
45static inline void pstore_register_ftrace(void) {} 45static inline void pstore_register_ftrace(void) {}
46#endif 46#endif
47 47
48#ifdef CONFIG_PSTORE_PMSG
49extern void pstore_register_pmsg(void);
50#else
51static inline void pstore_register_pmsg(void) {}
52#endif
53
48extern struct pstore_info *psinfo; 54extern struct pstore_info *psinfo;
49 55
50extern void pstore_set_kmsg_bytes(int); 56extern void pstore_set_kmsg_bytes(int);
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 0a9b72cdfeca..c4c9a10c5760 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -301,7 +301,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
301 301
302 if (big_oops_buf) { 302 if (big_oops_buf) {
303 dst = big_oops_buf; 303 dst = big_oops_buf;
304 hsize = sprintf(dst, "%s#%d Part%d\n", why, 304 hsize = sprintf(dst, "%s#%d Part%u\n", why,
305 oopscount, part); 305 oopscount, part);
306 size = big_oops_buf_sz - hsize; 306 size = big_oops_buf_sz - hsize;
307 307
@@ -321,7 +321,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
321 } 321 }
322 } else { 322 } else {
323 dst = psinfo->buf; 323 dst = psinfo->buf;
324 hsize = sprintf(dst, "%s#%d Part%d\n", why, oopscount, 324 hsize = sprintf(dst, "%s#%d Part%u\n", why, oopscount,
325 part); 325 part);
326 size = psinfo->bufsize - hsize; 326 size = psinfo->bufsize - hsize;
327 dst += hsize; 327 dst += hsize;
@@ -447,6 +447,7 @@ int pstore_register(struct pstore_info *psi)
447 if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) { 447 if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) {
448 pstore_register_console(); 448 pstore_register_console();
449 pstore_register_ftrace(); 449 pstore_register_ftrace();
450 pstore_register_pmsg();
450 } 451 }
451 452
452 if (pstore_update_ms >= 0) { 453 if (pstore_update_ms >= 0) {
diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
new file mode 100644
index 000000000000..feb5dd2948b4
--- /dev/null
+++ b/fs/pstore/pmsg.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2014 Google, Inc.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/cdev.h>
15#include <linux/device.h>
16#include <linux/fs.h>
17#include <linux/uaccess.h>
18#include <linux/vmalloc.h>
19#include "internal.h"
20
21static DEFINE_MUTEX(pmsg_lock);
22#define PMSG_MAX_BOUNCE_BUFFER_SIZE (2*PAGE_SIZE)
23
24static ssize_t write_pmsg(struct file *file, const char __user *buf,
25 size_t count, loff_t *ppos)
26{
27 size_t i, buffer_size;
28 char *buffer;
29
30 if (!count)
31 return 0;
32
33 if (!access_ok(VERIFY_READ, buf, count))
34 return -EFAULT;
35
36 buffer_size = count;
37 if (buffer_size > PMSG_MAX_BOUNCE_BUFFER_SIZE)
38 buffer_size = PMSG_MAX_BOUNCE_BUFFER_SIZE;
39 buffer = vmalloc(buffer_size);
40