From: Ji Luo Date: Wed, 21 Oct 2020 02:11:51 +0000 (+0800) Subject: MA-18087-1 Enhance virtual A/B slot check X-Git-Tag: rel_imx_5.10.35_2.0.0-somdevices.0~73^2~35 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=582ffab8332b1270a3eba7faf9a1091b32b4cad3;p=u-boot.git MA-18087-1 Enhance virtual A/B slot check Set the initial 'source_slot' in 'misc_virtual_ab_message' as the current slot. At the same time, add slot checks before erase data if virtual A/B is enabled. Test: virtual A/B update and erase. Signed-off-by: Ji Luo Change-Id: I84896335a95d9188b85e114037b470b3f4e7a209 (cherry picked from commit a522c2245c3e58adbbcb99c43e0917ce315cc1aa) (cherry picked from commit 40a1e64ded230e1c2b3d76cccaea1f910ed0d6d6) --- diff --git a/drivers/fastboot/fb_fsl/fb_fsl_command.c b/drivers/fastboot/fb_fsl/fb_fsl_command.c index 4f648d5e31..f6f7eaeccc 100644 --- a/drivers/fastboot/fb_fsl/fb_fsl_command.c +++ b/drivers/fastboot/fb_fsl/fb_fsl_command.c @@ -413,7 +413,8 @@ static FbLockState do_fastboot_unlock(bool force) #endif #ifdef CONFIG_VIRTUAL_AB_SUPPORT - if (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()) { + if (virtual_ab_update_is_merging() || + (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())) { printf("Can not erase userdata while a snapshot update is in progress!\n"); return FASTBOOT_LOCK_ERROR; } @@ -441,7 +442,8 @@ static FbLockState do_fastboot_lock(void) } #ifdef CONFIG_VIRTUAL_AB_SUPPORT - if (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted()) { + if (virtual_ab_update_is_merging() || + (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match())) { printf("Can not erase userdata while a snapshot update is in progress!\n"); return FASTBOOT_LOCK_ERROR; } diff --git a/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.c b/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.c index 09e54f51ee..11260e6b25 100644 --- a/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.c +++ b/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.c @@ -13,6 +13,7 @@ static int read_virtual_ab_message(misc_virtual_ab_message *message) { size_t num_bytes; + int source_slot; if (fsl_read_from_partition_multi(NULL, FASTBOOT_PARTITION_MISC, SYSTEM_SPACE_SIZE_IN_MISC, @@ -24,11 +25,18 @@ static int read_virtual_ab_message(misc_virtual_ab_message *message) if ((message->magic != MISC_VIRTUAL_AB_MAGIC_HEADER) || (message->version != MISC_VIRTUAL_AB_MESSAGE_VERSION)) { - printf("Invalid virtual AB status, resetting..."); + printf("Invalid virtual AB status, resetting...\n"); message->version = MISC_VIRTUAL_AB_MESSAGE_VERSION; message->magic = MISC_VIRTUAL_AB_MAGIC_HEADER; message->merge_status = VIRTUAL_AB_NONE; - message->source_slot = 0; + + /* Reset the source slot as the current slot */ + source_slot = current_slot(); + if (source_slot != -1) + message->source_slot = source_slot; + else + return -1; + if (fsl_write_to_partition(NULL, FASTBOOT_PARTITION_MISC, SYSTEM_SPACE_SIZE_IN_MISC, sizeof(misc_virtual_ab_message), @@ -49,7 +57,8 @@ bool partition_is_protected_during_merge(char *part) if ((!strncmp(part, "misc", sizeof("misc")) || !strncmp(part, "userdata", sizeof("userdata")) || !strncmp(part, "metadata", sizeof("metadata"))) && - (virtual_ab_update_is_merging() || virtual_ab_update_is_snapshoted())) + (virtual_ab_update_is_merging() || + (virtual_ab_update_is_snapshoted() && !virtual_ab_slot_match()))) return true; else return false; @@ -76,6 +85,17 @@ bool virtual_ab_update_is_snapshoted(void) return false; } +bool virtual_ab_slot_match(void) +{ + misc_virtual_ab_message message; + read_virtual_ab_message(&message); + + if (message.source_slot == current_slot()) + return true; + else + return false; +} + int virtual_ab_cancel_update(void) { misc_virtual_ab_message message; diff --git a/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.h b/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.h index 75ceb55092..3b33cd7ef2 100644 --- a/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.h +++ b/drivers/fastboot/fb_fsl/fb_fsl_virtual_ab.h @@ -14,4 +14,5 @@ typedef enum { bool partition_is_protected_during_merge(char *part); bool virtual_ab_update_is_merging(void); bool virtual_ab_update_is_snapshoted(void); +bool virtual_ab_slot_match(void); int virtual_ab_cancel_update(void); diff --git a/lib/avb/fsl/fsl_bootctrl.c b/lib/avb/fsl/fsl_bootctrl.c index 0414f09db7..db96b74862 100755 --- a/lib/avb/fsl/fsl_bootctrl.c +++ b/lib/avb/fsl/fsl_bootctrl.c @@ -37,6 +37,7 @@ * hardware/interfaces/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h */ #define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048 +extern AvbABOps fsl_avb_ab_ops; static char *slot_suffix[AVB_AB_SLOT_NUM] = {"_a", "_b"}; @@ -61,6 +62,19 @@ int get_curr_slot(struct bootloader_control *ab_data) { return -1; } +/* Return current slot without passing 'bootloader_control' struct */ +int current_slot(void) { + struct bootloader_control ab_data; + + /* Load A/B metadata and decide which slot we are going to load */ + if (fsl_avb_ab_ops.read_ab_metadata(&fsl_avb_ab_ops, &ab_data) != + AVB_IO_RESULT_OK) { + printf("Error loading AB metadata from misc!\n"); + return -1; + } + return get_curr_slot(&ab_data); +} + int slotidx_from_suffix(char *suffix) { int slot = -1; @@ -1048,7 +1062,6 @@ out: return ret; } -extern AvbABOps fsl_avb_ab_ops; static bool spl_recovery_flag = false; bool is_spl_recovery(void) { diff --git a/lib/avb/fsl/fsl_bootctrl.h b/lib/avb/fsl/fsl_bootctrl.h index 2d5be97f6b..6c7b30738a 100644 --- a/lib/avb/fsl/fsl_bootctrl.h +++ b/lib/avb/fsl/fsl_bootctrl.h @@ -133,6 +133,13 @@ bool is_slotvar_avb(char *cmd); * */ int get_curr_slot(struct bootloader_control* ab_data); +/* Get current bootable slot without passing the "bootloader_control" struct. + * return 0 for the first slot + * return 1 for the second slot + * return -1 for not supported slot + * */ +int current_slot(void); + /* return 0 for the first slot * return 1 for the second slot * return -1 for not supported slot