]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
MdeModulePkg: Connect VariablePolicy business logic to VariableServices
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / VariableDxe.c
index f1304c9dbccca27adf77cda5c30475bc83f9e537..0fca0bb2a9b51233d558044d89a317b3941448e8 100644 (file)
@@ -5,24 +5,34 @@
 Copyright (C) 2013, Red Hat, Inc.\r
 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "Variable.h"\r
 \r
+#include <Protocol/VariablePolicy.h>\r
+#include <Library/VariablePolicyLib.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ProtocolIsVariablePolicyEnabled (\r
+  OUT BOOLEAN *State\r
+  );\r
+\r
 EFI_HANDLE                          mHandle                    = NULL;\r
 EFI_EVENT                           mVirtualAddressChangeEvent = NULL;\r
-EFI_EVENT                           mFtwRegistration           = NULL;\r
+VOID                                *mFtwRegistration          = NULL;\r
 VOID                                ***mVarCheckAddressPointer = NULL;\r
 UINTN                               mVarCheckAddressPointerCount = 0;\r
 EDKII_VARIABLE_LOCK_PROTOCOL        mVariableLock              = { VariableLockRequestToLock };\r
+EDKII_VARIABLE_POLICY_PROTOCOL      mVariablePolicyProtocol    = { EDKII_VARIABLE_POLICY_PROTOCOL_REVISION,\r
+                                                                    DisableVariablePolicy,\r
+                                                                    ProtocolIsVariablePolicyEnabled,\r
+                                                                    RegisterVariablePolicy,\r
+                                                                    DumpVariablePolicy,\r
+                                                                    LockVariablePolicy };\r
 EDKII_VAR_CHECK_PROTOCOL            mVarCheck                  = { VarCheckRegisterSetVariableCheckHandler,\r
                                                                     VarCheckVariablePropertySet,\r
                                                                     VarCheckVariablePropertyGet };\r
@@ -236,14 +246,16 @@ VariableClassAddressChangeEvent (
 {\r
   UINTN          Index;\r
 \r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
-  EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
+  if (mVariableModuleGlobal->FvbInstance != NULL) {\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
+    EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
+  }\r
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);\r
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);\r
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);\r
@@ -286,8 +298,13 @@ OnReadyToBoot (
   VOID                                    *Context\r
   )\r
 {\r
+  EFI_STATUS        Status;\r
+\r
   if (!mEndOfDxe) {\r
     MorLockInitAtEndOfDxe ();\r
+\r
+    Status = LockVariablePolicy ();\r
+    ASSERT_EFI_ERROR (Status);\r
     //\r
     // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.\r
     //\r
@@ -326,8 +343,12 @@ OnEndOfDxe (
   VOID                                    *Context\r
   )\r
 {\r
+  EFI_STATUS    Status;\r
+\r
   DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n"));\r
   MorLockInitAtEndOfDxe ();\r
+  Status = LockVariablePolicy ();\r
+  ASSERT_EFI_ERROR (Status);\r
   mEndOfDxe = TRUE;\r
   mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);\r
   //\r
@@ -341,6 +362,40 @@ OnEndOfDxe (
   gBS->CloseEvent (Event);\r
 }\r
 \r
+/**\r
+  Initializes variable write service for DXE.\r
+\r
+**/\r
+VOID\r
+VariableWriteServiceInitializeDxe (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  Status = VariableWriteServiceInitialize ();\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));\r
+  }\r
+\r
+  //\r
+  // Some Secure Boot Policy Var (SecureBoot, etc) updates following other\r
+  // Secure Boot Policy Variable change. Record their initial value.\r
+  //\r
+  RecordSecureBootPolicyVarData();\r
+\r
+  //\r
+  // Install the Variable Write Architectural protocol.\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &mHandle,\r
+                  &gEfiVariableWriteArchProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
 /**\r
   Fault Tolerant Write protocol notification event handler.\r
 \r
@@ -382,13 +437,17 @@ FtwNotificationEvent (
     ASSERT (PcdGet32 (PcdFlashNvStorageVariableSize) <= FtwMaxBlockSize);\r
   }\r
 \r
+  NvStorageVariableBase = NV_STORAGE_VARIABLE_BASE;\r
+  VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;\r
+\r
+  //\r
+  // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.\r
+  //\r
+  mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
+\r
   //\r
   // Find the proper FVB protocol for variable.\r
   //\r
-  NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
-  if (NvStorageVariableBase == 0) {\r
-    NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
-  }\r
   Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);\r
   if (EFI_ERROR (Status)) {\r
     return ;\r
@@ -398,7 +457,6 @@ FtwNotificationEvent (
   //\r
   // Mark the variable storage region of the FLASH as RUNTIME.\r
   //\r
-  VariableStoreBase   = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;\r
   VariableStoreLength = mNvVariableCache->Size;\r
   BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);\r
   Length      = VariableStoreLength + (VariableStoreBase - BaseAddress);\r
@@ -420,27 +478,10 @@ FtwNotificationEvent (
     }\r
   }\r
 \r
-  Status = VariableWriteServiceInitialize ();\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));\r
-  }\r
-\r
   //\r
-  // Some Secure Boot Policy Var (SecureBoot, etc) updates following other\r
-  // Secure Boot Policy Variable change. Record their initial value.\r
+  // Initializes variable write service after FTW was ready.\r
   //\r
-  RecordSecureBootPolicyVarData();\r
-\r
-  //\r
-  // Install the Variable Write Architectural protocol.\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &mHandle,\r
-                  &gEfiVariableWriteArchProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  NULL\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
+  VariableWriteServiceInitializeDxe ();\r
 \r
   //\r
   // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.\r
@@ -450,6 +491,28 @@ FtwNotificationEvent (
 }\r
 \r
 \r
+/**\r
+  This API function returns whether or not the policy engine is\r
+  currently being enforced.\r
+\r
+  @param[out]   State       Pointer to a return value for whether the policy enforcement\r
+                            is currently enabled.\r
+\r
+  @retval     EFI_SUCCESS\r
+  @retval     Others        An error has prevented this command from completing.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ProtocolIsVariablePolicyEnabled (\r
+  OUT BOOLEAN *State\r
+  )\r
+{\r
+  *State = IsVariablePolicyEnabled ();\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Variable Driver main entry point. The Variable driver places the 4 EFI\r
   runtime services in the EFI System Table and installs arch protocols\r
@@ -508,16 +571,23 @@ VariableServiceInitialize (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Register FtwNotificationEvent () notify function.\r
-  //\r
-  EfiCreateProtocolNotifyEvent (\r
-    &gEfiFaultTolerantWriteProtocolGuid,\r
-    TPL_CALLBACK,\r
-    FtwNotificationEvent,\r
-    (VOID *)SystemTable,\r
-    &mFtwRegistration\r
-    );\r
+  if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {\r
+    //\r
+    // Register FtwNotificationEvent () notify function.\r
+    //\r
+    EfiCreateProtocolNotifyEvent (\r
+      &gEfiFaultTolerantWriteProtocolGuid,\r
+      TPL_CALLBACK,\r
+      FtwNotificationEvent,\r
+      (VOID *)SystemTable,\r
+      &mFtwRegistration\r
+      );\r
+  } else {\r
+    //\r
+    // Emulated non-volatile variable mode does not depend on FVB and FTW.\r
+    //\r
+    VariableWriteServiceInitializeDxe ();\r
+  }\r
 \r
   Status = gBS->CreateEventEx (\r
                   EVT_NOTIFY_SIGNAL,\r
@@ -553,6 +623,19 @@ VariableServiceInitialize (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  // Register and initialize the VariablePolicy engine.\r
+  Status = InitVariablePolicyLib (VariableServiceGetVariable);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = VarCheckRegisterSetVariableCheckHandler (ValidateSetVariable);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &mHandle,\r
+                    &gEdkiiVariablePolicyProtocolGuid,\r
+                    &mVariablePolicyProtocol,\r
+                    NULL\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r