QcomModulePkg: Update GPT only when attributes or GUID is changed
In a scenario, when a missing Blkio handle occured and the partition
info in the storage is right, doing attributes and GUID compare will
update the GPT header which will cause the device boot up failed. So
don't update the GPT header if nothing attribute or GUID needed to be
changed.
Change-Id: I093c1b56da0c4315cd312cd031697d7eb10bdd53
diff --git a/QcomModulePkg/Include/Library/PartitionTableUpdate.h b/QcomModulePkg/Include/Library/PartitionTableUpdate.h
index 9135b50..a22eaae 100644
--- a/QcomModulePkg/Include/Library/PartitionTableUpdate.h
+++ b/QcomModulePkg/Include/Library/PartitionTableUpdate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -43,6 +43,15 @@
FAILURE,
};
+typedef enum {
+ PARTITION_ATTRIBUTES = 1,
+ PARTITION_GUID,
+ PARTITION_ALL,
+} UPDATE_TYPE;
+
+#define PARTITION_ATTRIBUTES_MASK 0x1
+#define PARTITION_GUID_MASK 0x2
+
#define MAX_HANDLEINF_LST_SIZE 128
#define PARTITION_TYPE_MBR 0
@@ -199,7 +208,7 @@
PartitionHasMultiSlot (CONST CHAR16 *Pname);
EFI_STATUS EnumeratePartitions (VOID);
VOID UpdatePartitionEntries (VOID);
-VOID UpdatePartitionAttributes (VOID);
+VOID UpdatePartitionAttributes (UINT32 UpdateType);
VOID FindPtnActiveSlot (VOID);
EFI_STATUS
FindBootableSlot (Slot *BootableSlot);
diff --git a/QcomModulePkg/Library/BootLib/PartitionTableUpdate.c b/QcomModulePkg/Library/BootLib/PartitionTableUpdate.c
old mode 100755
new mode 100644
index b23dc10..4a80645
--- a/QcomModulePkg/Library/BootLib/PartitionTableUpdate.c
+++ b/QcomModulePkg/Library/BootLib/PartitionTableUpdate.c
@@ -32,6 +32,7 @@
#include <Library/BootLinux.h>
#include <Library/LinuxLoaderLib.h>
#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
#include <Uefi.h>
#include <Uefi/UefiSpec.h>
#include <VerifiedBoot.h>
@@ -43,6 +44,7 @@
STATIC UINT32 MaxLuns;
STATIC UINT32 PartitionCount;
STATIC BOOLEAN FirstBoot;
+STATIC struct PartitionEntry PtnEntriesBak[MAX_NUM_PARTITIONS];
STATIC struct BootPartsLinkedList *HeadNode;
STATIC EFI_STATUS
@@ -129,6 +131,8 @@
PtnEntries[Index].lun = i;
}
}
+ /* Back up the ptn entries */
+ gBS->CopyMem (PtnEntriesBak, PtnEntries, sizeof (PtnEntries));
}
INT32
@@ -183,7 +187,15 @@
return Status;
}
-VOID UpdatePartitionAttributes (VOID)
+STATIC BOOLEAN IsUpdatePartitionAttributes ()
+{
+ if (CompareMem (PtnEntries, PtnEntriesBak, sizeof (PtnEntries))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+VOID UpdatePartitionAttributes (UINT32 UpdateType)
{
UINT32 BlkSz;
UINT8 *GptHdr = NULL;
@@ -211,6 +223,13 @@
UINT64 Attr;
struct PartitionEntry *InMemPtnEnt;
+ /* The PtnEntries is the same as PtnEntriesBak by default
+ * It needs to update attributes or GUID when PtnEntries is changed
+ */
+ if (!IsUpdatePartitionAttributes ()) {
+ return;
+ }
+
GetRootDeviceType (BootDeviceType, BOOT_DEV_NAME_SIZE_MAX);
for (Lun = 0; Lun < MaxLuns; Lun++) {
@@ -225,7 +244,8 @@
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_ERROR,
- "Failed to get BlkIo for device. MaxHandles:%d - %r\n", Status));
+ "Failed to get BlkIo for device. MaxHandles:%d - %r\n",
+ MaxHandles, Status));
return;
}
if (MaxHandles != 1) {
@@ -292,16 +312,47 @@
continue;
}
Attr = GET_LLWORD_FROM_BYTE (&PtnEntriesPtr[ATTRIBUTE_FLAG_OFFSET]);
- if ((Attr != PtnEntries[i].PartEntry.Attributes) ||
- memcmp (&InMemPtnEnt->PartEntry.PartitionTypeGUID,
- &PtnEntries[i].PartEntry.PartitionTypeGUID, sizeof (EFI_GUID))) {
- /* Update the partition attributes and partiton GUID values */
- PUT_LONG_LONG (&PtnEntriesPtr[ATTRIBUTE_FLAG_OFFSET],
- PtnEntries[i].PartEntry.Attributes);
- gBS->CopyMem ((VOID *)PtnEntriesPtr,
+ if (UpdateType & PARTITION_GUID_MASK) {
+ if (CompareMem (&InMemPtnEnt->PartEntry.PartitionTypeGUID,
+ &PtnEntries[i].PartEntry.PartitionTypeGUID,
+ sizeof (EFI_GUID))) {
+ /* Update the partition GUID values */
+ gBS->CopyMem ((VOID *)PtnEntriesPtr,
+ (VOID *)&PtnEntries[i].PartEntry.PartitionTypeGUID,
+ GUID_SIZE);
+ /* Update the PtnEntriesBak for next comparison */
+ gBS->CopyMem (
+ (VOID *)&PtnEntriesBak[i].PartEntry.PartitionTypeGUID,
(VOID *)&PtnEntries[i].PartEntry.PartitionTypeGUID,
GUID_SIZE);
- SkipUpdation = FALSE;
+ SkipUpdation = FALSE;
+ }
+ }
+
+ if (UpdateType & PARTITION_ATTRIBUTES_MASK) {
+ /* If GUID is not present, then it is back up GPT, update it
+ * If GUID is present, and the GUID is matched, update it
+ */
+ if (!(InMemPtnEnt->PartEntry.PartitionTypeGUID.Data1) ||
+ !CompareMem (&InMemPtnEnt->PartEntry.PartitionTypeGUID,
+ &PtnEntries[i].PartEntry.PartitionTypeGUID,
+ sizeof (EFI_GUID))) {
+ if (Attr != PtnEntries[i].PartEntry.Attributes) {
+ /* Update the partition attributes */
+ PUT_LONG_LONG (&PtnEntriesPtr[ATTRIBUTE_FLAG_OFFSET],
+ PtnEntries[i].PartEntry.Attributes);
+ /* Update the PtnEntriesBak for next comparison */
+ PtnEntriesBak[i].PartEntry.Attributes =
+ PtnEntries[i].PartEntry.Attributes;
+ SkipUpdation = FALSE;
+ }
+ } else {
+ if (InMemPtnEnt->PartEntry.PartitionTypeGUID.Data1) {
+ DEBUG ((EFI_D_ERROR,
+ "Error in GPT header, GUID is not match!\n"));
+ continue;
+ }
+ }
}
/* point to the next partition entry */
@@ -384,7 +435,7 @@
}
/* Update the partition table */
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
}
STATIC VOID
@@ -526,6 +577,8 @@
}
UfsGetSetBootLun (&UfsBootLun, UfsSet);
}
+
+ UpdatePartitionAttributes (PARTITION_GUID);
}
EFI_STATUS
@@ -1215,7 +1268,7 @@
GUARD (StrnCpyS (ActiveSlot->Suffix, ARRAY_SIZE (ActiveSlot->Suffix),
Slots[0].Suffix, StrLen (Slots[0].Suffix)));
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
FirstBoot = TRUE;
return EFI_SUCCESS;
}
@@ -1293,6 +1346,7 @@
BootEntry->PartEntry.Attributes |=
(((UINT64)MAX_PRIORITY - 1) << PART_ATT_PRIORITY_BIT);
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
if (StrnCmp (CurrentSlot.Suffix, NewSlot->Suffix,
StrLen (CurrentSlot.Suffix)) == 0) {
DEBUG ((EFI_D_INFO, "SetActiveSlot: %s already active slot\n",
@@ -1324,9 +1378,6 @@
SwitchPtnSlots (NewSlot->Suffix);
MarkPtnActive (NewSlot->Suffix);
}
-
- UpdatePartitionAttributes ();
-
return EFI_SUCCESS;
}
@@ -1356,7 +1407,7 @@
} else {
BootEntry->PartEntry.Attributes |=
(PART_ATT_UNBOOTABLE_VAL) & (~PART_ATT_SUCCESSFUL_VAL);
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
}
if (StrnCmp (ActiveSlot.Suffix, Slots[0].Suffix, StrLen (Slots[0].Suffix)) ==
@@ -1416,7 +1467,7 @@
return EFI_NOT_FOUND;
}
BootEntry->PartEntry.Attributes &= ~PART_ATT_UNBOOTABLE_VAL;
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
return EFI_SUCCESS;
}
@@ -1526,7 +1577,7 @@
BootEntry->PartEntry.Attributes &= ~PART_ATT_MAX_RETRY_COUNT_VAL;
BootEntry->PartEntry.Attributes |= RetryCount
<< PART_ATT_MAX_RETRY_CNT_BIT;
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
DEBUG ((EFI_D_INFO, "Active Slot %s is bootable, retry count %ld\n",
BootableSlot->Suffix, RetryCount));
} else {
diff --git a/QcomModulePkg/Library/FastbootLib/FastbootCmds.c b/QcomModulePkg/Library/FastbootLib/FastbootCmds.c
index 4e4d9b8..1001f06 100644
--- a/QcomModulePkg/Library/FastbootLib/FastbootCmds.c
+++ b/QcomModulePkg/Library/FastbootLib/FastbootCmds.c
@@ -973,7 +973,7 @@
Ptn_Entries_Ptr->PartEntry.Attributes |=
(PART_ATT_PRIORITY_VAL | PART_ATT_MAX_RETRY_COUNT_VAL);
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ATTRIBUTES);
for (j = 0; j < SlotCount; j++) {
if (AsciiStrStr (SlotSuffixAscii, BootSlotInfo[j].SlotSuffix)) {
AsciiStrnCpyS (BootSlotInfo[j].SlotSuccessfulVal,
@@ -1513,6 +1513,7 @@
/*Check for multislot boot support*/
MultiSlotBoot = PartitionHasMultiSlot (L"boot");
if (MultiSlotBoot) {
+ UpdatePartitionAttributes (PARTITION_ALL);
FindPtnActiveSlot ();
PopulateMultislotMetadata ();
DEBUG ((EFI_D_VERBOSE, "Multi Slot boot is supported\n"));
@@ -1921,7 +1922,7 @@
j++;
} while (!SlotVarUpdateComplete);
- UpdatePartitionAttributes ();
+ UpdatePartitionAttributes (PARTITION_ALL);
FastbootOkay ("");
}
#endif