Add last attempt status tracking to RAW capsule updates to enable
proper ESRT reporting. This allows the OS to query firmware update
history and determine the outcome of previous update attempts.

Track last attempt information at all failure points in the update
flows. Update the FMP state variable with both success
and failure status to maintain accurate firmware state information.

Signed-off-by: Balaji Selvanathan <[email protected]>
---
 lib/efi_loader/efi_firmware.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index dff8de8cf8f..c30283cc9e4 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -869,8 +869,17 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
 
        status = efi_firmware_verify_image(&image, &image_size, image_index,
                                           &state);
-       if (status != EFI_SUCCESS)
+       if (status != EFI_SUCCESS) {
+               /* Set last attempt information for failed verification */
+               efi_firmware_set_last_attempt(&state, state.fw_version,
+                                             
efi_firmware_map_error_to_status(status));
+               efi_firmware_set_fmp_state_var(&state, image_index);
                return EFI_EXIT(status);
+       }
+
+       /* Set last attempt version before starting the update */
+       efi_firmware_set_last_attempt(&state, state.fw_version,
+                                     LAST_ATTEMPT_STATUS_SUCCESS);
 
        /*
         * dfu_alt_num is assigned from 0 while image_index starts from 1.
@@ -895,13 +904,21 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
                orig_dfu_env = strdup(orig_dfu_env);
                if (!orig_dfu_env) {
                        log_err("strdup() failed!\n");
-                       return EFI_EXIT(EFI_OUT_OF_RESOURCES);
+                       status = EFI_OUT_OF_RESOURCES;
+                       efi_firmware_set_last_attempt(&state, state.fw_version,
+                                                     
efi_firmware_map_error_to_status(status));
+                       efi_firmware_set_fmp_state_var(&state, image_index);
+                       return EFI_EXIT(status);
                }
        }
        if (env_set("dfu_alt_info", update_info.dfu_string)) {
                log_err("Unable to set env variable \"dfu_alt_info\"!\n");
                free(orig_dfu_env);
-               return EFI_EXIT(EFI_DEVICE_ERROR);
+               status = EFI_DEVICE_ERROR;
+               efi_firmware_set_last_attempt(&state, state.fw_version,
+                                             
efi_firmware_map_error_to_status(status));
+               efi_firmware_set_fmp_state_var(&state, image_index);
+               return EFI_EXIT(status);
        }
 
        ret = dfu_write_by_alt(dfu_alt_num, (void *)image, image_size,
@@ -912,9 +929,17 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
 
        free(orig_dfu_env);
 
-       if (ret)
-               return EFI_EXIT(EFI_DEVICE_ERROR);
+       if (ret) {
+               status = EFI_DEVICE_ERROR;
+               efi_firmware_set_last_attempt(&state, state.fw_version,
+                                             
efi_firmware_map_error_to_status(status));
+               efi_firmware_set_fmp_state_var(&state, image_index);
+               return EFI_EXIT(status);
+       }
 
+       /* Update successful - set success status */
+       efi_firmware_set_last_attempt(&state, state.fw_version,
+                                     LAST_ATTEMPT_STATUS_SUCCESS);
        efi_firmware_set_fmp_state_var(&state, image_index);
 
        return EFI_EXIT(EFI_SUCCESS);

-- 
2.34.1

Reply via email to