powerpc/pseries: Make caller pass buffer to plpks_read_var()
authorAndrew Donnellan <ajd@linux.ibm.com>
Fri, 10 Feb 2023 08:03:54 +0000 (19:03 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 12 Feb 2023 11:12:38 +0000 (22:12 +1100)
Currently, plpks_read_var() allocates a buffer to pass to the
H_PKS_READ_OBJECT hcall, then allocates another buffer into which the data
is copied, and returns that buffer to the caller.

This is a bit over the top - while we probably still want to allocate a
separate buffer to pass to the hypervisor in the hcall, we can let the
caller allocate the final buffer and specify the size.

Don't allocate var->data in plpks_read_var(), instead expect the caller to
allocate it. If the caller needs to discover the size, it can set
var->data to NULL and var->datalen will be populated. Update header file
to document this.

Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
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-20-ajd@linux.ibm.com
arch/powerpc/include/asm/plpks.h
arch/powerpc/platforms/pseries/plpks.c

index e7204e6..0c49969 100644 (file)
@@ -88,16 +88,28 @@ int plpks_remove_var(char *component, u8 varos,
 
 /**
  * Returns the data for the specified os variable.
+ *
+ * Caller must allocate a buffer in var->data with length in var->datalen.
+ * If no buffer is provided, var->datalen will be populated with the object's
+ * size.
  */
 int plpks_read_os_var(struct plpks_var *var);
 
 /**
  * Returns the data for the specified firmware variable.
+ *
+ * Caller must allocate a buffer in var->data with length in var->datalen.
+ * If no buffer is provided, var->datalen will be populated with the object's
+ * size.
  */
 int plpks_read_fw_var(struct plpks_var *var);
 
 /**
  * Returns the data for the specified bootloader variable.
+ *
+ * Caller must allocate a buffer in var->data with length in var->datalen.
+ * If no buffer is provided, var->datalen will be populated with the object's
+ * size.
  */
 int plpks_read_bootloader_var(struct plpks_var *var);
 
index e575544..926b6a9 100644 (file)
@@ -581,17 +581,14 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
                goto out_free_output;
        }
 
-       if (var->datalen == 0 || var->datalen > retbuf[0])
+       if (!var->data || var->datalen > retbuf[0])
                var->datalen = retbuf[0];
 
-       var->data = kzalloc(var->datalen, GFP_KERNEL);
-       if (!var->data) {
-               rc = -ENOMEM;
-               goto out_free_output;
-       }
        var->policy = retbuf[1];
 
-       memcpy(var->data, output, var->datalen);
+       if (var->data)
+               memcpy(var->data, output, var->datalen);
+
        rc = 0;
 
 out_free_output: