From: Eugen Hristev <eugen.hristev@linaro.org>
To: linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org,
kees@kernel.org
Cc: linux-kernel@vger.kernel.org, johannes@sipsolutions.net,
gregkh@linuxfoundation.org, rafael@kernel.org, dakr@kernel.org,
andersson@kernel.org, konradybcio@kernel.org,
tony.luck@intel.com, gpiccoli@igalia.com, pmladek@suse.com,
rostedt@goodmis.org, john.ogness@linutronix.de,
senozhatsky@chromium.org, quic_mojha@quicinc.com,
linux-arm-kernel@lists.infradead.org, kernel@quicinc.com,
Eugen Hristev <eugen.hristev@linaro.org>
Subject: [RFC][PATCH 03/10] pstore/zone: introduce directly mapped zones
Date: Mon, 17 Feb 2025 12:16:59 +0200 [thread overview]
Message-ID: <20250217101706.2104498-4-eugen.hristev@linaro.org> (raw)
In-Reply-To: <20250217101706.2104498-1-eugen.hristev@linaro.org>
Directly mapped zones have a different semantic from usual pstore zones.
Such zones use a pointer to data in their buffer struct, instead of
keeping the buffer locally.
The data pointer and size is then passed to the backend for further use.
Having a different semantics, backends supporting only these do not offer
read/write ops, and only new register_dmr and unregister_dmr ops.
Ofcourse, a backend could support both classic zones and directly mapped.
Directly mapped zones have the advantage of not being passed through
in the event of a crashed, but rather at registration time.
Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
---
fs/pstore/platform.c | 1 +
fs/pstore/smem.c | 6 ++---
fs/pstore/zone.c | 45 ++++++++++++++++++++++++++++---------
include/linux/pstore.h | 4 ++++
include/linux/pstore_zone.h | 3 +++
5 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index f56b066ab80c..e20e60b88727 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -51,6 +51,7 @@ static const char * const pstore_type_names[] = {
"powerpc-common",
"pmsg",
"powerpc-opal",
+ "directly-mapped",
};
static int pstore_new_entry;
diff --git a/fs/pstore/smem.c b/fs/pstore/smem.c
index 9eedd7df5446..684ecc20cae5 100644
--- a/fs/pstore/smem.c
+++ b/fs/pstore/smem.c
@@ -36,15 +36,15 @@ static int __register_pstore_device(struct pstore_device_info *dev)
pr_err("NULL device info\n");
return -EINVAL;
}
- if (!dev->zone.total_size) {
+ if (!dev->zone.total_size && !dev->zone.dmapped_cnt) {
pr_err("zero sized device\n");
return -EINVAL;
}
- if (!dev->zone.read) {
+ if (!dev->zone.read && !dev->zone.dmapped_cnt) {
pr_err("no read handler for device\n");
return -EINVAL;
}
- if (!dev->zone.write) {
+ if (!dev->zone.write && !dev->zone.dmapped_cnt) {
pr_err("no write handler for device\n");
return -EINVAL;
}
diff --git a/fs/pstore/zone.c b/fs/pstore/zone.c
index 5fa2fa2e7aa7..affa4370208c 100644
--- a/fs/pstore/zone.c
+++ b/fs/pstore/zone.c
@@ -113,6 +113,7 @@ struct psz_context {
struct pstore_zone *ppsz;
struct pstore_zone *cpsz;
struct pstore_zone **fpszs;
+ struct pstore_zone **dmszs;
unsigned int kmsg_max_cnt;
unsigned int kmsg_read_cnt;
unsigned int kmsg_write_cnt;
@@ -120,6 +121,7 @@ struct psz_context {
unsigned int console_read_cnt;
unsigned int ftrace_max_cnt;
unsigned int ftrace_read_cnt;
+ unsigned int dmapped_max_cnt;
/*
* These counters should be calculated during recovery.
* It records the oops/panic times after crashes rather than boots.
@@ -1148,6 +1150,8 @@ static void psz_free_all_zones(struct psz_context *cxt)
psz_free_zone(&cxt->cpsz);
if (cxt->fpszs)
psz_free_zones(&cxt->fpszs, &cxt->ftrace_max_cnt);
+ if (cxt->dmszs)
+ psz_free_zones(&cxt->dmszs, &cxt->dmapped_max_cnt);
}
static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
@@ -1160,9 +1164,9 @@ static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
if (!size)
return NULL;
- if (*off + size > info->total_size) {
- pr_err("no room for %s (0x%zx@0x%llx over 0x%lx)\n",
- name, size, *off, info->total_size);
+ if (*off + size > info->total_size && type != PSTORE_TYPE_DMAPPED) {
+ pr_err("no room for %s type %d (0x%zx@0x%llx over 0x%lx)\n",
+ name, type, size, *off, info->total_size);
return ERR_PTR(-ENOMEM);
}
@@ -1170,7 +1174,8 @@ static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
if (!zone)
return ERR_PTR(-ENOMEM);
- zone->buffer = kmalloc(size, GFP_KERNEL);
+ zone->buffer = kmalloc(type == PSTORE_TYPE_DMAPPED ?
+ sizeof(struct psz_buffer) : size, GFP_KERNEL);
if (!zone->buffer) {
kfree(zone);
return ERR_PTR(-ENOMEM);
@@ -1179,7 +1184,10 @@ static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
zone->off = *off;
zone->name = name;
zone->type = type;
- zone->buffer_size = size - sizeof(struct psz_buffer);
+ if (zone->type == PSTORE_TYPE_DMAPPED)
+ zone->buffer_size = 0;
+ else
+ zone->buffer_size = size - sizeof(struct psz_buffer);
zone->buffer->sig = type ^ PSZ_SIG;
zone->oldbuf = NULL;
atomic_set(&zone->dirty, 0);
@@ -1188,8 +1196,9 @@ static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
*off += size;
- pr_debug("pszone %s: off 0x%llx, %zu header, %zu data\n", zone->name,
- zone->off, sizeof(*zone->buffer), zone->buffer_size);
+ pr_debug("pszone %s: off 0x%llx, %zu header, %zu data %s\n", zone->name,
+ zone->off, sizeof(*zone->buffer), zone->buffer_size,
+ zone->type == PSTORE_TYPE_DMAPPED ? " dmapped " : "");
return zone;
}
@@ -1206,7 +1215,7 @@ static struct pstore_zone **psz_init_zones(enum pstore_type_id type,
if (!total_size || !record_size)
return NULL;
- if (*off + total_size > info->total_size) {
+ if (*off + total_size > info->total_size && type != PSTORE_TYPE_DMAPPED) {
pr_err("no room for zones %s (0x%zx@0x%llx over 0x%lx)\n",
name, total_size, *off, info->total_size);
return ERR_PTR(-ENOMEM);
@@ -1245,6 +1254,15 @@ static int psz_alloc_zones(struct psz_context *cxt)
int err;
size_t off_size = 0;
+ cxt->dmszs = psz_init_zones(PSTORE_TYPE_DMAPPED, &off,
+ info->dmapped_cnt,
+ 1, &cxt->dmapped_max_cnt);
+ if (IS_ERR(cxt->dmszs)) {
+ err = PTR_ERR(cxt->dmszs);
+ cxt->dmszs = NULL;
+ goto free_out;
+ }
+
off_size += info->pmsg_size;
cxt->ppsz = psz_init_zone(PSTORE_TYPE_PMSG, &off, info->pmsg_size);
if (IS_ERR(cxt->ppsz)) {
@@ -1302,7 +1320,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
int err = -EINVAL;
struct psz_context *cxt = &pstore_zone_cxt;
- if (info->total_size < 4096) {
+ if (info->total_size < 4096 && !info->dmapped_cnt) {
pr_warn("total_size must be >= 4096\n");
return -EINVAL;
}
@@ -1312,7 +1330,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
}
if (!info->kmsg_size && !info->pmsg_size && !info->console_size &&
- !info->ftrace_size) {
+ !info->ftrace_size && !info->dmapped_cnt) {
pr_warn("at least one record size must be non-zero\n");
return -EINVAL;
}
@@ -1345,7 +1363,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
* if no @read, pstore may mount failed.
* if no @write, pstore do not support to remove record file.
*/
- if (!info->read || !info->write) {
+ if (!info->dmapped_cnt && (!info->read || !info->write)) {
pr_err("no valid general read/write interface\n");
return -EINVAL;
}
@@ -1365,6 +1383,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
pr_debug("\tpmsg size : %ld Bytes\n", info->pmsg_size);
pr_debug("\tconsole size : %ld Bytes\n", info->console_size);
pr_debug("\tftrace size : %ld Bytes\n", info->ftrace_size);
+ pr_debug("\tdmapped areas : %ld\n", info->dmapped_cnt);
err = psz_alloc_zones(cxt);
if (err) {
@@ -1406,6 +1425,10 @@ int register_pstore_zone(struct pstore_zone_info *info)
cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
pr_cont(" ftrace");
}
+ if (info->dmapped_cnt) {
+ cxt->pstore.flags |= PSTORE_FLAGS_DMAPPED;
+ pr_cont(" dmapped");
+ }
pr_cont("\n");
err = pstore_register(&cxt->pstore);
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index fed601053c51..8360d94c96b6 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -39,6 +39,7 @@ enum pstore_type_id {
PSTORE_TYPE_PMSG = 7,
PSTORE_TYPE_PPC_OPAL = 8,
+ PSTORE_TYPE_DMAPPED = 9,
/* End of the list */
PSTORE_TYPE_MAX
};
@@ -199,6 +200,8 @@ struct pstore_info {
int (*write_user)(struct pstore_record *record,
const char __user *buf);
int (*erase)(struct pstore_record *record);
+ int (*register_dmr)(struct pstore_record *record);
+ int (*unregister_dmr)(struct pstore_record *record);
};
/* Supported frontends */
@@ -206,6 +209,7 @@ struct pstore_info {
#define PSTORE_FLAGS_CONSOLE BIT(1)
#define PSTORE_FLAGS_FTRACE BIT(2)
#define PSTORE_FLAGS_PMSG BIT(3)
+#define PSTORE_FLAGS_DMAPPED BIT(4)
extern int pstore_register(struct pstore_info *);
extern void pstore_unregister(struct pstore_info *);
diff --git a/include/linux/pstore_zone.h b/include/linux/pstore_zone.h
index 284364234162..a74d0cc75577 100644
--- a/include/linux/pstore_zone.h
+++ b/include/linux/pstore_zone.h
@@ -48,10 +48,13 @@ struct pstore_zone_info {
unsigned long pmsg_size;
unsigned long console_size;
unsigned long ftrace_size;
+ unsigned long dmapped_cnt;
pstore_zone_read_op read;
pstore_zone_write_op write;
pstore_zone_erase_op erase;
pstore_zone_write_op panic_write;
+ int (*register_dmr)(char *, int, void *, size_t);
+ int (*unregister_dmr)(void *, size_t);
};
/**
--
2.43.0
next prev parent reply other threads:[~2025-02-17 10:17 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-17 10:16 [RFC][PATCH 00/10] pstore: directly mapped regions Eugen Hristev
2025-02-17 10:16 ` [RFC][PATCH 01/10] pstore/zone: move pstore_device_info into zone header Eugen Hristev
2025-02-17 10:16 ` [RFC][PATCH 02/10] pstore/smem: add new pstore/smem type of pstore Eugen Hristev
2025-02-17 10:16 ` Eugen Hristev [this message]
2025-02-17 10:17 ` [RFC][PATCH 04/10] qcom: smem: add pstore smem backend Eugen Hristev
2025-02-17 10:17 ` [RFC][PATCH 05/10] pstore: implement core area registration Eugen Hristev
2025-02-17 10:17 ` [RFC][PATCH 06/10] qcom: smem: enable smem pstore backend Eugen Hristev
2025-02-17 10:17 ` [RFC][PATCH 07/10] printk: export symbols for buffer address and length functions Eugen Hristev
2025-02-18 8:26 ` Christoph Hellwig
2025-02-18 8:58 ` Sergey Senozhatsky
2025-02-18 9:11 ` Eugen Hristev
2025-02-17 10:17 ` [RFC][PATCH 08/10] pstore: register kmsg into directly mapped zones if available Eugen Hristev
2025-02-17 10:17 ` [RFC][PATCH 09/10] devcoredump: add devcd_{un}register_core_area API Eugen Hristev
2025-02-17 10:17 ` [RFC][PATCH 10/10] rng: qcom_rng: EXAMPLE: registering dev structure Eugen Hristev
2025-02-17 10:23 ` [RFC][PATCH 00/10] pstore: directly mapped regions Johannes Berg
2025-02-17 10:44 ` Eugen Hristev
2025-02-17 11:19 ` Johannes Berg
2025-02-17 11:39 ` Eugen Hristev
2025-02-17 11:43 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250217101706.2104498-4-eugen.hristev@linaro.org \
--to=eugen.hristev@linaro.org \
--cc=andersson@kernel.org \
--cc=dakr@kernel.org \
--cc=gpiccoli@igalia.com \
--cc=gregkh@linuxfoundation.org \
--cc=johannes@sipsolutions.net \
--cc=john.ogness@linutronix.de \
--cc=kees@kernel.org \
--cc=kernel@quicinc.com \
--cc=konradybcio@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pmladek@suse.com \
--cc=quic_mojha@quicinc.com \
--cc=rafael@kernel.org \
--cc=rostedt@goodmis.org \
--cc=senozhatsky@chromium.org \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox