All of lore.kernel.org
 help / color / mirror / Atom feed
From: Victor Hassan <victor@allwinnertech.com>
To: keescook@chromium.org
Cc: tony.luck@intel.com, gpiccoli@igalia.com,
	linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] pstore/blk: Export a method to implemente panic_write()
Date: Fri,  3 Feb 2023 19:35:15 +0800	[thread overview]
Message-ID: <20230203113515.93540-1-victor@allwinnertech.com> (raw)

The panic_write() is necessary to write the pstore frontend message
to blk devices when panic. Here is a way to register panic_write when
we use "best_effort" way to register the pstore blk-backend.

Usage:

    xx_register_pstore_panic_write(pstore_blk_notifier_type type,
	    struct pstore_device_info *pdi)
    {
	switch (type) {
	case PSTORE_BLK_BACKEND_REGISTER:
	case PSTORE_BLK_BACKEND_PANIC_DRV_REGISTER:
	    ...

	    pid->zone.panic_write = xxx;

	    ...
	    break;
	case PSTORE_BLK_BACKEND_UNREGISTER:
	case PSTORE_BLK_BACKEND_PANIC_DRV_UNREGISTER:
	    ...

	    pdi->zone.panic_write = NULL;

	    ...
	    break;
	default:
	    break;
	}

    }

    static struct pstore_blk_notifier pbn = {
	.notitifer_call = xx_register_pstore_panic_write;
    }

    use {un,}register_pstore_blk_panic_notifier() to register/unregister
    pstore_blk_notifier

Signed-off-by: Victor Hassan <victor@allwinnertech.com>
---
 fs/pstore/blk.c            | 101 +++++++++++++++++++++++++++++++++++--
 include/linux/pstore_blk.h |  19 +++++++
 2 files changed, 116 insertions(+), 4 deletions(-)

diff --git a/fs/pstore/blk.c b/fs/pstore/blk.c
index 4ae0cfcd15f2..2c70a3bff1ae 100644
--- a/fs/pstore/blk.c
+++ b/fs/pstore/blk.c
@@ -18,6 +18,7 @@
 #include <linux/file.h>
 #include <linux/init_syscalls.h>
 #include <linux/mount.h>
+#include <linux/notifier.h>
 
 static long kmsg_size = CONFIG_PSTORE_BLK_KMSG_SIZE;
 module_param(kmsg_size, long, 0400);
@@ -72,6 +73,14 @@ static DEFINE_MUTEX(pstore_blk_lock);
 static struct file *psblk_file;
 static struct pstore_device_info *pstore_device_info;
 
+static struct {
+	struct raw_notifier_head chain;
+	struct pstore_blk_notifier *pbn;
+	bool notifier;
+} pstore_blk_panic_notifier = {
+	.chain = RAW_NOTIFIER_INIT(pstore_blk_panic_notifier.chain),
+};
+
 #define check_size(name, alignsize) ({				\
 	long _##name_ = (name);					\
 	_##name_ = _##name_ <= 0 ? 0 : (_##name_ * 1024);	\
@@ -94,6 +103,82 @@ static struct pstore_device_info *pstore_device_info;
 	dev->zone.name = _##name_;				\
 }
 
