powerpc/secvar: Extend sysfs to include config vars
authorRussell Currey <ruscur@russell.cc>
Fri, 10 Feb 2023 08:03:45 +0000 (19:03 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 12 Feb 2023 11:12:37 +0000 (22:12 +1100)
The forthcoming pseries consumer of the secvar API wants to expose a
number of config variables.  Allowing secvar implementations to provide
their own sysfs attributes makes it easy for consumers to expose what
they need to.

This is not being used by the OPAL secvar implementation at present, and
the config directory will not be created if no attributes are set.

Signed-off-by: Russell Currey <ruscur@russell.cc>
Co-developed-by: Andrew Donnellan <ajd@linux.ibm.com>
Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20230210080401.345462-11-ajd@linux.ibm.com
arch/powerpc/include/asm/secvar.h
arch/powerpc/kernel/secvar-sysfs.c

index bf396215903d378efb0d7a9a5891d5c00acbf144..011a53a8076c34a61139aa7b72e0b83f0e78d072 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/sysfs.h>
 
 extern const struct secvar_operations *secvar_ops;
 
@@ -19,6 +20,7 @@ struct secvar_operations {
        int (*set)(const char *key, u64 key_len, u8 *data, u64 data_size);
        ssize_t (*format)(char *buf, size_t bufsize);
        int (*max_size)(u64 *max_size);
+       const struct attribute **config_attrs;
 };
 
 #ifdef CONFIG_PPC_SECURE_BOOT
index 8f3deff9400996a30c951344851e3bc7162dbb55..7df32be86507af61a0261da0b69baa85d6f562f8 100644 (file)
@@ -144,6 +144,19 @@ static int update_kobj_size(void)
        return 0;
 }
 
+static int secvar_sysfs_config(struct kobject *kobj)
+{
+       struct attribute_group config_group = {
+               .name = "config",
+               .attrs = (struct attribute **)secvar_ops->config_attrs,
+       };
+
+       if (secvar_ops->config_attrs)
+               return sysfs_create_group(kobj, &config_group);
+
+       return 0;
+}
+
 static int secvar_sysfs_load(void)
 {
        struct kobject *kobj;
@@ -208,26 +221,36 @@ static int secvar_sysfs_init(void)
 
        rc = sysfs_create_file(secvar_kobj, &format_attr.attr);
        if (rc) {
-               kobject_put(secvar_kobj);
-               return -ENOMEM;
+               pr_err("Failed to create format object\n");
+               rc = -ENOMEM;
+               goto err;
        }
 
        secvar_kset = kset_create_and_add("vars", NULL, secvar_kobj);
        if (!secvar_kset) {
                pr_err("sysfs kobject registration failed\n");
-               kobject_put(secvar_kobj);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto err;
        }
 
        rc = update_kobj_size();
        if (rc) {
                pr_err("Cannot read the size of the attribute\n");
-               return rc;
+               goto err;
+       }
+
+       rc = secvar_sysfs_config(secvar_kobj);
+       if (rc) {
+               pr_err("Failed to create config directory\n");
+               goto err;
        }
 
        secvar_sysfs_load();
 
        return 0;
+err:
+       kobject_put(secvar_kobj);
+       return rc;
 }
 
 late_initcall(secvar_sysfs_init);