mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-08 18:35:20 +02:00
pstore updates for v6.2-rc1
- Reporting improvements and return path fixes (Guilherme G. Piccoli, Wang Yufen, Kees Cook). - Clean up kmsg_bytes module parameter usage (Guilherme G. Piccoli). - Add Guilherme to pstore MAINTAINERS entry. - Choose friendlier allocation flags (Qiujun Huang, Stephen Boyd). -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmOOi3cWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJm8QD/901WcETCGFZlkWKsXLym8123rr Y87WifzKuI3cTf1oYTtG7zrYBTWMaFYEiPZBltcy0nEbLlUs0YtYukNlkykEt9S4 CWmyxV7DDFn2sZ/HluPhKvsIZlzcHtW1o5dzxoJadRMN06pjnAFZOHkktpuVniVN 0IXDOOTTEEBxh11BjbD7UrilnYR6BA9kXGKcZTd6Oo/GmO8EkpzXGnVxLRr6U1/i qwxhOZGgVzhFuCogQvOo1VQ0DcJ8l5u3h1UIS3b9vQD/oZlpe4brVGCoD5CGugwQ 1IpqqiBsLrsXIBtqbtg02MMgSy1bELgyLgb5jHRClfuuEiwcxw1GvAy6JzS78Uye 5g3eiKh3oVkF9/TojSVMAzD3ObAukH4hBo4y98Jy+X2PYvSzUn/WpW0itnxFIaou MqZZeYn2Xz7AMXQ5N3WF3fJLjscKoCT2D0WyyiNOqoWAaYSHeZcILXUGltT+Zjtz vyvEhLlzQ+avh6Tx0NOKrnIA91nemuW0TYjtGlKx4X8uBvEmt+cFaKd0oZ2M8grB l+B2iRxVMlIrMk63mzy+qISVzLN73XCdmhcpPw60Gqin7TyIOGJ6JvZ3viq9Col7 os5ii4MZyoerDM0bsdmPQlUq8bn0DMDUV+4kGAiZwczPkB1oigxn37ksDHMNbwRu jrFtb+v5Vazmb5Lafg== =EsLr -----END PGP SIGNATURE----- Merge tag 'pstore-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull pstore updates from Kees Cook: "A small collection of bug fixes, refactorings, and general improvements: - Reporting improvements and return path fixes (Guilherme G. Piccoli, Wang Yufen, Kees Cook) - Clean up kmsg_bytes module parameter usage (Guilherme G. Piccoli) - Add Guilherme to pstore MAINTAINERS entry - Choose friendlier allocation flags (Qiujun Huang, Stephen Boyd)" * tag 'pstore-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP pstore/ram: Fix error return code in ramoops_probe() pstore: Alert on backend write error MAINTAINERS: Update pstore maintainers pstore/ram: Set freed addresses to NULL pstore/ram: Move internal definitions out of kernel-wide include pstore/ram: Move pmsg init earlier pstore/ram: Consolidate kfree() paths efi: pstore: Follow convention for the efi-pstore backend name pstore: Inform unregistered backend names as well pstore: Expose kmsg_bytes as a module parameter pstore: Improve error reporting in case of backend overlap pstore/zone: Use GFP_ATOMIC to allocate zone buffer
This commit is contained in:
commit
059c4a341d
|
@ -16661,10 +16661,10 @@ F: net/psample
|
||||||
|
|
||||||
PSTORE FILESYSTEM
|
PSTORE FILESYSTEM
|
||||||
M: Kees Cook <keescook@chromium.org>
|
M: Kees Cook <keescook@chromium.org>
|
||||||
M: Anton Vorontsov <anton@enomsg.org>
|
R: Tony Luck <tony.luck@intel.com>
|
||||||
M: Colin Cross <ccross@android.com>
|
R: Guilherme G. Piccoli <gpiccoli@igalia.com>
|
||||||
M: Tony Luck <tony.luck@intel.com>
|
L: linux-hardening@vger.kernel.org
|
||||||
S: Maintained
|
S: Supported
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/pstore
|
||||||
F: Documentation/admin-guide/ramoops.rst
|
F: Documentation/admin-guide/ramoops.rst
|
||||||
F: Documentation/admin-guide/pstore-blk.rst
|
F: Documentation/admin-guide/pstore-blk.rst
|
||||||
|
|
|
@ -207,7 +207,7 @@ static int efi_pstore_erase(struct pstore_record *record)
|
||||||
|
|
||||||
static struct pstore_info efi_pstore_info = {
|
static struct pstore_info efi_pstore_info = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "efi",
|
.name = KBUILD_MODNAME,
|
||||||
.flags = PSTORE_FLAGS_DMESG,
|
.flags = PSTORE_FLAGS_DMESG,
|
||||||
.open = efi_pstore_open,
|
.open = efi_pstore_open,
|
||||||
.close = efi_pstore_close,
|
.close = efi_pstore_close,
|
||||||
|
|
|
@ -89,6 +89,11 @@ static char *compress =
|
||||||
module_param(compress, charp, 0444);
|
module_param(compress, charp, 0444);
|
||||||
MODULE_PARM_DESC(compress, "compression to use");
|
MODULE_PARM_DESC(compress, "compression to use");
|
||||||
|
|
||||||
|
/* How much of the kernel log to snapshot */
|
||||||
|
unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES;
|
||||||
|
module_param(kmsg_bytes, ulong, 0444);
|
||||||
|
MODULE_PARM_DESC(kmsg_bytes, "amount of kernel log to snapshot (in bytes)");
|
||||||
|
|
||||||
/* Compression parameters */
|
/* Compression parameters */
|
||||||
static struct crypto_comp *tfm;
|
static struct crypto_comp *tfm;
|
||||||
|
|
||||||
|
@ -100,9 +105,6 @@ struct pstore_zbackend {
|
||||||
static char *big_oops_buf;
|
static char *big_oops_buf;
|
||||||
static size_t big_oops_buf_sz;
|
static size_t big_oops_buf_sz;
|
||||||
|
|
||||||
/* How much of the console log to snapshot */
|
|
||||||
unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES;
|
|
||||||
|
|
||||||
void pstore_set_kmsg_bytes(int bytes)
|
void pstore_set_kmsg_bytes(int bytes)
|
||||||
{
|
{
|
||||||
kmsg_bytes = bytes;
|
kmsg_bytes = bytes;
|
||||||
|
@ -391,6 +393,7 @@ static void pstore_dump(struct kmsg_dumper *dumper,
|
||||||
const char *why;
|
const char *why;
|
||||||
unsigned int part = 1;
|
unsigned int part = 1;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
|
int saved_ret = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
why = kmsg_dump_reason_str(reason);
|
why = kmsg_dump_reason_str(reason);
|
||||||
|
@ -461,12 +464,21 @@ static void pstore_dump(struct kmsg_dumper *dumper,
|
||||||
if (ret == 0 && reason == KMSG_DUMP_OOPS) {
|
if (ret == 0 && reason == KMSG_DUMP_OOPS) {
|
||||||
pstore_new_entry = 1;
|
pstore_new_entry = 1;
|
||||||
pstore_timer_kick();
|
pstore_timer_kick();
|
||||||
|
} else {
|
||||||
|
/* Preserve only the first non-zero returned value. */
|
||||||
|
if (!saved_ret)
|
||||||
|
saved_ret = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
total += record.size;
|
total += record.size;
|
||||||
part++;
|
part++;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
|
spin_unlock_irqrestore(&psinfo->buf_lock, flags);
|
||||||
|
|
||||||
|
if (saved_ret) {
|
||||||
|
pr_err_once("backend (%s) writing error (%d)\n", psinfo->name,
|
||||||
|
saved_ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kmsg_dumper pstore_dumper = {
|
static struct kmsg_dumper pstore_dumper = {
|
||||||
|
@ -562,8 +574,9 @@ out:
|
||||||
int pstore_register(struct pstore_info *psi)
|
int pstore_register(struct pstore_info *psi)
|
||||||
{
|
{
|
||||||
if (backend && strcmp(backend, psi->name)) {
|
if (backend && strcmp(backend, psi->name)) {
|
||||||
pr_warn("ignoring unexpected backend '%s'\n", psi->name);
|
pr_warn("backend '%s' already in use: ignoring '%s'\n",
|
||||||
return -EPERM;
|
backend, psi->name);
|
||||||
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check flags. */
|
/* Sanity check flags. */
|
||||||
|
@ -662,6 +675,8 @@ void pstore_unregister(struct pstore_info *psi)
|
||||||
psinfo = NULL;
|
psinfo = NULL;
|
||||||
kfree(backend);
|
kfree(backend);
|
||||||
backend = NULL;
|
backend = NULL;
|
||||||
|
|
||||||
|
pr_info("Unregistered %s as persistent store backend\n", psi->name);
|
||||||
mutex_unlock(&psinfo_lock);
|
mutex_unlock(&psinfo_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pstore_unregister);
|
EXPORT_SYMBOL_GPL(pstore_unregister);
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/pstore_ram.h>
|
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "ram_internal.h"
|
||||||
|
|
||||||
#define RAMOOPS_KERNMSG_HDR "===="
|
#define RAMOOPS_KERNMSG_HDR "===="
|
||||||
#define MIN_MEM_SIZE 4096UL
|
#define MIN_MEM_SIZE 4096UL
|
||||||
|
@ -451,20 +452,28 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Free pmsg PRZ */
|
||||||
|
persistent_ram_free(&cxt->mprz);
|
||||||
|
|
||||||
|
/* Free console PRZ */
|
||||||
|
persistent_ram_free(&cxt->cprz);
|
||||||
|
|
||||||
/* Free dump PRZs */
|
/* Free dump PRZs */
|
||||||
if (cxt->dprzs) {
|
if (cxt->dprzs) {
|
||||||
for (i = 0; i < cxt->max_dump_cnt; i++)
|
for (i = 0; i < cxt->max_dump_cnt; i++)
|
||||||
persistent_ram_free(cxt->dprzs[i]);
|
persistent_ram_free(&cxt->dprzs[i]);
|
||||||
|
|
||||||
kfree(cxt->dprzs);
|
kfree(cxt->dprzs);
|
||||||
|
cxt->dprzs = NULL;
|
||||||
cxt->max_dump_cnt = 0;
|
cxt->max_dump_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free ftrace PRZs */
|
/* Free ftrace PRZs */
|
||||||
if (cxt->fprzs) {
|
if (cxt->fprzs) {
|
||||||
for (i = 0; i < cxt->max_ftrace_cnt; i++)
|
for (i = 0; i < cxt->max_ftrace_cnt; i++)
|
||||||
persistent_ram_free(cxt->fprzs[i]);
|
persistent_ram_free(&cxt->fprzs[i]);
|
||||||
kfree(cxt->fprzs);
|
kfree(cxt->fprzs);
|
||||||
|
cxt->fprzs = NULL;
|
||||||
cxt->max_ftrace_cnt = 0;
|
cxt->max_ftrace_cnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,9 +557,10 @@ static int ramoops_init_przs(const char *name,
|
||||||
|
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
i--;
|
i--;
|
||||||
persistent_ram_free(prz_ar[i]);
|
persistent_ram_free(&prz_ar[i]);
|
||||||
}
|
}
|
||||||
kfree(prz_ar);
|
kfree(prz_ar);
|
||||||
|
prz_ar = NULL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
*paddr += zone_sz;
|
*paddr += zone_sz;
|
||||||
|
@ -735,6 +745,7 @@ static int ramoops_probe(struct platform_device *pdev)
|
||||||
/* Make sure we didn't get bogus platform data pointer. */
|
/* Make sure we didn't get bogus platform data pointer. */
|
||||||
if (!pdata) {
|
if (!pdata) {
|
||||||
pr_err("NULL platform data\n");
|
pr_err("NULL platform data\n");
|
||||||
|
err = -EINVAL;
|
||||||
goto fail_out;
|
goto fail_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,6 +753,7 @@ static int ramoops_probe(struct platform_device *pdev)
|
||||||
!pdata->ftrace_size && !pdata->pmsg_size)) {
|
!pdata->ftrace_size && !pdata->pmsg_size)) {
|
||||||
pr_err("The memory size and the record/console size must be "
|
pr_err("The memory size and the record/console size must be "
|
||||||
"non-zero\n");
|
"non-zero\n");
|
||||||
|
err = -EINVAL;
|
||||||
goto fail_out;
|
goto fail_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,12 +784,17 @@ static int ramoops_probe(struct platform_device *pdev)
|
||||||
dump_mem_sz, cxt->record_size,
|
dump_mem_sz, cxt->record_size,
|
||||||
&cxt->max_dump_cnt, 0, 0);
|
&cxt->max_dump_cnt, 0, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail_out;
|
goto fail_init;
|
||||||
|
|
||||||
err = ramoops_init_prz("console", dev, cxt, &cxt->cprz, &paddr,
|
err = ramoops_init_prz("console", dev, cxt, &cxt->cprz, &paddr,
|
||||||
cxt->console_size, 0);
|
cxt->console_size, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail_init_cprz;
|
goto fail_init;
|
||||||
|
|
||||||
|
err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
|
||||||
|
cxt->pmsg_size, 0);
|
||||||
|
if (err)
|
||||||
|
goto fail_init;
|
||||||
|
|
||||||
cxt->max_ftrace_cnt = (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
|
cxt->max_ftrace_cnt = (cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
|
||||||
? nr_cpu_ids
|
? nr_cpu_ids
|
||||||
|
@ -788,12 +805,7 @@ static int ramoops_probe(struct platform_device *pdev)
|
||||||
(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
|
(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)
|
||||||
? PRZ_FLAG_NO_LOCK : 0);
|
? PRZ_FLAG_NO_LOCK : 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail_init_fprz;
|
goto fail_init;
|
||||||
|
|
||||||
err = ramoops_init_prz("pmsg", dev, cxt, &cxt->mprz, &paddr,
|
|
||||||
cxt->pmsg_size, 0);
|
|
||||||
if (err)
|
|
||||||
goto fail_init_mprz;
|
|
||||||
|
|
||||||
cxt->pstore.data = cxt;
|
cxt->pstore.data = cxt;
|
||||||
/*
|
/*
|
||||||
|
@ -857,11 +869,7 @@ fail_buf:
|
||||||
kfree(cxt->pstore.buf);
|
kfree(cxt->pstore.buf);
|
||||||
fail_clear:
|
fail_clear:
|
||||||
cxt->pstore.bufsize = 0;
|
cxt->pstore.bufsize = 0;
|
||||||
persistent_ram_free(cxt->mprz);
|
fail_init:
|
||||||
fail_init_mprz:
|
|
||||||
fail_init_fprz:
|
|
||||||
persistent_ram_free(cxt->cprz);
|
|
||||||
fail_init_cprz:
|
|
||||||
ramoops_free_przs(cxt);
|
ramoops_free_przs(cxt);
|
||||||
fail_out:
|
fail_out:
|
||||||
return err;
|
return err;
|
||||||
|
@ -876,8 +884,6 @@ static int ramoops_remove(struct platform_device *pdev)
|
||||||
kfree(cxt->pstore.buf);
|
kfree(cxt->pstore.buf);
|
||||||
cxt->pstore.bufsize = 0;
|
cxt->pstore.bufsize = 0;
|
||||||
|
|
||||||
persistent_ram_free(cxt->mprz);
|
|
||||||
persistent_ram_free(cxt->cprz);
|
|
||||||
ramoops_free_przs(cxt);
|
ramoops_free_przs(cxt);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/pstore_ram.h>
|
|
||||||
#include <linux/rslib.h>
|
#include <linux/rslib.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
|
||||||
|
#include "ram_internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct persistent_ram_buffer - persistent circular RAM buffer
|
* struct persistent_ram_buffer - persistent circular RAM buffer
|
||||||
*
|
*
|
||||||
|
@ -439,7 +440,11 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
|
||||||
phys_addr_t addr = page_start + i * PAGE_SIZE;
|
phys_addr_t addr = page_start + i * PAGE_SIZE;
|
||||||
pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
|
pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
|
||||||
}
|
}
|
||||||
vaddr = vmap(pages, page_count, VM_MAP, prot);
|
/*
|
||||||
|
* VM_IOREMAP used here to bypass this region during vread()
|
||||||
|
* and kmap_atomic() (i.e. kcore) to avoid __va() failures.
|
||||||
|
*/
|
||||||
|
vaddr = vmap(pages, page_count, VM_MAP | VM_IOREMAP, prot);
|
||||||
kfree(pages);
|
kfree(pages);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -543,8 +548,14 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void persistent_ram_free(struct persistent_ram_zone *prz)
|
void persistent_ram_free(struct persistent_ram_zone **_prz)
|
||||||
{
|
{
|
||||||
|
struct persistent_ram_zone *prz;
|
||||||
|
|
||||||
|
if (!_prz)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prz = *_prz;
|
||||||
if (!prz)
|
if (!prz)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -568,6 +579,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
|
||||||
persistent_ram_free_old(prz);
|
persistent_ram_free_old(prz);
|
||||||
kfree(prz->label);
|
kfree(prz->label);
|
||||||
kfree(prz);
|
kfree(prz);
|
||||||
|
*_prz = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
||||||
|
@ -604,6 +616,6 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
||||||
|
|
||||||
return prz;
|
return prz;
|
||||||
err:
|
err:
|
||||||
persistent_ram_free(prz);
|
persistent_ram_free(&prz);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
98
fs/pstore/ram_internal.h
Normal file
98
fs/pstore/ram_internal.h
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
|
||||||
|
* Copyright (C) 2011 Kees Cook <keescook@chromium.org>
|
||||||
|
* Copyright (C) 2011 Google, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/pstore_ram.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Choose whether access to the RAM zone requires locking or not. If a zone
|
||||||
|
* can be written to from different CPUs like with ftrace for example, then
|
||||||
|
* PRZ_FLAG_NO_LOCK is used. For all other cases, locking is required.
|
||||||
|
*/
|
||||||
|
#define PRZ_FLAG_NO_LOCK BIT(0)
|
||||||
|
/*
|
||||||
|
* If a PRZ should only have a single-boot lifetime, this marks it as
|
||||||
|
* getting wiped after its contents get copied out after boot.
|
||||||
|
*/
|
||||||
|
#define PRZ_FLAG_ZAP_OLD BIT(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct persistent_ram_zone - Details of a persistent RAM zone (PRZ)
|
||||||
|
* used as a pstore backend
|
||||||
|
*
|
||||||
|
* @paddr: physical address of the mapped RAM area
|
||||||
|
* @size: size of mapping
|
||||||
|
* @label: unique name of this PRZ
|
||||||
|
* @type: frontend type for this PRZ
|
||||||
|
* @flags: holds PRZ_FLAGS_* bits
|
||||||
|
*
|
||||||
|
* @buffer_lock:
|
||||||
|
* locks access to @buffer "size" bytes and "start" offset
|
||||||
|
* @buffer:
|
||||||
|
* pointer to actual RAM area managed by this PRZ
|
||||||
|
* @buffer_size:
|
||||||
|
* bytes in @buffer->data (not including any trailing ECC bytes)
|
||||||
|
*
|
||||||
|
* @par_buffer:
|
||||||
|
* pointer into @buffer->data containing ECC bytes for @buffer->data
|
||||||
|
* @par_header:
|
||||||
|
* pointer into @buffer->data containing ECC bytes for @buffer header
|
||||||
|
* (i.e. all fields up to @data)
|
||||||
|
* @rs_decoder:
|
||||||
|
* RSLIB instance for doing ECC calculations
|
||||||
|
* @corrected_bytes:
|
||||||
|
* ECC corrected bytes accounting since boot
|
||||||
|
* @bad_blocks:
|
||||||
|
* ECC uncorrectable bytes accounting since boot
|
||||||
|
* @ecc_info:
|
||||||
|
* ECC configuration details
|
||||||
|
*
|
||||||
|
* @old_log:
|
||||||
|
* saved copy of @buffer->data prior to most recent wipe
|
||||||
|
* @old_log_size:
|
||||||
|
* bytes contained in @old_log
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct persistent_ram_zone {
|
||||||
|
phys_addr_t paddr;
|
||||||
|
size_t size;
|
||||||
|
void *vaddr;
|
||||||
|
char *label;
|
||||||
|
enum pstore_type_id type;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
|
raw_spinlock_t buffer_lock;
|
||||||
|
struct persistent_ram_buffer *buffer;
|
||||||
|
size_t buffer_size;
|
||||||
|
|
||||||
|
char *par_buffer;
|
||||||
|
char *par_header;
|
||||||
|
struct rs_control *rs_decoder;
|
||||||
|
int corrected_bytes;
|
||||||
|
int bad_blocks;
|
||||||
|
struct persistent_ram_ecc_info ecc_info;
|
||||||
|
|
||||||
|
char *old_log;
|
||||||
|
size_t old_log_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
||||||
|
u32 sig, struct persistent_ram_ecc_info *ecc_info,
|
||||||
|
unsigned int memtype, u32 flags, char *label);
|
||||||
|
void persistent_ram_free(struct persistent_ram_zone **_prz);
|
||||||
|
void persistent_ram_zap(struct persistent_ram_zone *prz);
|
||||||
|
|
||||||
|
int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
|
||||||
|
unsigned int count);
|
||||||
|
int persistent_ram_write_user(struct persistent_ram_zone *prz,
|
||||||
|
const void __user *s, unsigned int count);
|
||||||
|
|
||||||
|
void persistent_ram_save_old(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_free_old(struct persistent_ram_zone *prz);
|
||||||
|
ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
|
||||||
|
char *str, size_t len);
|
|
@ -761,7 +761,7 @@ static inline int notrace psz_kmsg_write_record(struct psz_context *cxt,
|
||||||
/* avoid destroying old data, allocate a new one */
|
/* avoid destroying old data, allocate a new one */
|
||||||
len = zone->buffer_size + sizeof(*zone->buffer);
|
len = zone->buffer_size + sizeof(*zone->buffer);
|
||||||
zone->oldbuf = zone->buffer;
|
zone->oldbuf = zone->buffer;
|
||||||
zone->buffer = kzalloc(len, GFP_KERNEL);
|
zone->buffer = kzalloc(len, GFP_ATOMIC);
|
||||||
if (!zone->buffer) {
|
if (!zone->buffer) {
|
||||||
zone->buffer = zone->oldbuf;
|
zone->buffer = zone->oldbuf;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -8,28 +8,7 @@
|
||||||
#ifndef __LINUX_PSTORE_RAM_H__
|
#ifndef __LINUX_PSTORE_RAM_H__
|
||||||
#define __LINUX_PSTORE_RAM_H__
|
#define __LINUX_PSTORE_RAM_H__
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/pstore.h>
|
#include <linux/pstore.h>
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Choose whether access to the RAM zone requires locking or not. If a zone
|
|
||||||
* can be written to from different CPUs like with ftrace for example, then
|
|
||||||
* PRZ_FLAG_NO_LOCK is used. For all other cases, locking is required.
|
|
||||||
*/
|
|
||||||
#define PRZ_FLAG_NO_LOCK BIT(0)
|
|
||||||
/*
|
|
||||||
* If a PRZ should only have a single-boot lifetime, this marks it as
|
|
||||||
* getting wiped after its contents get copied out after boot.
|
|
||||||
*/
|
|
||||||
#define PRZ_FLAG_ZAP_OLD BIT(1)
|
|
||||||
|
|
||||||
struct persistent_ram_buffer;
|
|
||||||
struct rs_control;
|
|
||||||
|
|
||||||
struct persistent_ram_ecc_info {
|
struct persistent_ram_ecc_info {
|
||||||
int block_size;
|
int block_size;
|
||||||
|
@ -39,84 +18,6 @@ struct persistent_ram_ecc_info {
|
||||||
uint16_t *par;
|
uint16_t *par;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct persistent_ram_zone - Details of a persistent RAM zone (PRZ)
|
|
||||||
* used as a pstore backend
|
|
||||||
*
|
|
||||||
* @paddr: physical address of the mapped RAM area
|
|
||||||
* @size: size of mapping
|
|
||||||
* @label: unique name of this PRZ
|
|
||||||
* @type: frontend type for this PRZ
|
|
||||||
* @flags: holds PRZ_FLAGS_* bits
|
|
||||||
*
|
|
||||||
* @buffer_lock:
|
|
||||||
* locks access to @buffer "size" bytes and "start" offset
|
|
||||||
* @buffer:
|
|
||||||
* pointer to actual RAM area managed by this PRZ
|
|
||||||
* @buffer_size:
|
|
||||||
* bytes in @buffer->data (not including any trailing ECC bytes)
|
|
||||||
*
|
|
||||||
* @par_buffer:
|
|
||||||
* pointer into @buffer->data containing ECC bytes for @buffer->data
|
|
||||||
* @par_header:
|
|
||||||
* pointer into @buffer->data containing ECC bytes for @buffer header
|
|
||||||
* (i.e. all fields up to @data)
|
|
||||||
* @rs_decoder:
|
|
||||||
* RSLIB instance for doing ECC calculations
|
|
||||||
* @corrected_bytes:
|
|
||||||
* ECC corrected bytes accounting since boot
|
|
||||||
* @bad_blocks:
|
|
||||||
* ECC uncorrectable bytes accounting since boot
|
|
||||||
* @ecc_info:
|
|
||||||
* ECC configuration details
|
|
||||||
*
|
|
||||||
* @old_log:
|
|
||||||
* saved copy of @buffer->data prior to most recent wipe
|
|
||||||
* @old_log_size:
|
|
||||||
* bytes contained in @old_log
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct persistent_ram_zone {
|
|
||||||
phys_addr_t paddr;
|
|
||||||
size_t size;
|
|
||||||
void *vaddr;
|
|
||||||
char *label;
|
|
||||||
enum pstore_type_id type;
|
|
||||||
u32 flags;
|
|
||||||
|
|
||||||
raw_spinlock_t buffer_lock;
|
|
||||||
struct persistent_ram_buffer *buffer;
|
|
||||||
size_t buffer_size;
|
|
||||||
|
|
||||||
char *par_buffer;
|
|
||||||
char *par_header;
|
|
||||||
struct rs_control *rs_decoder;
|
|
||||||
int corrected_bytes;
|
|
||||||
int bad_blocks;
|
|
||||||
struct persistent_ram_ecc_info ecc_info;
|
|
||||||
|
|
||||||
char *old_log;
|
|
||||||
size_t old_log_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
|
||||||
u32 sig, struct persistent_ram_ecc_info *ecc_info,
|
|
||||||
unsigned int memtype, u32 flags, char *label);
|
|
||||||
void persistent_ram_free(struct persistent_ram_zone *prz);
|
|
||||||
void persistent_ram_zap(struct persistent_ram_zone *prz);
|
|
||||||
|
|
||||||
int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
|
|
||||||
unsigned int count);
|
|
||||||
int persistent_ram_write_user(struct persistent_ram_zone *prz,
|
|
||||||
const void __user *s, unsigned int count);
|
|
||||||
|
|
||||||
void persistent_ram_save_old(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_free_old(struct persistent_ram_zone *prz);
|
|
||||||
ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz,
|
|
||||||
char *str, size_t len);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ramoops platform data
|
* Ramoops platform data
|
||||||
* @mem_size memory size for ramoops
|
* @mem_size memory size for ramoops
|
||||||
|
|
Loading…
Reference in New Issue
Block a user