aboutsummaryrefslogtreecommitdiff
path: root/fs/pstore/ram.c
diff options
context:
space:
mode:
authorAnton Vorontsov <anton.vorontsov@linaro.org>2012-07-17 12:11:12 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-17 16:48:09 -0700
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 1dd108e0cc6..0b311bc1891 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -25,6 +25,7 @@
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/version.h>
#include <linux/pstore.h>
#include <linux/time.h>
#include <linux/io.h>
@@ -309,7 +310,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
for (i = 0; i < cxt->max_dump_cnt; i++) {
size_t sz = cxt->record_size;
- cxt->przs[i] = persistent_ram_new(*paddr, sz, cxt->ecc_size);
+ cxt->przs[i] = persistent_ram_new(*paddr, sz, 0, cxt->ecc_size);
if (IS_ERR(cxt->przs[i])) {
err = PTR_ERR(cxt->przs[i]);
dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
@@ -327,7 +328,7 @@ fail_prz:
static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
struct persistent_ram_zone **prz,
- phys_addr_t *paddr, size_t sz)
+ phys_addr_t *paddr, size_t sz, u32 sig)
{
if (!sz)
return 0;
@@ -335,7 +336,7 @@ static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
if (*paddr + sz > *paddr + cxt->size)
return -ENOMEM;
- *prz = persistent_ram_new(*paddr, sz, cxt->ecc_size);
+ *prz = persistent_ram_new(*paddr, sz, sig, cxt->ecc_size);
if (IS_ERR(*prz)) {
int err = PTR_ERR(*prz);
@@ -394,11 +395,13 @@ static int __devinit ramoops_probe(struct platform_device *pdev)
if (err)
goto fail_out;
- err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr, cxt->console_size);
+ err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr,
+ cxt->console_size, 0);
if (err)
goto fail_init_cprz;
- err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size);
+ err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size,
+ LINUX_VERSION_CODE);
if (err)
goto fail_init_fprz;