Re: [PATCH v4 21/24] powerpc/pseries: Pass PLPKS password on kexec
From: Russell Currey
Date: Mon Jan 30 2023 - 21:44:04 EST
On Tue, 2023-01-24 at 14:36 +1000, Nicholas Piggin wrote:
> On Fri Jan 20, 2023 at 5:43 PM AEST, Andrew Donnellan wrote:
> > From: Russell Currey <ruscur@xxxxxxxxxx>
> >
> > Before interacting with the PLPKS, we ask the hypervisor to
> > generate a
> > password for the current boot, which is then required for most
> > further
> > PLPKS operations.
> >
> > If we kexec into a new kernel, the new kernel will try and fail to
> > generate a new password, as the password has already been set.
> >
> > Pass the password through to the new kernel via the device tree, in
> > /chosen/plpks-pw. Check for the presence of this property before
> > trying
>
> In /chosen/ibm,plpks-pw
Good catch, thanks
>
> > to generate a new password - if it exists, use the existing
> > password and
> > remove it from the device tree.
> >
> > Signed-off-by: Russell Currey <ruscur@xxxxxxxxxx>
> > Signed-off-by: Andrew Donnellan <ajd@xxxxxxxxxxxxx>
> >
> > ---
> >
> > v3: New patch
> >
> > v4: Fix compile when CONFIG_PSERIES_PLPKS=n (snowpatch)
> >
> > Fix error handling on fdt_path_offset() call (ruscur)
> > ---
> > arch/powerpc/kexec/file_load_64.c | 18 ++++++++++++++++++
> > arch/powerpc/platforms/pseries/plpks.c | 18 +++++++++++++++++-
> > 2 files changed, 35 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/powerpc/kexec/file_load_64.c
> > b/arch/powerpc/kexec/file_load_64.c
> > index af8854f9eae3..0c9130af60cc 100644
> > --- a/arch/powerpc/kexec/file_load_64.c
> > +++ b/arch/powerpc/kexec/file_load_64.c
> > @@ -27,6 +27,7 @@
> > #include <asm/kexec_ranges.h>
> > #include <asm/crashdump-ppc64.h>
> > #include <asm/prom.h>
> > +#include <asm/plpks.h>
> >
> > struct umem_info {
> > u64 *buf; /* data buffer for usable-memory
> > property */
> > @@ -1156,6 +1157,9 @@ int setup_new_fdt_ppc64(const struct kimage
> > *image, void *fdt,
> > {
> > struct crash_mem *umem = NULL, *rmem = NULL;
> > int i, nr_ranges, ret;
> > +#ifdef CONFIG_PSERIES_PLPKS
> > + int chosen_offset;
> > +#endif
>
> Could put this in plpks_is_available and avoid an ifdef.
Yep, moving this out, though not into plpks_is_available().
>
> >
> > /*
> > * Restrict memory usage for kdump kernel by setting up
> > @@ -1230,6 +1234,20 @@ int setup_new_fdt_ppc64(const struct kimage
> > *image, void *fdt,
> > }
> > }
> >
> > +#ifdef CONFIG_PSERIES_PLPKS
> > + // If we have PLPKS active, we need to provide the password
> > + if (plpks_is_available()) {
> > + chosen_offset = fdt_path_offset(fdt, "/chosen");
> > + if (chosen_offset < 0) {
> > + pr_err("Can't find chosen node: %s\n",
> > + fdt_strerror(chosen_offset));
> > + goto out;
> > + }
> > + ret = fdt_setprop(fdt, chosen_offset, "ibm,plpks-
> > pw",
> > + plpks_get_password(),
> > plpks_get_passwordlen());
> > + }
> > +#endif // CONFIG_PSERIES_PLPKS
>
> I think if you define plpks_get_password and plpks_get_passwordlen as
> BUILD_BUG_ON when PLPKS is not configured and plpks_is_available as
> false, you could remove the ifdef entirely.
I'm moving this into a helper in plpks.c since now there's FDT handling
in early boot in there. We can drop plpks_get_password() entirely.
>
> > +
> > out:
> > kfree(rmem);
> > kfree(umem);
> > diff --git a/arch/powerpc/platforms/pseries/plpks.c
> > b/arch/powerpc/platforms/pseries/plpks.c
> > index b3c7410a4f13..0350f10e1755 100644
> > --- a/arch/powerpc/platforms/pseries/plpks.c
> > +++ b/arch/powerpc/platforms/pseries/plpks.c
> > @@ -16,6 +16,7 @@
> > #include <linux/slab.h>
> > #include <linux/string.h>
> > #include <linux/types.h>
> > +#include <linux/of.h>
> > #include <asm/hvcall.h>
> > #include <asm/machdep.h>
> > #include <asm/plpks.h>
> > @@ -126,7 +127,22 @@ static int plpks_gen_password(void)
> > {
> > unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
> > u8 *password, consumer = PLPKS_OS_OWNER;
> > - int rc;
> > + struct property *prop;
> > + int rc, len;
> > +
> > + // Before we generate the password, we may have been booted
> > by kexec and
> > + // provided with a previous password. Check for that
> > first.
>
> So not really generating the password then. Should it be in a
> different
> function the caller makes first?
Yes this should have been separate, and now has to be anyway since
we're retrieving the password from the FDT in early boot.
>
> > + prop = of_find_property(of_chosen, "ibm,plpks-pw", &len);
> > + if (prop) {
> > + ospasswordlength = (u16)len;
> > + ospassword = kzalloc(ospasswordlength, GFP_KERNEL);
> > + if (!ospassword) {
> > + of_remove_property(of_chosen, prop);
> > + return -ENOMEM;
> > + }
> > + memcpy(ospassword, prop->value, len);
> > + return of_remove_property(of_chosen, prop);
>
> Why do you remove the property afterward?
As Andrew mentioned, so we don't have a password lingering in the
device tree, though it's not especially useful. We're going to get it
and clear it from the FDT in early boot instead.
>
> Thanks,
> Nick