From: Chen Yu <yu.c.chen@intel.com>
To: Mike Rapoport <rppt@kernel.org>
Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
Len Brown <len.brown@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Andy Shevchenko <andriy.shevchenko@intel.com>,
Aubrey Li <aubrey.li@intel.com>, Ashok Raj <ashok.raj@intel.com>,
Jonathan Corbet <corbet@lwn.net>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Hans de Goede <hdegoede@redhat.com>,
Maximilian Luz <luzmaximilian@gmail.com>,
Alexander Graf <graf@amazon.com>,
Jarkko Sakkinen <jarkko@kernel.org>,
Shuo Liu <shuo.a.liu@intel.com>, Hannes Reinecke <hare@suse.de>,
Ioana Ciornei <ioana.ciornei@nxp.com>,
Jiri Slaby <jirislaby@kernel.org>,
Andra Paraschiv <andraprs@amazon.com>,
Randy Dunlap <rdunlap@infradead.org>,
Ben Widawsky <ben.widawsky@intel.com>,
linux-doc@vger.kernel.org
Subject: Re: [PATCH 3/5][RFC] drivers/acpi: Introduce Platform Firmware Runtime Update device driver
Date: Tue, 14 Sep 2021 13:54:47 +0800 [thread overview]
Message-ID: <20210914055447.GA78108@chenyu-desktop> (raw)
In-Reply-To: <YTh8mPOVv8T1Yhgy@kernel.org>
Thank you very much and sorry for late response, Mike,
On Wed, Sep 08, 2021 at 12:04:24PM +0300, Mike Rapoport wrote:
> Hi,
>
> On Tue, Sep 07, 2021 at 11:27:42PM +0800, Chen Yu wrote:
> > Introduce the pfru_update driver which can be used for Platform Firmware
> > Runtime code injection and driver update. The user is expected to provide
> > the update firmware in the form of capsule file, and pass it to the driver
> > via ioctl. Then the driver would hand this capsule file to the Platform
> > Firmware Runtime Update via the ACPI device _DSM method. At last the low
> > level Management Mode would do the firmware update.
> >
> > Signed-off-by: Chen Yu <yu.c.chen@intel.com>
> > ---
> > .../userspace-api/ioctl/ioctl-number.rst | 1 +
> > drivers/acpi/Kconfig | 1 +
> > drivers/acpi/Makefile | 1 +
> > drivers/acpi/pfru/Kconfig | 15 +
> > drivers/acpi/pfru/Makefile | 2 +
> > drivers/acpi/pfru/pfru_update.c | 544 ++++++++++++++++++
> > include/uapi/linux/pfru.h | 106 ++++
> > 7 files changed, 670 insertions(+)
[cut]
> > +struct pfru_device {
> > + guid_t uuid;
> > + int rev_id;
> > + struct device *dev;
> > +};
> > +
> > +static struct pfru_device pfru_dev;
>
> Please don't presume a single instance and update the driver to work with
> allocated pfru_device objects.
>
Okay, this global variable has been switched to a dynamic allocated pointer.
Since there would be only one instance of this ACPI device, more than one
instance would indicate a bogus BIOS. The duplication check logic was added
during driver initialization that, if more than than one instance was detected,
only the first instance would take effect.
> > +static struct pfru_device *get_pfru_dev(void)
> > +{
> > + return &pfru_dev;
> > +}
> > +
[cut]
> > + for (i = 0; i < out_obj->package.count; i++) {
> > + union acpi_object *obj = &out_obj->package.elements[i];
> > +
> > + switch (i) {
> > + case 0:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + cap->status = obj->integer.value;
> > + break;
> > + case 1:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + cap->update_cap = obj->integer.value;
> > + break;
> > + case 2:
> > + if (obj->type != ACPI_TYPE_BUFFER)
> > + goto free_acpi_buffer;
> > + memcpy(&cap->code_type, obj->buffer.pointer,
> > + obj->buffer.length);
> > + break;
> > + case 3:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + cap->fw_version = obj->integer.value;
> > + break;
> > + case 4:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + cap->code_rt_version = obj->integer.value;
> > + break;
> > + case 5:
> > + if (obj->type != ACPI_TYPE_BUFFER)
> > + goto free_acpi_buffer;
> > + memcpy(&cap->drv_type, obj->buffer.pointer,
> > + obj->buffer.length);
> > + break;
> > + case 6:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + cap->drv_rt_version = obj->integer.value;
> > + break;
> > + case 7:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + cap->drv_svn = obj->integer.value;
> > + break;
> > + case 8:
> > + if (obj->type != ACPI_TYPE_BUFFER)
> > + goto free_acpi_buffer;
> > + memcpy(&cap->platform_id, obj->buffer.pointer,
> > + obj->buffer.length);
> > + break;
> > + case 9:
> > + if (obj->type != ACPI_TYPE_BUFFER)
> > + goto free_acpi_buffer;
> > + memcpy(&cap->oem_id, obj->buffer.pointer,
> > + obj->buffer.length);
> > + break;
>
> Please get rid of the magic numbers and add a default clause with the error
> handling. Nothing guaranties that there will be exactly 10 fields in the
> out_obj.
>
Okay, got it, changed in next version.
> Also, the obj->type checks could move outside the switch, with an if or a
> static mapping between the field number and the desired type.
>
>
Okay, changed in next version.
> > + }
> > + }
[cut]
> > + case 4:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + info->buf_size = obj->integer.value;
> > + break;
>
> The same comments as for query_capability() functions apply here as well.
>
Okay.
> > + }
> > + }
> > + ret = 0;
> > +
> > +free_acpi_buffer:
> > + ACPI_FREE(out_obj);
> > +
> > + return ret;
> > +}
> > +
> > +static int get_image_type(efi_manage_capsule_image_header_t *img_hdr,
> > + int *type)
> > +{
> > + int ret;
> > + guid_t code_inj_id, drv_update_id, *image_type_id;
> > +
> > + ret = guid_parse(PFRU_CODE_INJ_UUID, &code_inj_id);
> > + if (ret)
> > + return ret;
> > + ret = guid_parse(PFRU_DRV_UPDATE_UUID, &drv_update_id);
> > + if (ret)
> > + return ret;
>
> The code_inj_id and drv_update_id are "constant", they can be parsed once
> at driver initialization time.
>
Okay, changed in next version.
> > + /* check whether this is a code injection or driver update */
> > + image_type_id = &img_hdr->image_type_id;
> > + if (guid_equal(image_type_id, &code_inj_id))
> > + *type = CODE_INJECT_TYPE;
> > + else if (guid_equal(image_type_id, &drv_update_id))
> > + *type = DRIVER_UPDATE_TYPE;
> > + else
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * The (u64 hw_ins) was introduced in UEFI spec version 2,
> > + * and (u64 capsule_support) was introduced in version 3.
> > + * The size needs to be adjusted accordingly.
>
> The comment here does not really explain how exactly the size needs to be
> adjusted.
>
The comment has been refined in next version.
> > +
[cut]
> > +static void parse_update_result(struct updated_result *result)
>
> I think dump_update_result() would be more appropriate.
>
Okay, changed accordingly.
> > +{
> > + pr_debug("Update result:\n");
> > + pr_debug("Status:%d\n", result->status);
> > + pr_debug("Extended Status:%d\n", result->ext_status);
> > + pr_debug("Authentication Time Low:%ld\n", result->low_auth_time);
> > + pr_debug("Authentication Time High:%ld\n", result->high_auth_time);
> > + pr_debug("Execution Time Low:%ld\n", result->low_exec_time);
> > + pr_debug("Execution Time High:%ld\n", result->high_exec_time);
> > +}
> > +
> > + case 5:
> > + if (obj->type != ACPI_TYPE_INTEGER)
> > + goto free_acpi_buffer;
> > + update_result.high_exec_time = obj->integer.value;
> > + break;
> > + }
>
> The same comments as for query_capability() functions apply here as well.
>
Okay, changed in next version.
> > + }
> > + parse_update_result(&update_result);
> > + ret = 0;
> > +
> > +free_acpi_buffer:
> > + ACPI_FREE(out_obj);
> > +
> > + return ret;
> > +}
> > +
[cut]
> > + case PFRU_IOC_STAGE_ACTIVATE:
> > + ret = start_acpi_update(START_STAGE_ACTIVATE);
> > + if (ret)
> > + return ret;
>
> These
> if (ret)
> return ret;
>
> seem redundant here.
>
I see. Changed accordingly.
> > + break;
> > + default:
> > + ret = -ENOIOCTLCMD;
> > + break;
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +
[cut]
> > +struct com_buf_info {
> > + enum dsm_status status;
> > + enum dsm_status ext_status;
> > + unsigned long addr_lo;
> > + unsigned long addr_hi;
> > + int buf_size;
> > +};
> > +
> > +struct capsulate_buf_info {
> > + unsigned long src;
> > + int size;
> > +};
> > +
> > +struct updated_result {
> > + enum dsm_status status;
> > + enum dsm_status ext_status;
> > + unsigned long low_auth_time;
> > + unsigned long high_auth_time;
> > + unsigned long low_exec_time;
> > + unsigned long high_exec_time;
> > +};
>
> Are all these types need to be visible to userspace?
> If not, please move the driver internal types to pfru_update.c.
>
The struct capsulate_buf_info is only usable in kernel space, so it
is moved into pfru_update.c in next version. While the other structures
are required by the userspace for customization.
thanks,
Chenyu
next prev parent reply other threads:[~2021-09-14 5:49 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-07 15:08 [PATCH 0/5][RFC] Introduce Platform Firmware Runtime Update and Telemetry drivers Chen Yu
2021-09-07 15:15 ` [PATCH 1/5][RFC] Documentation: Introduce Platform Firmware Runtime Update documentation Chen Yu
2021-09-07 15:23 ` Jonathan Corbet
2021-09-07 15:48 ` Chen Yu
2021-09-07 15:17 ` [PATCH 2/5][RFC] efi: Introduce EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER and corresponding structures Chen Yu
2021-09-07 16:06 ` Ard Biesheuvel
2021-09-07 23:56 ` Chen Yu
2021-09-07 15:27 ` [PATCH 3/5][RFC] drivers/acpi: Introduce Platform Firmware Runtime Update device driver Chen Yu
2021-09-08 9:04 ` Mike Rapoport
2021-09-14 5:54 ` Chen Yu [this message]
2021-09-07 15:39 ` [PATCH 4/5][RFC] drivers/acpi: Introduce Platform Firmware Runtime Update Telemetry Chen Yu
2021-09-07 15:40 ` [PATCH 5/5][RFC] selftests/pfru: add test for Platform Firmware Runtime Update and Telemetry Chen Yu
2021-09-07 21:28 ` Shuah Khan
2021-09-14 6:46 ` Chen Yu
2021-09-08 9:08 ` Mike Rapoport
2021-09-14 7:08 ` Chen Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210914055447.GA78108@chenyu-desktop \
--to=yu.c.chen@intel.com \
--cc=andraprs@amazon.com \
--cc=andriy.shevchenko@intel.com \
--cc=ashok.raj@intel.com \
--cc=aubrey.li@intel.com \
--cc=ben.widawsky@intel.com \
--cc=corbet@lwn.net \
--cc=dan.j.williams@intel.com \
--cc=graf@amazon.com \
--cc=gregkh@linuxfoundation.org \
--cc=hare@suse.de \
--cc=hdegoede@redhat.com \
--cc=ioana.ciornei@nxp.com \
--cc=jarkko@kernel.org \
--cc=jirislaby@kernel.org \
--cc=len.brown@intel.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luzmaximilian@gmail.com \
--cc=rdunlap@infradead.org \
--cc=rjw@rjwysocki.net \
--cc=rppt@kernel.org \
--cc=shuo.a.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.