]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/HiiDB: Make sure database update behaviors are atomic
authorDandan Bi <dandan.bi@intel.com>
Fri, 12 Oct 2018 10:13:19 +0000 (18:13 +0800)
committerHao Wu <hao.a.wu@intel.com>
Fri, 26 Oct 2018 07:08:44 +0000 (15:08 +0800)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1235

When update contents in HiiDatabase, like:
1. Add/update/remove package list
2. Add/update string
3. Add/update image
We should make these operations atomic to prevent the
potential issue that the one update operation with
higher TPL may interrupt another.
This commit is to make the HiiDatabase update behaviors
atomic by adding EfiAcquireLock/EfiReleaseLock function.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
MdeModulePkg/Universal/HiiDatabaseDxe/Database.c
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h
MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
MdeModulePkg/Universal/HiiDatabaseDxe/String.c

index 655eba8cb90402dd48c91ff8656c97e87f44b8ef..b59a9b2965af10c527510a25089602473862de18 100644 (file)
@@ -26,6 +26,11 @@ UINTN                          gNvDefaultStoreSize = 0;
 SKU_ID                         gSkuId              = 0xFFFFFFFFFFFFFFFF;\r
 LIST_ENTRY                     gVarStorageList     = INITIALIZE_LIST_HEAD_VARIABLE (gVarStorageList);\r
 \r
+//\r
+// HII database lock.\r
+//\r
+EFI_LOCK mHiiDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE(TPL_NOTIFY);\r
+\r
 /**\r
   This function generates a HII_DATABASE_RECORD node and adds into hii database.\r
   This is a internal function.\r
@@ -3493,11 +3498,14 @@ HiiNewPackageList (
     }\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   //\r
   // Build a PackageList node\r
   //\r
   Status = GenerateHiiDatabaseRecord (Private, &DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -3507,6 +3515,7 @@ HiiNewPackageList (
   //\r
   Status = AddPackages (Private, EFI_HII_DATABASE_NOTIFY_NEW_PACK, PackageList, DatabaseRecord);\r
   if (EFI_ERROR (Status)) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return Status;\r
   }\r
 \r
@@ -3534,8 +3543,17 @@ HiiNewPackageList (
   if (gExportAfterReadyToBoot) {\r
     HiiGetDatabaseInfo (This);\r
   }\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
 \r
   //\r
+  // Notes:\r
+  // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+  // belong to the atomic behavior of Hii Database update.\r
+  // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+  // we can not think it belong to the atomic behavior of Hii Database update.\r
+  // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+  //\r
+\r
   // Check whether need to get the configuration setting info from HII drivers.\r
   // When after ReadyToBoot and need to do the export for form package add.\r
   //\r
@@ -3585,6 +3603,8 @@ HiiRemovePackageList (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Private = HII_DATABASE_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   //\r
@@ -3602,34 +3622,42 @@ HiiRemovePackageList (
       //\r
       Status = RemoveGuidPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFormPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveKeyboardLayoutPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveStringPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveImagePackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveSimpleFontPackages (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
       Status = RemoveDevicePathPackage (Private, Handle, PackageList);\r
       if (EFI_ERROR (Status)) {\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return Status;\r
       }\r
 \r
@@ -3655,6 +3683,16 @@ HiiRemovePackageList (
       if (gExportAfterReadyToBoot) {\r
         HiiGetDatabaseInfo (This);\r
       }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
 \r
       //\r
       // Check whether need to get the configuration setting info from HII drivers.\r
@@ -3667,6 +3705,7 @@ HiiRemovePackageList (
     }\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -3719,6 +3758,7 @@ HiiUpdatePackageList (
 \r
   Status = EFI_SUCCESS;\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
   //\r
   // Get original packagelist to be updated\r
   //\r
@@ -3760,6 +3800,7 @@ HiiUpdatePackageList (
         }\r
 \r
         if (EFI_ERROR (Status)) {\r
+          EfiReleaseLock (&mHiiDatabaseLock);\r
           return Status;\r
         }\r
 \r
@@ -3779,6 +3820,16 @@ HiiUpdatePackageList (
       if (gExportAfterReadyToBoot && Status == EFI_SUCCESS) {\r
         HiiGetDatabaseInfo (This);\r
       }\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
+      //\r
+      // Notes:\r
+      // HiiGetDatabaseInfo () will get the contents of HII data base,\r
+      // belong to the atomic behavior of Hii Database update.\r
+      // And since HiiGetConfigRespInfo () will get the configuration setting info from HII drivers\r
+      // we can not think it belong to the atomic behavior of Hii Database update.\r
+      // That's why EfiReleaseLock (&mHiiDatabaseLock) is callled before HiiGetConfigRespInfo ().\r
+      //\r
 \r
       //\r
       // Check whether need to get the configuration setting info from HII drivers.\r
@@ -3791,7 +3842,7 @@ HiiUpdatePackageList (
       return Status;\r
     }\r
   }\r
-\r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
index 3a6eb8a55c79306006e5e08862d5faa18bcf41ba..154e36e88f4baf4008350783dc5d5b8cdf46de17 100644 (file)
@@ -61,6 +61,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define BITMAP_LEN_8_BIT(Width, Height)  ((Width) * (Height))\r
 #define BITMAP_LEN_24_BIT(Width, Height) ((Width) * (Height) * 3)\r
 \r
+extern EFI_LOCK mHiiDatabaseLock;\r
+\r
 //\r
 // IFR data structure\r
 //\r
index d1010820e05e67d352257a30f1dccc8b48954bfd..71ebc559c07f14d0aa27f1d779bff1682fea405b 100644 (file)
@@ -649,6 +649,8 @@ HiiNewImage (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   NewBlockSize = sizeof (EFI_HII_IIBT_IMAGE_24BIT_BLOCK) - sizeof (EFI_HII_RGB_PIXEL) +\r
                  BITMAP_LEN_24_BIT ((UINT32) Image->Width, Image->Height);\r
 \r
@@ -671,6 +673,7 @@ HiiNewImage (
     //\r
     ImageBlocks = AllocatePool (ImagePackage->ImageBlockSize + NewBlockSize);\r
     if (ImageBlocks == NULL) {\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
@@ -704,6 +707,7 @@ HiiNewImage (
     //\r
     ImagePackage = (HII_IMAGE_PACKAGE_INSTANCE *) AllocateZeroPool (sizeof (HII_IMAGE_PACKAGE_INSTANCE));\r
     if (ImagePackage == NULL) {\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
@@ -732,6 +736,7 @@ HiiNewImage (
     ImagePackage->ImageBlock = AllocateZeroPool (NewBlockSize + sizeof (EFI_HII_IIBT_END_BLOCK));\r
     if (ImagePackage->ImageBlock == NULL) {\r
       FreePool (ImagePackage);\r
+      EfiReleaseLock (&mHiiDatabaseLock);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     ImageBlocks = ImagePackage->ImageBlock;\r
@@ -769,6 +774,8 @@ HiiNewImage (
     HiiGetDatabaseInfo(&Private->HiiDatabase);\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1064,6 +1071,8 @@ HiiSetImage (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   //\r
   // Get the size of original image block. Use some common block code here\r
   // since the definition of some structures is the same.\r
@@ -1108,6 +1117,7 @@ HiiSetImage (
                      );\r
     break;\r
   default:\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -1121,6 +1131,7 @@ HiiSetImage (
   //\r
   ImageBlocks = AllocateZeroPool (ImagePackage->ImageBlockSize + NewBlockSize - OldBlockSize);\r
   if (ImageBlocks == NULL) {\r
+    EfiReleaseLock (&mHiiDatabaseLock);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -1158,6 +1169,7 @@ HiiSetImage (
     HiiGetDatabaseInfo(&Private->HiiDatabase);\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_SUCCESS;\r
 \r
 }\r
index aeda47430f7203c5c2f82756ad125a3a59655955..a8178bdca2523719d599c370795cb1582c7baf4a 100644 (file)
@@ -1210,6 +1210,8 @@ HiiNewString (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Status = EFI_SUCCESS;\r
   NewStringPackageCreated = FALSE;\r
   NewStringId   = 0;\r
@@ -1573,6 +1575,8 @@ Done:
     }\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
+\r
   return Status;\r
 }\r
 \r
@@ -1738,6 +1742,8 @@ HiiSetString (
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  EfiAcquireLock (&mHiiDatabaseLock);\r
+\r
   Private = HII_STRING_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
   PackageListNode = NULL;\r
 \r
@@ -1764,6 +1770,7 @@ HiiSetString (
                    (EFI_FONT_INFO *) StringFontInfo\r
                    );\r
         if (EFI_ERROR (Status)) {\r
+          EfiReleaseLock (&mHiiDatabaseLock);\r
           return Status;\r
         }\r
         PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length - OldPackageLen;\r
@@ -1774,11 +1781,13 @@ HiiSetString (
         if (gExportAfterReadyToBoot) {\r
           HiiGetDatabaseInfo(&Private->HiiDatabase);\r
         }\r
+        EfiReleaseLock (&mHiiDatabaseLock);\r
         return EFI_SUCCESS;\r
       }\r
     }\r
   }\r
 \r
+  EfiReleaseLock (&mHiiDatabaseLock);\r
   return EFI_NOT_FOUND;\r
 }\r
 \r