[PATCH v3 14/16] powernv/opalcore: provide an option to invalidate /sys/firmware/opal/core file
From: Hari Bathini <hbathini@linux.ibm.com>
Date: 2019-06-25 21:20:50
Subsystem:
linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Michael Ellerman, Linus Torvalds
Writing '1' to /sys/kernel/fadump_release_opalcore would release the memory held by kernel in exporting /sys/firmware/opal/core file. Signed-off-by: Hari Bathini <hbathini@linux.ibm.com> --- arch/powerpc/platforms/powernv/opal-core.c | 40 +++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index 56fb1cd..f3e336c 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c@@ -19,6 +19,8 @@ #include <linux/proc_fs.h> #include <linux/elf.h> #include <linux/elfcore.h> +#include <linux/kobject.h> +#include <linux/sysfs.h> #include <linux/slab.h> #include <linux/crash_core.h> #include <linux/of.h>
@@ -172,7 +174,7 @@ static ssize_t read_opalcore(struct file *file, struct kobject *kobj, if (pos >= oc_conf->opalcore_size) return 0; - /* Adjust count if it goes beyond opacore size */ + /* Adjust count if it goes beyond opalcore size */ avail = oc_conf->opalcore_size - pos; if (count > avail) count = avail;
@@ -559,6 +561,36 @@ static void opalcore_cleanup(void) } __exitcall(opalcore_cleanup); +static ssize_t fadump_release_opalcore_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int input = -1; + + if (kstrtoint(buf, 0, &input)) + return -EINVAL; + + if (input == 1) { + if (oc_conf == NULL) { + pr_err("'/proc/opalcore' file does not exist!\n"); + return -EPERM; + } + + /* + * Take away '/proc/opalcore' and release all memory + * used for exporting this file. + */ + opalcore_cleanup(); + } else + return -EINVAL; + + return count; +} + +static struct kobj_attribute opalcore_rel_attr = __ATTR(fadump_release_opalcore, + 0200, NULL, + fadump_release_opalcore_store); + /* Init function for opalcore module. */ static int __init opalcore_init(void) {
@@ -591,6 +623,12 @@ static int __init opalcore_init(void) return rc; } + rc = sysfs_create_file(kernel_kobj, &opalcore_rel_attr.attr); + if (rc) { + pr_warn("unable to create sysfs file fadump_release_opalcore (%d)\n", + rc); + } + return 0; } fs_initcall(opalcore_init);