+static int pstore_blk_panic_notifier_call(struct notifier_block *nb,
+			     unsigned long action, void *data)
+{
+	int ret = 0;
+	struct pstore_blk_notifier *pbn =
+				container_of(nb, struct pstore_blk_notifier, nb);
+
+	if (pbn)
+		ret = pbn->notifier_call(action, data);
+
+	return ret;
+}
+
+int register_pstore_blk_panic_notifier(struct pstore_blk_notifier *pbn)
+{
+	int err = 0;
+	struct notifier_block *nb;
+
+	mutex_lock(&pstore_blk_lock);
+
+	if (pstore_blk_panic_notifier.notifier) {
+		pr_info("had register panic\n");
+		goto unlock;
+	}
+
+	nb = &pbn->nb;
+	nb->notifier_call = pstore_blk_panic_notifier_call;
+
+	err = raw_notifier_chain_register(&pstore_blk_panic_notifier.chain, nb);
+	if (err)
+		goto unlock;
+
+	if (pstore_device_info)
+		err = nb->notifier_call(nb, PSTORE_BLK_BACKEND_PANIC_DRV_REGISTER,
+				pstore_device_info);
+
+	if (!err)
+		pstore_blk_panic_notifier.notifier = true;
+
+unlock:
+	mutex_unlock(&pstore_blk_lock);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(register_pstore_blk_panic_notifier);
+
+void unregister_pstore_blk_panic_notifier(struct pstore_blk_notifier *pbn)
+{
+	struct notifier_block *nb = &pbn->nb;
+
+	mutex_lock(&pstore_blk_lock);
+
+	raw_notifier_chain_unregister(&pstore_blk_panic_notifier.chain, nb);
+
+	if (pstore_device_info)
+		nb->notifier_call(nb, PSTORE_BLK_BACKEND_PANIC_DRV_UNREGISTER,
+				pstore_device_info);
+
+	pstore_blk_panic_notifier.notifier = false;
+
+	mutex_unlock(&pstore_blk_lock);
+}
+EXPORT_SYMBOL_GPL(unregister_pstore_blk_panic_notifier);
+
+static int pstore_blk_panic_notifier_init_call(struct pstore_device_info *pdi)
+{
+	return raw_notifier_call_chain(&pstore_blk_panic_notifier.chain,
+			PSTORE_BLK_BACKEND_REGISTER, pdi);
+}
+
+static int pstore_blk_panic_notifier_exit_call(struct pstore_device_info *pdi)
+{
+	return raw_notifier_call_chain(&pstore_blk_panic_notifier.chain,
+			PSTORE_BLK_BACKEND_UNREGISTER, pdi);
+}
+
 static int __register_pstore_device(struct pstore_device_info *dev)
 {
 	int ret;
@@ -301,16 +386,22 @@ static int __init __best_effort_init(void)
 	if (!best_effort_dev)
 		return -ENOMEM;
 
+	strcpy(best_effort_dev->path, blkdev);
 	best_effort_dev->zone.read = psblk_generic_blk_read;
 	best_effort_dev->zone.write = psblk_generic_blk_write;
 
 	ret = __register_pstore_blk(best_effort_dev,
 				    early_boot_devpath(blkdev));
-	if (ret)
+	if (ret) {
 		kfree(best_effort_dev);
-	else
-		pr_info("attached %s (%lu) (no dedicated panic_write!)\n",
-			blkdev, best_effort_dev->zone.total_size);
+	} else {
+		if (pstore_blk_panic_notifier_init_call(best_effort_dev) == NOTIFY_OK)
+			pr_info("attached %s (%lu) (dedicated panic_write!)\n",
+				    blkdev, best_effort_dev->zone.total_size);
+		else
+			pr_info("attached %s (%lu) (no dedicated panic_write!)\n",
+				    blkdev, best_effort_dev->zone.total_size);
+	}
 
 	return ret;
 }
@@ -326,6 +417,8 @@ static void __exit __best_effort_exit(void)
 	if (psblk_file) {
 		struct pstore_device_info *dev = pstore_device_info;
 
+		pstore_blk_panic_notifier_exit_call(dev);
+
 		__unregister_pstore_device(dev);
 		kfree(dev);
 		fput(psblk_file);
diff --git a/include/linux/pstore_blk.h b/include/linux/pstore_blk.h
index 924ca07aafbd..4c1fc8debdc7 100644
--- a/include/linux/pstore_blk.h
+++ b/include/linux/pstore_blk.h
@@ -17,13 +17,32 @@
  *
  */
 struct pstore_device_info {
+	char path[80];
 	unsigned int flags;
 	struct pstore_zone_info zone;
 };
 
+enum pstore_blk_notifier_type {
+	PSTORE_BLK_BACKEND_REGISTER = 1,
+	PSTORE_BLK_BACKEND_PANIC_DRV_REGISTER,
+	PSTORE_BLK_BACKEND_UNREGISTER,
+	PSTORE_BLK_BACKEND_PANIC_DRV_UNREGISTER,
+};
+
+typedef	int (*pstore_blk_notifier_fn_t)(pstore_blk_notifier_type type,
+		struct pstore_device_info *dev);
+
+struct pstore_blk_notifier {
+	struct notifier_block nb;
+	pstore_blk_notifier_fn_t notifier_call;
+};
+
 int  register_pstore_device(struct pstore_device_info *dev);
 void unregister_pstore_device(struct pstore_device_info *dev);
 
+int register_pstore_blk_panic_notifier(struct pstore_blk_notifier *pbn);
+void unregister_pstore_blk_panic_notifier(struct pstore_blk_notifier *nb);
+
 /**
  * struct pstore_blk_config - the pstore_blk backend configuration
  *
-- 
2.29.0


             reply	other threads:[~2023-02-03 11:35 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-03 11:35 Victor Hassan [this message]
2023-02-03 19:57 ` [PATCH] pstore/blk: Export a method to implemente panic_write() kernel test robot
2023-02-03 21:19 ` kernel test robot

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=20230203113515.93540-1-victor@allwinnertech.com \
    --to=victor@allwinnertech.com \
    --cc=gpiccoli@igalia.com \
    --cc=keescook@chromium.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.