Commit 8e343c8b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux

Pull pstore fixes from Tony Luck:
 "Series of small bug fixes for pstore"

* tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
  pstore: Fix memory leak when decompress using big_oops_buf
  pstore: Fix buffer overflow while write offset equal to buffer size
  pstore: Correct the max_dump_cnt clearing of ramoops
  pstore: Fix NULL pointer fault if get NULL prz in ramoops_get_next_prz
  pstore: skip zero size persistent ram buffer in traverse
  pstore: clarify clearing of _read_cnt in ramoops_context
parents 370d2662 e32634f5
...@@ -497,6 +497,7 @@ void pstore_get_records(int quiet) ...@@ -497,6 +497,7 @@ void pstore_get_records(int quiet)
big_oops_buf_sz); big_oops_buf_sz);
if (unzipped_len > 0) { if (unzipped_len > 0) {
kfree(buf);
buf = big_oops_buf; buf = big_oops_buf;
size = unzipped_len; size = unzipped_len;
compressed = false; compressed = false;
......
...@@ -86,6 +86,7 @@ struct ramoops_context { ...@@ -86,6 +86,7 @@ struct ramoops_context {
struct persistent_ram_ecc_info ecc_info; struct persistent_ram_ecc_info ecc_info;
unsigned int max_dump_cnt; unsigned int max_dump_cnt;
unsigned int dump_write_cnt; unsigned int dump_write_cnt;
/* _read_cnt need clear on ramoops_pstore_open */
unsigned int dump_read_cnt; unsigned int dump_read_cnt;
unsigned int console_read_cnt; unsigned int console_read_cnt;
unsigned int ftrace_read_cnt; unsigned int ftrace_read_cnt;
...@@ -101,6 +102,7 @@ static int ramoops_pstore_open(struct pstore_info *psi) ...@@ -101,6 +102,7 @@ static int ramoops_pstore_open(struct pstore_info *psi)
cxt->dump_read_cnt = 0; cxt->dump_read_cnt = 0;
cxt->console_read_cnt = 0; cxt->console_read_cnt = 0;
cxt->ftrace_read_cnt = 0;
return 0; return 0;
} }
...@@ -117,13 +119,15 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max, ...@@ -117,13 +119,15 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
return NULL; return NULL;
prz = przs[i]; prz = przs[i];
if (!prz)
return NULL;
if (update) { /* Update old/shadowed buffer. */
/* Update old/shadowed buffer. */ if (update)
persistent_ram_save_old(prz); persistent_ram_save_old(prz);
if (!persistent_ram_old_size(prz))
return NULL; if (!persistent_ram_old_size(prz))
} return NULL;
*typep = type; *typep = type;
*id = i; *id = i;
...@@ -316,6 +320,7 @@ static void ramoops_free_przs(struct ramoops_context *cxt) ...@@ -316,6 +320,7 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
{ {
int i; int i;
cxt->max_dump_cnt = 0;
if (!cxt->przs) if (!cxt->przs)
return; return;
...@@ -346,7 +351,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, ...@@ -346,7 +351,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
GFP_KERNEL); GFP_KERNEL);
if (!cxt->przs) { if (!cxt->przs) {
dev_err(dev, "failed to initialize a prz array for dumps\n"); dev_err(dev, "failed to initialize a prz array for dumps\n");
return -ENOMEM; goto fail_prz;
} }
for (i = 0; i < cxt->max_dump_cnt; i++) { for (i = 0; i < cxt->max_dump_cnt; i++) {
...@@ -428,7 +433,6 @@ static int ramoops_probe(struct platform_device *pdev) ...@@ -428,7 +433,6 @@ static int ramoops_probe(struct platform_device *pdev)
if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size)) if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
cxt->dump_read_cnt = 0;
cxt->size = pdata->mem_size; cxt->size = pdata->mem_size;
cxt->phys_addr = pdata->mem_address; cxt->phys_addr = pdata->mem_address;
cxt->record_size = pdata->record_size; cxt->record_size = pdata->record_size;
...@@ -505,7 +509,6 @@ static int ramoops_probe(struct platform_device *pdev) ...@@ -505,7 +509,6 @@ static int ramoops_probe(struct platform_device *pdev)
kfree(cxt->pstore.buf); kfree(cxt->pstore.buf);
fail_clear: fail_clear:
cxt->pstore.bufsize = 0; cxt->pstore.bufsize = 0;
cxt->max_dump_cnt = 0;
fail_cnt: fail_cnt:
kfree(cxt->fprz); kfree(cxt->fprz);
fail_init_fprz: fail_init_fprz:
......
...@@ -54,7 +54,7 @@ static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a) ...@@ -54,7 +54,7 @@ static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
do { do {
old = atomic_read(&prz->buffer->start); old = atomic_read(&prz->buffer->start);
new = old + a; new = old + a;
while (unlikely(new > prz->buffer_size)) while (unlikely(new >= prz->buffer_size))
new -= prz->buffer_size; new -= prz->buffer_size;
} while (atomic_cmpxchg(&prz->buffer->start, old, new) != old); } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);
...@@ -91,7 +91,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) ...@@ -91,7 +91,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
old = atomic_read(&prz->buffer->start); old = atomic_read(&prz->buffer->start);
new = old + a; new = old + a;
while (unlikely(new > prz->buffer_size)) while (unlikely(new >= prz->buffer_size))
new -= prz->buffer_size; new -= prz->buffer_size;
atomic_set(&prz->buffer->start, new); atomic_set(&prz->buffer->start, new);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment