Commit 201e4aca authored by Anton Vorontsov's avatar Anton Vorontsov Committed by Greg Kroah-Hartman

pstore/ram: Should update old dmesg buffer before reading

Without the update, we'll only see the new dmesg buffer after the
reboot, but previously we could see it right away. Making an oops
visible in pstore filesystem before reboot is a somewhat dubious
feature, but removing it wasn't an intentional change, so let's
restore it.

For this we have to make persistent_ram_save_old() safe for calling
multiple times, and also extern it.
Signed-off-by: default avatarAnton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 33735a94
...@@ -106,6 +106,8 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, ...@@ -106,6 +106,8 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
time->tv_sec = 0; time->tv_sec = 0;
time->tv_nsec = 0; time->tv_nsec = 0;
/* Update old/shadowed buffer. */
persistent_ram_save_old(prz);
size = persistent_ram_old_size(prz); size = persistent_ram_old_size(prz);
*buf = kmalloc(size, GFP_KERNEL); *buf = kmalloc(size, GFP_KERNEL);
if (*buf == NULL) if (*buf == NULL)
......
...@@ -250,23 +250,24 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz, ...@@ -250,23 +250,24 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz,
persistent_ram_update_ecc(prz, start, count); persistent_ram_update_ecc(prz, start, count);
} }
static void __init void persistent_ram_save_old(struct persistent_ram_zone *prz)
persistent_ram_save_old(struct persistent_ram_zone *prz)
{ {
struct persistent_ram_buffer *buffer = prz->buffer; struct persistent_ram_buffer *buffer = prz->buffer;
size_t size = buffer_size(prz); size_t size = buffer_size(prz);
size_t start = buffer_start(prz); size_t start = buffer_start(prz);
char *dest;
persistent_ram_ecc_old(prz); if (!size)
return;
dest = kmalloc(size, GFP_KERNEL); if (!prz->old_log) {
if (dest == NULL) { persistent_ram_ecc_old(prz);
prz->old_log = kmalloc(size, GFP_KERNEL);
}
if (!prz->old_log) {
pr_err("persistent_ram: failed to allocate buffer\n"); pr_err("persistent_ram: failed to allocate buffer\n");
return; return;
} }
prz->old_log = dest;
prz->old_log_size = size; prz->old_log_size = size;
memcpy(prz->old_log, &buffer->data[start], size - start); memcpy(prz->old_log, &buffer->data[start], size - start);
memcpy(prz->old_log + size - start, &buffer->data[0], start); memcpy(prz->old_log + size - start, &buffer->data[0], start);
......
...@@ -75,6 +75,7 @@ struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, ...@@ -75,6 +75,7 @@ struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev,
int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
unsigned int count); unsigned int count);
void persistent_ram_save_old(struct persistent_ram_zone *prz);
size_t persistent_ram_old_size(struct persistent_ram_zone *prz); size_t persistent_ram_old_size(struct persistent_ram_zone *prz);
void *persistent_ram_old(struct persistent_ram_zone *prz); void *persistent_ram_old(struct persistent_ram_zone *prz);
void persistent_ram_free_old(struct persistent_ram_zone *prz); void persistent_ram_free_old(struct persistent_ram_zone *prz);
......
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