On 31.08.2026 4:47 PM, Srish Srinivasan wrote:
When a plpks variable is initialized without a policy and used to read an
object with the 'wrapping key' policy set, the hypervisor returns
H_AUTHORITY along with the object's policy. However, plpks_read_var() at
present treats this the same as any other H_AUTHORITY failure and returns
an error without propagating the policy information to the caller.

Distinguish this case from other H_AUTHORITY failures and only propagate
policy information when it is returned alongside H_AUTHORITY by the
hypervisor. Remove the explicit assignment of rc to zero in the case of
H_SUCCESS as it is redundant.

Also return -EPERM instead of -EINVAL when the 'wrapping key' policy bit is
set by the caller, better reflecting the access restriction being enforced.

Fixes: 2454a7af0f2a ("powerpc/pseries: define driver for Platform KeyStore")
Fixes: 133aa79e211d ("pseries/plpks: add HCALLs for PowerVM Key Wrapping 
Module")
Cc: [email protected]
Signed-off-by: Srish Srinivasan <[email protected]>
Tested-by: R Nageswara Sastry <[email protected]>

Tested on ppc64le PowerVM LPARs on firmware with wrap/unwrap support,
with and without Secure Boot enabled.

Verified that PKWM initialisation succeeds and the trusted key seal/unseal
round-trip works correctly. Confirmed that -EPERM is now returned (instead
of -EINVAL) when a read is attempted on an object with the wrapping key
policy bit set. The full key lifecycle (create, export, reload) passed on
all configurations.
---
  arch/powerpc/platforms/pseries/plpks.c | 13 ++++++-------
  1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 23e4e2a922fc..7bd5c149dd09 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -826,7 +826,7 @@ static int plpks_read_var(u8 consumer, struct plpks_var 
*var)
                return -EINVAL;
if (var->policy & PLPKS_WRAPPINGKEY)
-               return -EINVAL;
+               return -EPERM;
auth = construct_auth(consumer);
        if (IS_ERR(auth))
@@ -856,22 +856,21 @@ static int plpks_read_var(u8 consumer, struct plpks_var 
*var)
                                 virt_to_phys(var->name), var->namelen, 
virt_to_phys(output),
                                 maxobjsize);
-
        if (rc != H_SUCCESS) {
                rc = pseries_status_to_err(rc);
-               goto out_free_output;
+               if (rc != -EPERM || !retbuf[1])
+                       goto out_free_output;
+               goto out_copy_policy;
        }
if (!var->data || var->datalen > retbuf[0])
                var->datalen = retbuf[0];
- var->policy = retbuf[1];
-
        if (var->data)
                memcpy(var->data, output, var->datalen);
- rc = 0;
-
+out_copy_policy:
+       var->policy = retbuf[1];
  out_free_output:
        kfree(output);
  out_free_label:

--
Thanks and Regards
R.Nageswara Sastry


Reply via email to