diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:36:52 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:36:52 -0500 |
| commit | 07f80d41cf24b7e6e76cd97d420167932c9a7f82 (patch) | |
| tree | 86ee28ad0e085d96a94986c1efdada11d5457139 | |
| parent | 6f83e5bd3e96228ee0caff0b103addb5f4e95459 (diff) | |
| parent | a6b8978c54b771308f6f1692b9735ac0bb087cc2 (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/Kconfig | 10 | ||||
| -rw-r--r-- | fs/pstore/Makefile | 2 | ||||
| -rw-r--r-- | fs/pstore/inode.c | 26 | ||||
| -rw-r--r-- | fs/pstore/internal.h | 6 | ||||
| -rw-r--r-- | fs/pstore/platform.c | 5 | ||||
| -rw-r--r-- | fs/pstore/pmsg.c | 114 | ||||
| -rw-r--r-- | fs/pstore/ram.c | 53 | ||||
| -rw-r--r-- | include/linux/pstore.h | 1 | ||||
| -rw-r--r-- | include/linux/pstore_ram.h | 1 |
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 | ||
| 24 | config 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 | |||
| 24 | config PSTORE_FTRACE | 34 | config 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 | |||
| 7 | pstore-objs += inode.o platform.o | 7 | pstore-objs += inode.o platform.o |
| 8 | obj-$(CONFIG_PSTORE_FTRACE) += ftrace.o | 8 | obj-$(CONFIG_PSTORE_FTRACE) += ftrace.o |
| 9 | 9 | ||
| 10 | obj-$(CONFIG_PSTORE_PMSG) += pmsg.o | ||
| 11 | |||
| 10 | ramoops-objs += ram.o ram_core.o | 12 | ramoops-objs += ram.o ram_core.o |
| 11 | obj-$(CONFIG_PSTORE_RAM) += ramoops.o | 13 | obj-$(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); | |||
| 45 | static inline void pstore_register_ftrace(void) {} | 45 | static inline void pstore_register_ftrace(void) {} |
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | #ifdef CONFIG_PSTORE_PMSG | ||
| 49 | extern void pstore_register_pmsg(void); | ||
| 50 | #else | ||
| 51 | static inline void pstore_register_pmsg(void) {} | ||
| 52 | #endif | ||
| 53 | |||
| 48 | extern struct pstore_info *psinfo; | 54 | extern struct pstore_info *psinfo; |
| 49 | 55 | ||
| 50 | extern void pstore_set_kmsg_bytes(int); | 56 | extern 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 | |||
| 21 | static DEFINE_MUTEX(pmsg_lock); | ||
| 22 | #define PMSG_MAX_BOUNCE_BUFFER_SIZE (2*PAGE_SIZE) | ||
| 23 | |||
| 24 | static 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 | |||
