powerpc/secvar: Allow backend to populate static list of variable names
authorAndrew Donnellan <ajd@linux.ibm.com>
Fri, 10 Feb 2023 08:03:46 +0000 (19:03 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 12 Feb 2023 11:12:37 +0000 (22:12 +1100)
Currently, the list of variables is populated by calling
secvar_ops->get_next() repeatedly, which is explicitly modelled on the
OPAL API (including the keylen parameter).

For the upcoming PLPKS backend, we have a static list of variable names.
It is messy to fit that into get_next(), so instead, let the backend put
a NULL-terminated array of variable names into secvar_ops->var_names,
which will be used if get_next() is undefined.

Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com>
Signed-off-by: Russell Currey <ruscur@russell.cc>
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-12-ajd@linux.ibm.com
arch/powerpc/include/asm/secvar.h
arch/powerpc/kernel/secvar-sysfs.c

index 011a53a..4828e0a 100644 (file)
@@ -21,6 +21,10 @@ struct secvar_operations {
        ssize_t (*format)(char *buf, size_t bufsize);
        int (*max_size)(u64 *max_size);
        const struct attribute **config_attrs;
+
+       // NULL-terminated array of fixed variable names
+       // Only used if get_next() isn't provided
+       const char * const *var_names;
 };
 
 #ifdef CONFIG_PPC_SECURE_BOOT
index 7df32be..bfb19f2 100644 (file)
@@ -157,9 +157,31 @@ static int secvar_sysfs_config(struct kobject *kobj)
        return 0;
 }
 
-static int secvar_sysfs_load(void)
+static int add_var(const char *name)
 {
        struct kobject *kobj;
+       int rc;
+
+       kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
+       if (!kobj)
+               return -ENOMEM;
+
+       kobject_init(kobj, &secvar_ktype);
+
+       rc = kobject_add(kobj, &secvar_kset->kobj, "%s", name);
+       if (rc) {
+               pr_warn("kobject_add error %d for attribute: %s\n", rc,
+                       name);
+               kobject_put(kobj);
+               return rc;
+       }
+
+       kobject_uevent(kobj, KOBJ_ADD);
+       return 0;
+}
+
+static int secvar_sysfs_load(void)
+{
        u64 namesize = 0;
        char *name;
        int rc;
@@ -179,31 +201,28 @@ static int secvar_sysfs_load(void)
                        break;
                }
 
-               kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
-               if (!kobj) {
-                       rc = -ENOMEM;
-                       break;
-               }
-
-               kobject_init(kobj, &secvar_ktype);
-
-               rc = kobject_add(kobj, &secvar_kset->kobj, "%s", name);
-               if (rc) {
-                       pr_warn("kobject_add error %d for attribute: %s\n", rc,
-                               name);
-                       kobject_put(kobj);
-                       kobj = NULL;
-               }
-
-               if (kobj)
-                       kobject_uevent(kobj, KOBJ_ADD);
-
+               rc = add_var(name);
        } while (!rc);
 
        kfree(name);
        return rc;
 }
 
+static int secvar_sysfs_load_static(void)
+{
+       const char * const *name_ptr = secvar_ops->var_names;
+       int rc;
+
+       while (*name_ptr) {
+               rc = add_var(*name_ptr);
+               if (rc)
+                       return rc;
+               name_ptr++;
+       }
+
+       return 0;
+}
+
 static int secvar_sysfs_init(void)
 {
        int rc;
@@ -245,7 +264,15 @@ static int secvar_sysfs_init(void)
                goto err;
        }
 
-       secvar_sysfs_load();
+       if (secvar_ops->get_next)
+               rc = secvar_sysfs_load();
+       else
+               rc = secvar_sysfs_load_static();
+
+       if (rc) {
+               pr_err("Failed to create variable attributes\n");
+               goto err;
+       }
 
        return 0;
 err: