aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/ram.c
diff options
context:
space:
mode:
authorAnton Vorontsov <anton.vorontsov@linaro.org>2012-07-17 15:11:12 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-17 19:48:09 -0400
commitcbe7cbf5a666ad9dfe2e0c276066131af73769ab (patch)
treea354f2ed2f0a45f336b0172c46d0bb7c718eee0f /fs/pstore/ram.c
parent67a101f573b0cb1043c8c305112113450cb9fdbf (diff)
pstore/ram: Make tracing log versioned
Decoding the binary trace w/ a different kernel might be troublesome since we convert addresses to symbols. For kernels with minimal changes, the mappings would probably match, but it's not guaranteed at all. (But still we could convert the addresses by hand, since we do print raw addresses.) If we use modules, the symbols could be loaded at different addresses from the previously booted kernel, and so this would also fail, but there's nothing we can do about it. Also, the binary data format that pstore/ram is using in its ringbuffer may change between the kernels, so here we too must ensure that we're running the same kernel. So, there are two questions really: 1. How to compute the unique kernel tag; 2. Where to store it. In this patch we're using LINUX_VERSION_CODE, just as hibernation (suspend-to-disk) does. This way we are protecting from the kernel version mismatch, making sure that we're running the same kernel version and patch level. We could use CRC of a symbol table (as suggested by Tony Luck), but for now let's not be that strict. And as for storing, we are using a small trick here. Instead of allocating a dedicated buffer for the tag (i.e. another prz), or hacking ram_core routines to "reserve" some control data in the buffer, we are just encoding the tag into the buffer signature (and XOR'ing it with the actual signature value, so that buffers not needing a tag can just pass zero, which will result into the plain old PRZ signature). Suggested-by: Steven Rostedt <rostedt@goodmis.org> Suggested-by: Tony Luck <tony.luck@intel.com> Suggested-by: Colin Cross <ccross@android.com> Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r--fs/pstore/ram.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 1dd108e0cc60..0b311bc18916 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -25,6 +25,7 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/version.h>
28#include <linux/pstore.h> 29#include <linux/pstore.h>
29#include <linux/time.h> 30#include <linux/time.h>
30#include <linux/io.h> 31#include <linux/io.h>
@@ -309,7 +310,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
309 for (i = 0; i < cxt->max_dump_cnt; i++) { 310 for (i = 0; i < cxt->max_dump_cnt; i++) {
310 size_t sz = cxt->record_size; 311 size_t sz = cxt->record_size;
311 312
312 cxt->przs[i] = persistent_ram_new(*paddr, sz, cxt->ecc_size); 313 cxt->przs[i] = persistent_ram_new(*paddr, sz, 0, cxt->ecc_size);
313 if (IS_ERR(cxt->przs[i])) { 314 if (IS_ERR(cxt->przs[i])) {
314 err = PTR_ERR(cxt->przs[i]); 315 err = PTR_ERR(cxt->przs[i]);
315 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", 316 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
@@ -327,7 +328,7 @@ fail_prz:
327 328
328static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt, 329static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
329 struct persistent_ram_zone **prz, 330 struct persistent_ram_zone **prz,
330 phys_addr_t *paddr, size_t sz) 331 phys_addr_t *paddr, size_t sz, u32 sig)
331{ 332{
332 if (!sz) 333 if (!sz)
333 return 0; 334 return 0;
@@ -335,7 +336,7 @@ static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
335 if (*paddr + sz > *paddr + cxt->size) 336 if (*paddr + sz > *paddr + cxt->size)
336 return -ENOMEM; 337 return -ENOMEM;
337 338
338 *prz = persistent_ram_new(*paddr, sz, cxt->ecc_size); 339 *prz = persistent_ram_new(*paddr, sz, sig, cxt->ecc_size);
339 if (IS_ERR(*prz)) { 340 if (IS_ERR(*prz)) {
340 int err = PTR_ERR(*prz); 341 int err = PTR_ERR(*prz);
341 342
@@ -394,11 +395,13 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
394 if (err) 395 if (err)
395 goto fail_out; 396 goto fail_out;
396 397
397 err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr, cxt->console_size); 398 err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr,
399 cxt->console_size, 0);
398 if (err) 400 if (err)
399 goto fail_init_cprz; 401 goto fail_init_cprz;
400 402
401 err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size); 403 err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size,
404 LINUX_VERSION_CODE);
402 if (err) 405 if (err)
403 goto fail_init_fprz; 406 goto fail_init_fprz;
404 407