From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [RFC 11/14] efi_loader: variable: export variables table for runtime access
Date: Wed, 18 Mar 2020 10:53:45 +0900 [thread overview]
Message-ID: <20200318015343.GS13880@linaro.org> (raw)
In-Reply-To: <ffd105a7-2510-7f20-67ee-59844f4cc39b@gmx.de>
On Tue, Mar 17, 2020 at 08:37:47AM +0100, Heinrich Schuchardt wrote:
> On 3/17/20 3:12 AM, AKASHI Takahiro wrote:
> > There are platforms on which OS's won't be able to access UEFI variables
> > at runtime (i.e. after ExitBootServices).
> > With this patch, all the UEFI variables are exported as a configuration
> > table so as to enable retrieving variables' values from the table, and
> > later modifying them via capsule-on-disk if necessary.
>
> I do not understand why we should expose our internal memory for holding
> UEFI variables to the operating system. This might end up in users
> trying to access the variables directly.
I think that you somehow misunderstand my code as it never exposes
any "internal memory," although I don't know what it exactly means in
this context.
This configuration table is nothing but a list of data that represent
all the UEFI variables in implementation-agnostic format.
> I do not understand why we should not keep the pointer in our private
> memory.
Anyway, this patch naively implements Peter's proposal while I also
submitted another patch[1] that allows HL-OS to use GetVariable
interface directly via *caching*.
Since how we should enable accessing UEFI variables at runtime is
one of key issues, I'd rather discuss in boot-arch ML as I suggested
in the cover letter.
I have already re-activated the discussion there[2].
Please make your comments there for wider audience.
[1] https://lists.denx.de/pipermail/u-boot/2019-June/371769.html
[2] https://lists.linaro.org/pipermail/boot-architecture/2020-March/001149.html
Thanks,
-Takahiro Akashi
> Best regards
>
> Heinrich
>
> >
> > The idea is based on Peter's proposal[1] in boot-arch ML.
> >
> > [1] https://lists.linaro.org/pipermail/boot-architecture/2018-October/000883.html
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> > include/efi_loader.h | 7 +++
> > lib/efi_loader/Kconfig | 10 ++++
> > lib/efi_loader/efi_boottime.c | 10 ++++
> > lib/efi_loader/efi_capsule.c | 4 ++
> > lib/efi_loader/efi_variable.c | 109 ++++++++++++++++++++++++++++++++++
> > 5 files changed, 140 insertions(+)
> >
> > diff --git a/include/efi_loader.h b/include/efi_loader.h
> > index 79bdf9586d24..93ed5502821c 100644
> > --- a/include/efi_loader.h
> > +++ b/include/efi_loader.h
> > @@ -183,6 +183,8 @@ extern const efi_guid_t efi_guid_hii_string_protocol;
> > extern const efi_guid_t efi_guid_capsule_report;
> > /* GUID of firmware management protocol */
> > extern const efi_guid_t efi_guid_firmware_management_protocol;
> > +/* GUID of runtime variable access */
> > +extern const efi_guid_t efi_guid_variable_storage;
> >
> > /* GUID of RNG protocol */
> > extern const efi_guid_t efi_guid_rng_protocol;
> > @@ -659,6 +661,10 @@ efi_status_t EFIAPI efi_query_variable_info(
> > u64 *remaining_variable_storage_size,
> > u64 *maximum_variable_size);
> >
> > +#ifdef CONFIG_EFI_VARIABLE_EXPORT
> > +efi_status_t efi_install_variables_table(void);
> > +#endif
> > +
> > /*
> > * See section 3.1.3 in the v2.7 UEFI spec for more details on
> > * the layout of EFI_LOAD_OPTION. In short it is:
> > @@ -683,6 +689,7 @@ struct efi_load_option {
> > void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
> > unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
> > efi_status_t efi_bootmgr_load(efi_handle_t *handle);
> > +efi_status_t efi_install_variables_table(void);
> >
> > /* Capsule update */
> > efi_status_t EFIAPI efi_update_capsule(
> > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
> > index 616e2acbe102..edb8d19059ea 100644
> > --- a/lib/efi_loader/Kconfig
> > +++ b/lib/efi_loader/Kconfig
> > @@ -41,6 +41,16 @@ config EFI_SET_TIME
> > Provide the SetTime() runtime service at boottime. This service
> > can be used by an EFI application to adjust the real time clock.
> >
> > +config EFI_VARIABLE_EXPORT
> > + bool "Export variables table as configuration table"
> > + depends on !EFI_VARIABLE_RUNTIME_ACCESS
> > + depends on EFI_CAPSULE_UPDATE_VARIABLE
> > + default y
> > + help
> > + Select this option if you want to export UEFI variables as
> > + configuration table so that OS can still get UEFI variable's
> > + value.
> > +
> > config EFI_DEVICE_PATH_TO_TEXT
> > bool "Device path to text protocol"
> > default y
> > diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
> > index c2a789b4f910..406644e4da67 100644
> > --- a/lib/efi_loader/efi_boottime.c
> > +++ b/lib/efi_loader/efi_boottime.c
> > @@ -2898,6 +2898,16 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
> > if (ret != EFI_SUCCESS)
> > return EFI_EXIT(EFI_INVALID_PARAMETER);
> >
> > +#ifdef CONFIG_EFI_VARIABLE_EXPORT
> > + /* Install variables database as a configuration table */
> > + ret = efi_install_variables_table();
> > + if (ret != EFI_SUCCESS)
> > + return EFI_EXIT(ret);
> > +#endif
> > + /*
> > + * TODO: remove a table after image is terminated.
> > + */
> > +
> > image_obj->exit_data_size = exit_data_size;
> > image_obj->exit_data = exit_data;
> >
> > diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
> > index 1293270aea95..6b737aec1b28 100644
> > --- a/lib/efi_loader/efi_capsule.c
> > +++ b/lib/efi_loader/efi_capsule.c
> > @@ -18,7 +18,11 @@ static const efi_guid_t efi_guid_firmware_management_capsule_id =
> > EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> > const efi_guid_t efi_guid_firmware_management_protocol =
> > EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
> > +#ifdef CONFIG_EFI_VARIABLE_EXPORT
> > +const efi_guid_t efi_guid_variable_storage = EFI_VARIABLE_STORAGE_GUID;
> > +#else
> > static const efi_guid_t efi_guid_variable_storage = EFI_VARIABLE_STORAGE_GUID;
> > +#endif
> >
> > /* for file system access */
> > static struct efi_file_handle *bootdev_root;
> > diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
> > index c316bdfec0e4..270e5211f633 100644
> > --- a/lib/efi_loader/efi_variable.c
> > +++ b/lib/efi_loader/efi_variable.c
> > @@ -641,3 +641,112 @@ efi_status_t efi_init_variables(void)
> > {
> > return EFI_SUCCESS;
> > }
> > +
> > +#ifdef CONFIG_EFI_VARIABLE_EXPORT
> > +/**
> > + * efi_install_variables_table() - install variables table
> > + *
> > + * This function adds a configuration table that contains all the cache
> > + * data of UEFI variables for runtime access.
> > + *
> > + * Return: status code
> > + */
> > +efi_status_t efi_install_variables_table(void)
> > +{
> > + u16 var_name16[64];
> > + efi_uintn_t var_name16_len;
> > + efi_guid_t guid;
> > + u32 attributes;
> > + struct efi_capsule_header capsule;
> > + u8 *data = NULL, *p;
> > + efi_uintn_t capsule_size;
> > + struct efi_ebbr_variable variable;
> > + u8 *var_buf;
> > + efi_uintn_t var_size, var_max_size;
> > + efi_status_t ret;
> > +
> > + capsule.capsule_guid = efi_guid_variable_storage;
> > + capsule.header_size = sizeof(capsule);
> > + capsule.flags = CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;
> > + capsule_size = sizeof(capsule);
> > +
> > + /* Determine size of capsule */
> > + var_name16[0] = 0;
> > + var_name16_len = 64;
> > + var_buf = NULL;
> > + var_max_size = 0;
> > + for (;;) {
> > + ret = EFI_CALL(efi_get_next_variable_name(&var_name16_len,
> > + var_name16,
> > + &guid));
> > + if (ret == EFI_NOT_FOUND)
> > + break;
> > + else if (ret != EFI_SUCCESS)
> > + goto out;
> > +
> > + var_size = 0;
> > + ret = EFI_CALL(efi_get_variable(var_name16, &guid, &attributes,
> > + &var_size, var_buf));
> > + if (ret != EFI_BUFFER_TOO_SMALL)
> > + goto out;
> > +
> > + capsule_size += sizeof(variable) + var_size;
> > + if (var_size > var_max_size)
> > + var_max_size = var_size;
> > + }
> > + capsule.capsule_image_size = capsule_size;
> > +
> > + ret = efi_allocate_pool(EFI_RUNTIME_SERVICES_DATA,
> > + capsule_size, (void **)&data);
> > + if (ret != EFI_SUCCESS)
> > + return EFI_OUT_OF_RESOURCES;
> > +
> > + var_buf = malloc(var_max_size);
> > + if (!var_buf) {
> > + ret = EFI_OUT_OF_RESOURCES;
> > + goto out;
> > + }
> > +
> > + /* Copy data */
> > + p = data;
> > + memcpy(p, &capsule, sizeof(capsule));
> > + p += sizeof(capsule);
> > +
> > + var_name16[0] = 0;
> > + for (;;) {
> > + ret = EFI_CALL(efi_get_next_variable_name(&var_name16_len,
> > + var_name16, &guid));
> > + if (ret == EFI_NOT_FOUND)
> > + break;
> > + else if (ret != EFI_SUCCESS)
> > + goto out;
> > +
> > + var_size = var_max_size;
> > + ret = EFI_CALL(efi_get_variable(var_name16, &guid, &attributes,
> > + &var_size, var_buf));
> > + if (ret != EFI_SUCCESS)
> > + /* should not happen */
> > + goto out;
> > +
> > + u16_strcpy(variable.variable_name, var_name16);
> > + variable.vendor_guid = guid;
> > + variable.attributes = attributes;
> > + variable.data_size = var_size;
> > +
> > + memcpy(p, &variable, sizeof(variable));
> > + p += sizeof(variable);
> > + memcpy(p, var_buf, var_size);
> > + p += var_size;
> > + }
> > +
> > + ret = EFI_CALL(efi_install_configuration_table(
> > + &efi_guid_variable_storage, data));
> > +
> > +out:
> > + free(var_buf);
> > + if (ret != EFI_SUCCESS && data)
> > + efi_free_pool(data);
> > +
> > + return ret;
> > +}
> > +#endif /* CONFIG_EFI_VARIABLE_EXPORT */
> >
>
next prev parent reply other threads:[~2020-03-18 1:53 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-17 2:12 [RFC 00/14] efi_loader: add capsule update support AKASHI Takahiro
2020-03-17 2:12 ` [RFC 01/14] efi_loader: define OsIndicationsSupported flags AKASHI Takahiro
2020-03-17 7:03 ` Heinrich Schuchardt
2020-03-18 1:18 ` AKASHI Takahiro
2020-03-18 18:01 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 02/14] efi_loader: define System Resource Table macros AKASHI Takahiro
2020-03-17 7:06 ` Heinrich Schuchardt
2020-03-18 18:02 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 03/14] efi_loader: export a couple of protocol related functions AKASHI Takahiro
2020-03-17 7:19 ` Heinrich Schuchardt
2020-03-18 18:03 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 04/14] efi_loader: correct a definition of struct efi_capsule_header AKASHI Takahiro
2020-03-17 7:25 ` Heinrich Schuchardt
2020-03-18 18:03 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 05/14] efi_loader: define UpdateCapsule api AKASHI Takahiro
2020-03-17 2:12 ` [RFC 06/14] efi_loader: capsule: add capsule_on_disk support AKASHI Takahiro
2020-03-18 8:55 ` Heinrich Schuchardt
2020-03-19 17:08 ` Heinrich Schuchardt
2020-03-30 7:43 ` AKASHI Takahiro
2020-03-17 2:12 ` [RFC 07/14] efi_loader: capsule: add memory range capsule definitions AKASHI Takahiro
2020-03-17 8:11 ` Heinrich Schuchardt
2020-03-18 1:22 ` AKASHI Takahiro
2020-03-18 7:35 ` Heinrich Schuchardt
2020-03-18 7:57 ` AKASHI Takahiro
2020-04-06 7:48 ` AKASHI Takahiro
2020-03-17 2:12 ` [RFC 08/14] efi_loader: capsule: support firmware update AKASHI Takahiro
2020-03-18 14:09 ` Sughosh Ganu
2020-03-17 2:12 ` [RFC 09/14] efi_loader: add simple firmware management protocol for FIT image AKASHI Takahiro
2020-03-18 8:04 ` Heinrich Schuchardt
2020-03-18 8:17 ` AKASHI Takahiro
2020-03-18 9:06 ` Heinrich Schuchardt
2020-04-06 7:59 ` AKASHI Takahiro
2020-03-17 2:12 ` [RFC 10/14] efi_loader: capsule: support variable update AKASHI Takahiro
2020-03-17 2:12 ` [RFC 11/14] efi_loader: variable: export variables table for runtime access AKASHI Takahiro
2020-03-17 7:37 ` Heinrich Schuchardt
2020-03-18 1:53 ` AKASHI Takahiro [this message]
2020-03-19 9:30 ` Ilias Apalodimas
2020-03-18 13:54 ` Sughosh Ganu
2020-03-17 2:12 ` [RFC 12/14] cmd: add "efidebug capsule" command AKASHI Takahiro
2020-03-17 2:12 ` [RFC 13/14] tools: add mkeficapsule command for UEFI capsule update test AKASHI Takahiro
2020-03-17 7:58 ` Heinrich Schuchardt
2020-03-18 1:32 ` AKASHI Takahiro
2020-03-19 8:55 ` Ilias Apalodimas
2020-03-17 2:12 ` [RFC 14/14] test/py: add efi capsule test AKASHI Takahiro
2020-03-17 7:49 ` [RFC 00/14] efi_loader: add capsule update support Heinrich Schuchardt
2020-03-18 2:04 ` AKASHI Takahiro
2020-03-31 4:36 ` AKASHI Takahiro
2020-04-14 4:38 ` AKASHI Takahiro
2020-03-18 18:16 ` Sughosh Ganu
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=20200318015343.GS13880@linaro.org \
--to=takahiro.akashi@linaro.org \
--cc=u-boot@lists.denx.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox