[PATCH 1/3 v3] efi: Fix to use null handle to create new handle for efi_fmp_raw

From: Masami Hiramatsu masami.hiramatsu@linaro.org
When running the efidebug capsule disk-update command, the efi_fmp_raw protocol installation fails with 2 (EFI_INVALID_PARAMETER) as below. This is because the code passes efi_root instead of the handle local var.
=> efidebug capsule disk-update EFI: Call: efi_install_multiple_protocol_interfaces( &handle, &efi_guid_firmware_management_protocol, &efi_fmp_fit, NULL) EFI: Entry efi_install_multiple_protocol_interfaces(00000000fbaf5988) EFI: Call: efi_install_protocol_interface( handle, protocol, EFI_NATIVE_INTERFACE, protocol_interface) EFI: Entry efi_install_protocol_interface(00000000fbaf5988, 86c77a67-0b97-4633-a187-49104d0685c7, 0, 00000000fbfa6ee8) EFI: new handle 00000000fbb37520 EFI: Exit: efi_install_protocol_interface: 0 EFI: 0 returned by efi_install_protocol_interface( handle, protocol, EFI_NATIVE_INTERFACE, protocol_interface) EFI: Exit: efi_install_multiple_protocol_interfaces: 0 EFI: 0 returned by efi_install_multiple_protocol_interfaces( &handle, &efi_guid_firmware_management_protocol, &efi_fmp_fit, NULL) EFI: Call: efi_install_multiple_protocol_interfaces( &efi_root, &efi_guid_firmware_management_protocol, &efi_fmp_raw, NULL) EFI: Entry efi_install_multiple_protocol_interfaces(00000000fbfec648) EFI: Call: efi_install_protocol_interface( handle, protocol, EFI_NATIVE_INTERFACE, protocol_interface) EFI: Entry efi_install_protocol_interface(00000000fbfec648, 86c77a67-0b97-4633-a187-49104d0685c7, 0, 00000000fbfa6f18) EFI: handle 00000000fbaf8520 EFI: Exit: efi_install_protocol_interface: 2 EFI: 2 returned by efi_install_protocol_interface( handle, protocol, EFI_NATIVE_INTERFACE, protocol_interface) EFI: Exit: efi_install_multiple_protocol_interfaces: 2 EFI: 2 returned by efi_install_multiple_protocol_interfaces( &efi_root, &efi_guid_firmware_management_protocol, &efi_fmp_raw, NULL) Command failed, result=1
To fix this issue, pass the handle local var which is set NULL right before installing efi_fmp_raw as same as the installing efi_fmp_fit. (In both cases, the local reference to the handle will be just discarded)
Signed-off-by: Masami Hiramatsu masami.hiramatsu@linaro.org Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- Changes since v2: - Updated commit description Changes since v1: - lib/efi_loader/efi_capsule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 60309d4a07d0..cc6ed453ed21 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -940,7 +940,7 @@ efi_status_t __weak arch_efi_load_capsule_drivers(void) if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) { handle = NULL; ret = EFI_CALL(efi_install_multiple_protocol_interfaces( - &efi_root, + &handle, &efi_guid_firmware_management_protocol, &efi_fmp_raw, NULL)); }

Chapter 23 of the EFI spec (rev 2.9) says: "A specific updatable hardware firmware store must be represented by exactly one FMP instance". This is not the case for us, since both of our FMP protocols can be installed at the same time because they are controlled by a single 'dfu_alt_info' env variable. So make the config options depend on each other and allow the user to install one of them at any given time. If we fix the meta-data provided by the 'dfu_alt_info' in the future, to hint about the capsule type (fit or raw) we can revise this and enable both FMPs to be installed, as long as they target different firmware hardware stores
Note that we are not using a Kconfig 'choice' on purpose, since we want to allow both of those to be installed and tested in sandbox
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- Changes since v2: - Changes since v1: - Don't use 'choice' on Kconfig sicne we need both of the FMPs installed for sandbox testing instead just make them mutually exclusive with 'depends on'
configs/xilinx_zynqmp_virt_defconfig | 1 - lib/efi_loader/Kconfig | 45 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 6adbe987cb7f..4d34e6c4cba5 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -187,5 +187,4 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_EFI_SET_TIME=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6242caceb7f9..684adfb62379 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -161,6 +161,28 @@ config EFI_CAPSULE_FIRMWARE_MANAGEMENT Select this option if you want to enable capsule-based firmware update using Firmware Management Protocol.
+config EFI_CAPSULE_FIRMWARE_FIT + bool "FMP driver for FIT images" + depends on FIT + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + select UPDATE_FIT + select DFU + select EFI_CAPSULE_FIRMWARE + help + Select this option if you want to enable firmware management protocol + driver for FIT image + +config EFI_CAPSULE_FIRMWARE_RAW + bool "FMP driver for raw images" + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT) + select DFU_WRITE_ALT + select DFU + select EFI_CAPSULE_FIRMWARE + help + Select this option if you want to enable firmware management protocol + driver for raw image + config EFI_CAPSULE_AUTHENTICATE bool "Update Capsule authentication" depends on EFI_CAPSULE_FIRMWARE @@ -181,29 +203,6 @@ config EFI_CAPSULE_AUTHENTICATE Select this option if you want to enable capsule authentication
-config EFI_CAPSULE_FIRMWARE_FIT - bool "FMP driver for FIT image" - depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT - depends on FIT - select UPDATE_FIT - select DFU - select EFI_CAPSULE_FIRMWARE - default n - help - Select this option if you want to enable firmware management protocol - driver for FIT image - -config EFI_CAPSULE_FIRMWARE_RAW - bool "FMP driver for raw image" - depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT - select DFU - select DFU_WRITE_ALT - select EFI_CAPSULE_FIRMWARE - default n - help - Select this option if you want to enable firmware management protocol - driver for raw image - config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y

Hi,
2021年6月22日(火) 23:39 Ilias Apalodimas ilias.apalodimas@linaro.org:
Chapter 23 of the EFI spec (rev 2.9) says: "A specific updatable hardware firmware store must be represented by exactly one FMP instance". This is not the case for us, since both of our FMP protocols can be installed at the same time because they are controlled by a single 'dfu_alt_info' env variable. So make the config options depend on each other and allow the user to install one of them at any given time. If we fix the meta-data provided by the 'dfu_alt_info' in the future, to hint about the capsule type (fit or raw) we can revise this and enable both FMPs to be installed, as long as they target different firmware hardware stores
Note that we are not using a Kconfig 'choice' on purpose, since we want to allow both of those to be installed and tested in sandbox
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org
This looks good to me.
Reviewed-by: Masami Hiramatsu masami.hiramatsu@linaro.org
Changes since v2:
BTW, you might need to describe the change (fix to move the FMP installation part to the next patch, etc.). But I think this is a minor issue.
Thank you,
Changes since v1:
- Don't use 'choice' on Kconfig sicne we need both of the FMPs installed for sandbox testing instead just make them mutually exclusive with 'depends on'
configs/xilinx_zynqmp_virt_defconfig | 1 - lib/efi_loader/Kconfig | 45 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 6adbe987cb7f..4d34e6c4cba5 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -187,5 +187,4 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_EFI_SET_TIME=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6242caceb7f9..684adfb62379 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -161,6 +161,28 @@ config EFI_CAPSULE_FIRMWARE_MANAGEMENT Select this option if you want to enable capsule-based firmware update using Firmware Management Protocol.
+config EFI_CAPSULE_FIRMWARE_FIT
bool "FMP driver for FIT images"
depends on FIT
depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
select UPDATE_FIT
select DFU
select EFI_CAPSULE_FIRMWARE
help
Select this option if you want to enable firmware management protocol
driver for FIT image
+config EFI_CAPSULE_FIRMWARE_RAW
bool "FMP driver for raw images"
depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT)
select DFU_WRITE_ALT
select DFU
select EFI_CAPSULE_FIRMWARE
help
Select this option if you want to enable firmware management protocol
driver for raw image
config EFI_CAPSULE_AUTHENTICATE bool "Update Capsule authentication" depends on EFI_CAPSULE_FIRMWARE @@ -181,29 +203,6 @@ config EFI_CAPSULE_AUTHENTICATE Select this option if you want to enable capsule authentication
-config EFI_CAPSULE_FIRMWARE_FIT
bool "FMP driver for FIT image"
depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
depends on FIT
select UPDATE_FIT
select DFU
select EFI_CAPSULE_FIRMWARE
default n
help
Select this option if you want to enable firmware management protocol
driver for FIT image
-config EFI_CAPSULE_FIRMWARE_RAW
bool "FMP driver for raw image"
depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
select DFU
select DFU_WRITE_ALT
select EFI_CAPSULE_FIRMWARE
default n
help
Select this option if you want to enable firmware management protocol
driver for raw image
config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y -- 2.32.0.rc0
-- Masami Hiramatsu

On 6/22/21 4:38 PM, Ilias Apalodimas wrote:
Chapter 23 of the EFI spec (rev 2.9) says: "A specific updatable hardware firmware store must be represented by exactly one FMP instance". This is not the case for us, since both of our FMP protocols can be installed at the same time because they are controlled by a single 'dfu_alt_info' env variable. So make the config options depend on each other and allow the user to install one of them at any given time. If we fix the meta-data provided by the 'dfu_alt_info' in the future, to hint about the capsule type (fit or raw) we can revise this and enable both FMPs to be installed, as long as they target different firmware hardware stores
Note that we are not using a Kconfig 'choice' on purpose, since we want to allow both of those to be installed and tested in sandbox
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org
Changes since v2:
Changes since v1:
Don't use 'choice' on Kconfig sicne we need both of the FMPs installed for sandbox testing instead just make them mutually exclusive with 'depends on'
configs/xilinx_zynqmp_virt_defconfig | 1 - lib/efi_loader/Kconfig | 45 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 6adbe987cb7f..4d34e6c4cba5 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -187,5 +187,4 @@ CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_EFI_SET_TIME=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6242caceb7f9..684adfb62379 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -161,6 +161,28 @@ config EFI_CAPSULE_FIRMWARE_MANAGEMENT Select this option if you want to enable capsule-based firmware update using Firmware Management Protocol.
+config EFI_CAPSULE_FIRMWARE_FIT
- bool "FMP driver for FIT images"
- depends on FIT
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
Should here be:
depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_RAW)
Best regards
Heinrich
- select UPDATE_FIT
- select DFU
- select EFI_CAPSULE_FIRMWARE
- help
Select this option if you want to enable firmware management protocol
driver for FIT image
+config EFI_CAPSULE_FIRMWARE_RAW
- bool "FMP driver for raw images"
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
- depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT)
- select DFU_WRITE_ALT
- select DFU
- select EFI_CAPSULE_FIRMWARE
- help
Select this option if you want to enable firmware management protocol
driver for raw image
- config EFI_CAPSULE_AUTHENTICATE bool "Update Capsule authentication" depends on EFI_CAPSULE_FIRMWARE
@@ -181,29 +203,6 @@ config EFI_CAPSULE_AUTHENTICATE Select this option if you want to enable capsule authentication
-config EFI_CAPSULE_FIRMWARE_FIT
- bool "FMP driver for FIT image"
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
- depends on FIT
- select UPDATE_FIT
- select DFU
- select EFI_CAPSULE_FIRMWARE
- default n
- help
Select this option if you want to enable firmware management protocol
driver for FIT image
-config EFI_CAPSULE_FIRMWARE_RAW
- bool "FMP driver for raw image"
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
- select DFU
- select DFU_WRITE_ALT
- select EFI_CAPSULE_FIRMWARE
- default n
- help
Select this option if you want to enable firmware management protocol
driver for raw image
- config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y

- bool "FMP driver for FIT images"
[...]
- depends on FIT
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
Should here be:
depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_RAW)
Well on of them is enough and makes them mutually exclusive. If you choose EFI_CAPSULE_FIRMWARE_RAW in this specific case the FIT variant will dissapear.
I dont mind adding it for completeness, up to you
Cheers /Ilias
Best regards
Heinrich
- select UPDATE_FIT
- select DFU
- select EFI_CAPSULE_FIRMWARE
- help
Select this option if you want to enable firmware management protocol
driver for FIT image
+config EFI_CAPSULE_FIRMWARE_RAW
- bool "FMP driver for raw images"
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
- depends on SANDBOX || (!SANDBOX && !EFI_CAPSULE_FIRMWARE_FIT)
- select DFU_WRITE_ALT
- select DFU
- select EFI_CAPSULE_FIRMWARE
- help
Select this option if you want to enable firmware management protocol
driver for raw image
- config EFI_CAPSULE_AUTHENTICATE bool "Update Capsule authentication" depends on EFI_CAPSULE_FIRMWARE
@@ -181,29 +203,6 @@ config EFI_CAPSULE_AUTHENTICATE Select this option if you want to enable capsule authentication
-config EFI_CAPSULE_FIRMWARE_FIT
- bool "FMP driver for FIT image"
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
- depends on FIT
- select UPDATE_FIT
- select DFU
- select EFI_CAPSULE_FIRMWARE
- default n
- help
Select this option if you want to enable firmware management protocol
driver for FIT image
-config EFI_CAPSULE_FIRMWARE_RAW
- bool "FMP driver for raw image"
- depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT
- select DFU
- select DFU_WRITE_ALT
- select EFI_CAPSULE_FIRMWARE
- default n
- help
Select this option if you want to enable firmware management protocol
driver for raw image
- config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y

We only install FMPs if a CapsuleUpdate is requested. Since we now have an ESRT table which relies on FMPs to build the required information, it makes more sense to unconditionally install them. This will allow userspace applications (e.g fwupd) to make use of the ERST and provide us with files we can use to run CapsuleUpdate on-disk
Signed-off-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- Changes since v2: - Changes since v1: - Only install the FMPs if CONFIG_EFI_HAVE_CAPSULE_SUPPORT is selected include/efi_loader.h | 1 + lib/efi_loader/efi_capsule.c | 11 +++-------- lib/efi_loader/efi_setup.c | 6 ++++++ 3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/include/efi_loader.h b/include/efi_loader.h index 0a9c82a257e1..b81180cfda8b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -972,4 +972,5 @@ efi_status_t efi_esrt_register(void); * - error code otherwise. */ efi_status_t efi_esrt_populate(void); +efi_status_t efi_load_capsule_drivers(void); #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index cc6ed453ed21..d7136035d8f9 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -919,13 +919,13 @@ static void efi_capsule_scan_done(void) }
/** - * arch_efi_load_capsule_drivers - initialize capsule drivers + * efi_load_capsule_drivers - initialize capsule drivers * - * Architecture or board specific initialization routine + * Generic FMP drivers backed by DFU * * Return: status code */ -efi_status_t __weak arch_efi_load_capsule_drivers(void) +efi_status_t __weak efi_load_capsule_drivers(void) { __maybe_unused efi_handle_t handle; efi_status_t ret = EFI_SUCCESS; @@ -976,11 +976,6 @@ efi_status_t efi_launch_capsules(void)
index = get_last_capsule();
- /* Load capsule drivers */ - ret = arch_efi_load_capsule_drivers(); - if (ret != EFI_SUCCESS) - return ret; - /* * Find capsules on disk. * All the capsules are collected at the beginning because diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 3c5cf9a4357e..2dc6ba8337a7 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -254,6 +254,12 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out;
+ if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) { + ret = efi_load_capsule_drivers(); + if (ret != EFI_SUCCESS) + goto out; + } + #if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO) ret = efi_gop_register(); if (ret != EFI_SUCCESS)
participants (3)
-
Heinrich Schuchardt
-
Ilias Apalodimas
-
Masami Hiramatsu