aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 18:16:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 18:16:16 -0400
commit0fb3ca447ddabcfb8dc7e0f719955e500b170cbd (patch)
tree57e516541b7650149c468a9567152164b12c75e3
parent3940ee36a0565ea7fb848e3c798afe22efd0b90a (diff)
parentf88baf68ebe5b2efced64725fd98548af9b8f510 (diff)
Merge tag 'pstore-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull pstore updates from Kees Cook: - Fix bug in module unloading - Switch to always using spinlock over cmpxchg - Explicitly define pstore backend's supported modes - Remove bounce buffer from pmsg - Switch to using memcpy_to/fromio() - Error checking improvements * tag 'pstore-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: ramoops: move spin_lock_init after kmalloc error checking pstore/ram: Use memcpy_fromio() to save old buffer pstore/ram: Use memcpy_toio instead of memcpy pstore/pmsg: drop bounce buffer pstore/ram: Set pstore flags dynamically pstore: Split pstore fragile flags pstore/core: drop cmpxchg based updates pstore/ramoops: fixup driver removal
-rw-r--r--drivers/acpi/apei/erst.c2
-rw-r--r--drivers/firmware/efi/efi-pstore.c2
-rw-r--r--fs/pstore/platform.c53
-rw-r--r--fs/pstore/pmsg.c35
-rw-r--r--fs/pstore/ram.c46
-rw-r--r--fs/pstore/ram_core.c96
-rw-r--r--include/linux/pstore.h17
-rw-r--r--include/linux/pstore_ram.h7
8 files changed, 162 insertions, 96 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index f096ab3cb54d..ec4f507b524f 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -938,7 +938,7 @@ static int erst_clearer(enum pstore_type_id type, u64 id, int count,
938static struct pstore_info erst_info = { 938static struct pstore_info erst_info = {
939 .owner = THIS_MODULE, 939 .owner = THIS_MODULE,
940 .name = "erst", 940 .name = "erst",
941 .flags = PSTORE_FLAGS_FRAGILE, 941 .flags = PSTORE_FLAGS_DMESG,
942 .open = erst_open_pstore, 942 .open = erst_open_pstore,
943 .close = erst_close_pstore, 943 .close = erst_close_pstore,
944 .read = erst_reader, 944 .read = erst_reader,
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 1c33d7469e4a..f402ba2eed46 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -380,7 +380,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
380static struct pstore_info efi_pstore_info = { 380static struct pstore_info efi_pstore_info = {
381 .owner = THIS_MODULE, 381 .owner = THIS_MODULE,
382 .name = "efi", 382 .name = "efi",
383 .flags = PSTORE_FLAGS_FRAGILE, 383 .flags = PSTORE_FLAGS_DMESG,
384 .open = efi_pstore_open, 384 .open = efi_pstore_open,
385 .close = efi_pstore_close, 385 .close = efi_pstore_close,
386 .read = efi_pstore_read, 386 .read = efi_pstore_read,
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 16ecca5b72d8..14984d902a99 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -623,6 +623,40 @@ static int pstore_write_compat(enum pstore_type_id type,
623 size, psi); 623 size, psi);
624} 624}
625 625
626static int pstore_write_buf_user_compat(enum pstore_type_id type,
627 enum kmsg_dump_reason reason,
628 u64 *id, unsigned int part,
629 const char __user *buf,
630 bool compressed, size_t size,
631 struct pstore_info *psi)
632{
633 unsigned long flags = 0;
634 size_t i, bufsize = size;
635 long ret = 0;
636
637 if (unlikely(!access_ok(VERIFY_READ, buf, size)))
638 return -EFAULT;
639 if (bufsize > psinfo->bufsize)
640 bufsize = psinfo->bufsize;
641 spin_lock_irqsave(&psinfo->buf_lock, flags);
642 for (i = 0; i < size; ) {
643 size_t c = min(size - i, bufsize);
644
645 ret = __copy_from_user(psinfo->buf, buf + i, c);
646 if (unlikely(ret != 0)) {
647 ret = -EFAULT;
648 break;
649 }
650 ret = psi->write_buf(type, reason, id, part, psinfo->buf,
651 compressed, c, psi);
652 if (unlikely(ret < 0))
653 break;
654 i += c;
655 }
656 spin_unlock_irqrestore(&psinfo->buf_lock, flags);
657 return unlikely(ret < 0) ? ret : size;
658}
659
626/* 660/*
627 * platform specific persistent storage driver registers with 661 * platform specific persistent storage driver registers with
628 * us here. If pstore is already mounted, call the platform 662 * us here. If pstore is already mounted, call the platform
@@ -645,6 +679,8 @@ int pstore_register(struct pstore_info *psi)
645 679
646 if (!psi->write) 680 if (!psi->write)
647 psi->write = pstore_write_compat; 681 psi->write = pstore_write_compat;
682 if (!psi->write_buf_user)
683 psi->write_buf_user = pstore_write_buf_user_compat;
648 psinfo = psi; 684 psinfo = psi;
649 mutex_init(&psinfo->read_mutex); 685 mutex_init(&psinfo->read_mutex);
650 spin_unlock(&pstore_lock); 686 spin_unlock(&pstore_lock);
@@ -659,13 +695,14 @@ int pstore_register(struct pstore_info *psi)
659 if (pstore_is_mounted()) 695 if (pstore_is_mounted())
660 pstore_get_records(0); 696 pstore_get_records(0);
661 697
662 pstore_register_kmsg(); 698 if (psi->flags & PSTORE_FLAGS_DMESG)
663 699 pstore_register_kmsg();
664 if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) { 700 if (psi->flags & PSTORE_FLAGS_CONSOLE)
665 pstore_register_console(); 701 pstore_register_console();
702 if (psi->flags & PSTORE_FLAGS_FTRACE)
666 pstore_register_ftrace(); 703 pstore_register_ftrace();
704 if (psi->flags & PSTORE_FLAGS_PMSG)
667 pstore_register_pmsg(); 705 pstore_register_pmsg();
668 }
669 706
670 if (pstore_update_ms >= 0) { 707 if (pstore_update_ms >= 0) {
671 pstore_timer.expires = jiffies + 708 pstore_timer.expires = jiffies +
@@ -689,12 +726,14 @@ EXPORT_SYMBOL_GPL(pstore_register);
689 726
690void pstore_unregister(struct pstore_info *psi) 727void pstore_unregister(struct pstore_info *psi)
691{ 728{
692 if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) { 729 if (psi->flags & PSTORE_FLAGS_PMSG)
693 pstore_unregister_pmsg(); 730 pstore_unregister_pmsg();
731 if (psi->flags & PSTORE_FLAGS_FTRACE)
694 pstore_unregister_ftrace(); 732 pstore_unregister_ftrace();
733 if (psi->flags & PSTORE_FLAGS_CONSOLE)
695 pstore_unregister_console(); 734 pstore_unregister_console();
696 } 735 if (psi->flags & PSTORE_FLAGS_DMESG)
697 pstore_unregister_kmsg(); 736 pstore_unregister_kmsg();
698 737
699 free_buf_for_compression(); 738 free_buf_for_compression();
700 739
diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
index 7de20cd3797f..78f6176c020f 100644
--- a/fs/pstore/pmsg.c
+++ b/fs/pstore/pmsg.c
@@ -19,48 +19,25 @@
19#include "internal.h" 19#include "internal.h"
20 20
21static DEFINE_MUTEX(pmsg_lock); 21static DEFINE_MUTEX(pmsg_lock);
22#define PMSG_MAX_BOUNCE_BUFFER_SIZE (2*PAGE_SIZE)
23 22
24static ssize_t write_pmsg(struct file *file, const char __user *buf, 23static ssize_t write_pmsg(struct file *file, const char __user *buf,
25 size_t count, loff_t *ppos) 24 size_t count, loff_t *ppos)
26{ 25{
27 size_t i, buffer_size; 26 u64 id;
28 char *buffer; 27 int ret;
29 28
30 if (!count) 29 if (!count)
31 return 0; 30 return 0;
32 31
32 /* check outside lock, page in any data. write_buf_user also checks */
33 if (!access_ok(VERIFY_READ, buf, count)) 33 if (!access_ok(VERIFY_READ, buf, count))
34 return -EFAULT; 34 return -EFAULT;
35 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 if (!buffer)
41 return -ENOMEM;
42
43 mutex_lock(&pmsg_lock); 36 mutex_lock(&pmsg_lock);
44 for (i = 0; i < count; ) { 37 ret = psinfo->write_buf_user(PSTORE_TYPE_PMSG, 0, &id, 0, buf, 0, count,
45 size_t c = min(count - i, buffer_size); 38 psinfo);
46 u64 id;
47 long ret;
48
49 ret = __copy_from_user(buffer, buf + i, c);
50 if (unlikely(ret != 0)) {
51 mutex_unlock(&pmsg_lock);
52 vfree(buffer);
53 return -EFAULT;
54 }
55 psinfo->write_buf(PSTORE_TYPE_PMSG, 0, &id, 0, buffer, 0, c,
56 psinfo);
57
58 i += c;
59 }
60
61 mutex_unlock(&pmsg_lock); 39 mutex_unlock(&pmsg_lock);
62 vfree(buffer); 40 return ret ? ret : count;
63 return count;
64} 41}
65 42
66static const struct file_operations pmsg_fops = { 43static const struct file_operations pmsg_fops = {
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 7a034d62cf8c..6ad831b9d1b8 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -331,6 +331,24 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
331 return 0; 331 return 0;
332} 332}
333 333
334static int notrace ramoops_pstore_write_buf_user(enum pstore_type_id type,
335 enum kmsg_dump_reason reason,
336 u64 *id, unsigned int part,
337 const char __user *buf,
338 bool compressed, size_t size,
339 struct pstore_info *psi)
340{
341 if (type == PSTORE_TYPE_PMSG) {
342 struct ramoops_context *cxt = psi->data;
343
344 if (!cxt->mprz)
345 return -ENOMEM;
346 return persistent_ram_write_user(cxt->mprz, buf, size);
347 }
348
349 return -EINVAL;
350}
351
334static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count, 352static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count,
335 struct timespec time, struct pstore_info *psi) 353 struct timespec time, struct pstore_info *psi)
336{ 354{
@@ -369,6 +387,7 @@ static struct ramoops_context oops_cxt = {
369 .open = ramoops_pstore_open, 387 .open = ramoops_pstore_open,
370 .read = ramoops_pstore_read, 388 .read = ramoops_pstore_read,
371 .write_buf = ramoops_pstore_write_buf, 389 .write_buf = ramoops_pstore_write_buf,
390 .write_buf_user = ramoops_pstore_write_buf_user,
372 .erase = ramoops_pstore_erase, 391 .erase = ramoops_pstore_erase,
373 }, 392 },
374}; 393};
@@ -377,13 +396,14 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
377{ 396{
378 int i; 397 int i;
379 398
380 cxt->max_dump_cnt = 0;
381 if (!cxt->przs) 399 if (!cxt->przs)
382 return; 400 return;
383 401
384 for (i = 0; !IS_ERR_OR_NULL(cxt->przs[i]); i++) 402 for (i = 0; i < cxt->max_dump_cnt; i++)
385 persistent_ram_free(cxt->przs[i]); 403 persistent_ram_free(cxt->przs[i]);
404
386 kfree(cxt->przs); 405 kfree(cxt->przs);
406 cxt->max_dump_cnt = 0;
387} 407}
388 408
389static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, 409static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
@@ -408,7 +428,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
408 GFP_KERNEL); 428 GFP_KERNEL);
409 if (!cxt->przs) { 429 if (!cxt->przs) {
410 dev_err(dev, "failed to initialize a prz array for dumps\n"); 430 dev_err(dev, "failed to initialize a prz array for dumps\n");
411 goto fail_prz; 431 goto fail_mem;
412 } 432 }
413 433
414 for (i = 0; i < cxt->max_dump_cnt; i++) { 434 for (i = 0; i < cxt->max_dump_cnt; i++) {
@@ -419,6 +439,11 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
419 err = PTR_ERR(cxt->przs[i]); 439 err = PTR_ERR(cxt->przs[i]);
420 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", 440 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
421 cxt->record_size, (unsigned long long)*paddr, err); 441 cxt->record_size, (unsigned long long)*paddr, err);
442
443 while (i > 0) {
444 i--;
445 persistent_ram_free(cxt->przs[i]);
446 }
422 goto fail_prz; 447 goto fail_prz;
423 } 448 }
424 *paddr += cxt->record_size; 449 *paddr += cxt->record_size;
@@ -426,7 +451,9 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
426 451
427 return 0; 452 return 0;
428fail_prz: 453fail_prz:
429 ramoops_free_przs(cxt); 454 kfree(cxt->przs);
455fail_mem:
456 cxt->max_dump_cnt = 0;
430 return err; 457 return err;
431} 458}
432 459
@@ -608,12 +635,20 @@ static int ramoops_probe(struct platform_device *pdev)
608 cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */ 635 cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
609 cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize); 636 cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
610 cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL); 637 cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
611 spin_lock_init(&cxt->pstore.buf_lock);
612 if (!cxt->pstore.buf) { 638 if (!cxt->pstore.buf) {
613 pr_err("cannot allocate pstore buffer\n"); 639 pr_err("cannot allocate pstore buffer\n");
614 err = -ENOMEM; 640 err = -ENOMEM;
615 goto fail_clear; 641 goto fail_clear;
616 } 642 }
643 spin_lock_init(&cxt->pstore.buf_lock);
644
645 cxt->pstore.flags = PSTORE_FLAGS_DMESG;
646 if (cxt->console_size)
647 cxt->pstore.flags |= PSTORE_FLAGS_CONSOLE;
648 if (cxt->ftrace_size)
649 cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
650 if (cxt->pmsg_size)
651 cxt->pstore.flags |= PSTORE_FLAGS_PMSG;
617 652
618 err = pstore_register(&cxt->pstore); 653 err = pstore_register(&cxt->pstore);
619 if (err) { 654 if (err) {
@@ -659,7 +694,6 @@ static int ramoops_remove(struct platform_device *pdev)
659 struct ramoops_context *cxt = &oops_cxt; 694 struct ramoops_context *cxt = &oops_cxt;
660 695
661 pstore_unregister(&cxt->pstore); 696 pstore_unregister(&cxt->pstore);
662 cxt->max_dump_cnt = 0;
663 697
664 kfree(cxt->pstore.buf); 698 kfree(cxt->pstore.buf);
665 cxt->pstore.bufsize = 0; 699 cxt->pstore.bufsize = 0;
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 76c3f80efdfa..3975deec02f8 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -17,15 +17,16 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/kernel.h>
21#include <linux/init.h> 20#include <linux/init.h>
22#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/kernel.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/memblock.h> 24#include <linux/memblock.h>
25#include <linux/pstore_ram.h>
25#include <linux/rslib.h> 26#include <linux/rslib.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/uaccess.h>
27#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
28#include <linux/pstore_ram.h>
29#include <asm/page.h> 30#include <asm/page.h>
30 31
31struct persistent_ram_buffer { 32struct persistent_ram_buffer {
@@ -47,43 +48,10 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz)
47 return atomic_read(&prz->buffer->start); 48 return atomic_read(&prz->buffer->start);
48} 49}
49 50
50/* increase and wrap the start pointer, returning the old value */
51static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
52{
53 int old;
54 int new;
55
56 do {
57 old = atomic_read(&prz->buffer->start);
58 new = old + a;
59 while (unlikely(new >= prz->buffer_size))
60 new -= prz->buffer_size;
61 } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);
62
63 return old;
64}
65
66/* increase the size counter until it hits the max size */
67static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a)
68{
69 size_t old;
70 size_t new;
71
72 if (atomic_read(&prz->buffer->size) == prz->buffer_size)
73 return;
74
75 do {
76 old = atomic_read(&prz->buffer->size);
77 new = old + a;
78 if (new > prz->buffer_size)
79 new = prz->buffer_size;
80 } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
81}
82
83static DEFINE_RAW_SPINLOCK(buffer_lock); 51static DEFINE_RAW_SPINLOCK(buffer_lock);
84 52
85/* increase and wrap the start pointer, returning the old value */ 53/* increase and wrap the start pointer, returning the old value */
86static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) 54static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
87{ 55{
88 int old; 56 int old;
89 int new; 57 int new;
@@ -103,7 +71,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
103} 71}
104 72
105/* increase the size counter until it hits the max size */ 73/* increase the size counter until it hits the max size */
106static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) 74static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
107{ 75{
108 size_t old; 76 size_t old;
109 size_t new; 77 size_t new;
@@ -124,9 +92,6 @@ exit:
124 raw_spin_unlock_irqrestore(&buffer_lock, flags); 92 raw_spin_unlock_irqrestore(&buffer_lock, flags);
125} 93}
126 94
127static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic;
128static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic;
129
130static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, 95static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
131 uint8_t *data, size_t len, uint8_t *ecc) 96 uint8_t *data, size_t len, uint8_t *ecc)
132{ 97{
@@ -299,10 +264,20 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz,
299 const void *s, unsigned int start, unsigned int count) 264 const void *s, unsigned int start, unsigned int count)
300{ 265{
301 struct persistent_ram_buffer *buffer = prz->buffer; 266 struct persistent_ram_buffer *buffer = prz->buffer;
302 memcpy(buffer->data + start, s, count); 267 memcpy_toio(buffer->data + start, s, count);
303 persistent_ram_update_ecc(prz, start, count); 268 persistent_ram_update_ecc(prz, start, count);
304} 269}
305 270
271static int notrace persistent_ram_update_user(struct persistent_ram_zone *prz,
272 const void __user *s, unsigned int start, unsigned int count)
273{
274 struct persistent_ram_buffer *buffer = prz->buffer;
275 int ret = unlikely(__copy_from_user(buffer->data + start, s, count)) ?
276 -EFAULT : 0;
277 persistent_ram_update_ecc(prz, start, count);
278 return ret;
279}
280
306void persistent_ram_save_old(struct persistent_ram_zone *prz) 281void persistent_ram_save_old(struct persistent_ram_zone *prz)
307{ 282{
308 struct persistent_ram_buffer *buffer = prz->buffer; 283 struct persistent_ram_buffer *buffer = prz->buffer;
@@ -322,8 +297,8 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz)
322 } 297 }
323 298
324 prz->old_log_size = size; 299 prz->old_log_size = size;
325 memcpy(prz->old_log, &buffer->data[start], size - start); 300 memcpy_fromio(prz->old_log, &buffer->data[start], size - start);
326 memcpy(prz->old_log + size - start, &buffer->data[0], start); 301 memcpy_fromio(prz->old_log + size - start, &buffer->data[0], start);
327} 302}
328 303
329int notrace persistent_ram_write(struct persistent_ram_zone *prz, 304int notrace persistent_ram_write(struct persistent_ram_zone *prz,
@@ -356,6 +331,38 @@ int notrace persistent_ram_write(struct persistent_ram_zone *prz,
356 return count; 331 return count;
357} 332}
358 333
334int notrace persistent_ram_write_user(struct persistent_ram_zone *prz,
335 const void __user *s, unsigned int count)
336{
337 int rem, ret = 0, c = count;
338 size_t start;
339
340 if (unlikely(!access_ok(VERIFY_READ, s, count)))
341 return -EFAULT;
342 if (unlikely(c > prz->buffer_size)) {
343 s += c - prz->buffer_size;
344 c = prz->buffer_size;
345 }
346
347 buffer_size_add(prz, c);
348
349 start = buffer_start_add(prz, c);
350
351 rem = prz->buffer_size - start;
352 if (unlikely(rem < c)) {
353 ret = persistent_ram_update_user(prz, s, start, rem);
354 s += rem;
355 c -= rem;
356 start = 0;
357 }
358 if (likely(!ret))
359 ret = persistent_ram_update_user(prz, s, start, c);
360
361 persistent_ram_update_header_ecc(prz);
362
363 return unlikely(ret) ? ret : count;
364}
365
359size_t persistent_ram_old_size(struct persistent_ram_zone *prz) 366size_t persistent_ram_old_size(struct persistent_ram_zone *prz)
360{ 367{
361 return prz->old_log_size; 368 return prz->old_log_size;
@@ -426,9 +433,6 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
426 return NULL; 433 return NULL;
427 } 434 }
428 435
429 buffer_start_add = buffer_start_add_locked;
430 buffer_size_add = buffer_size_add_locked;
431
432 if (memtype) 436 if (memtype)
433 va = ioremap(start, size); 437 va = ioremap(start, size);
434 else 438 else
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 899e95e84400..92013cc9cc8c 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -22,12 +22,13 @@
22#ifndef _LINUX_PSTORE_H 22#ifndef _LINUX_PSTORE_H
23#define _LINUX_PSTORE_H 23#define _LINUX_PSTORE_H
24 24
25#include <linux/time.h> 25#include <linux/compiler.h>
26#include <linux/errno.h>
26#include <linux/kmsg_dump.h> 27#include <linux/kmsg_dump.h>
27#include <linux/mutex.h> 28#include <linux/mutex.h>
28#include <linux/types.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/errno.h> 30#include <linux/time.h>
31#include <linux/types.h>
31 32
32/* types */ 33/* types */
33enum pstore_type_id { 34enum pstore_type_id {
@@ -68,13 +69,21 @@ struct pstore_info {
68 enum kmsg_dump_reason reason, u64 *id, 69 enum kmsg_dump_reason reason, u64 *id,
69 unsigned int part, const char *buf, bool compressed, 70 unsigned int part, const char *buf, bool compressed,
70 size_t size, struct pstore_info *psi); 71 size_t size, struct pstore_info *psi);
72 int (*write_buf_user)(enum pstore_type_id type,
73 enum kmsg_dump_reason reason, u64 *id,
74 unsigned int part, const char __user *buf,
75 bool compressed, size_t size, struct pstore_info *psi);
71 int (*erase)(enum pstore_type_id type, u64 id, 76 int (*erase)(enum pstore_type_id type, u64 id,
72 int count, struct timespec time, 77 int count, struct timespec time,
73 struct pstore_info *psi); 78 struct pstore_info *psi);
74 void *data; 79 void *data;
75}; 80};
76 81
77#define PSTORE_FLAGS_FRAGILE 1 82#define PSTORE_FLAGS_DMESG (1 << 0)
83#define PSTORE_FLAGS_FRAGILE PSTORE_FLAGS_DMESG
84#define PSTORE_FLAGS_CONSOLE (1 << 1)
85#define PSTORE_FLAGS_FTRACE (1 << 2)
86#define PSTORE_FLAGS_PMSG (1 << 3)
78 87
79extern int pstore_register(struct pstore_info *); 88extern int pstore_register(struct pstore_info *);
80extern void pstore_unregister(struct pstore_info *); 89extern void pstore_unregister(struct pstore_info *);
diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h
index 4660aaa3195e..c668c861c96c 100644
--- a/include/linux/pstore_ram.h
+++ b/include/linux/pstore_ram.h
@@ -17,11 +17,12 @@
17#ifndef __LINUX_PSTORE_RAM_H__ 17#ifndef __LINUX_PSTORE_RAM_H__
18#define __LINUX_PSTORE_RAM_H__ 18#define __LINUX_PSTORE_RAM_H__
19 19
20#include <linux/compiler.h>
20#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/init.h>
21#include <linux/kernel.h> 23#include <linux/kernel.h>
22#include <linux/list.h> 24#include <linux/list.h>
23#include <linux/types.h> 25#include <linux/types.h>
24#include <linux/init.h>
25 26
26struct persistent_ram_buffer; 27struct persistent_ram_buffer;
27struct rs_control; 28struct rs_control;
@@ -59,7 +60,9 @@ void persistent_ram_free(struct persistent_ram_zone *prz);
59void persistent_ram_zap(struct persistent_ram_zone *prz); 60void persistent_ram_zap(struct persistent_ram_zone *prz);
60 61
61int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, 62int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
62 unsigned int count); 63 unsigned int count);
64int persistent_ram_write_user(struct persistent_ram_zone *prz,
65 const void __user *s, unsigned int count);
63 66
64void persistent_ram_save_old(struct persistent_ram_zone *prz); 67void persistent_ram_save_old(struct persistent_ram_zone *prz);
65size_t persistent_ram_old_size(struct persistent_ram_zone *prz); 68size_t persistent_ram_old_size(struct persistent_ram_zone *prz);