X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FVariable%2FRuntimeDxe%2FVariable.c;h=98137c6a3f0cf83d26a99320a34b1a5da07ec2db;hb=ce8bd86e8f49f17fd2b11e14bbc3b3e816d82c1b;hp=f59d2a396981102b7fecde6faad535e41e028c2a;hpb=f53a07320e7021b5a80973cc7b265bd8ce5caf40;p=mirror_edk2.git diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c index f59d2a3969..98137c6a3f 100644 --- a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -1,13 +1,13 @@ /*++ -Copyright (c) 2006, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. Module Name: @@ -27,42 +27,39 @@ Revision History // ESAL_VARIABLE_GLOBAL *mVariableModuleGlobal; -UINT32 -EFIAPI -ArrayLength ( - IN CHAR16 *String +// +// This is a temperary function which will be removed +// when EfiAcquireLock in UefiLib can handle the +// the call in UEFI Runtimer driver in RT phase. +// +STATIC +VOID +AcquireLockOnlyAtBootTime ( + IN EFI_LOCK *Lock ) -/*++ - -Routine Description: - - Determine the length of null terminated char16 array. - -Arguments: - - String Null-terminated CHAR16 array pointer. - -Returns: - - UINT32 Number of bytes in the string, including the double NULL at the end; - ---*/ { - UINT32 Count; - - if (NULL == String) { - return 0; + if (!EfiAtRuntime ()) { + EfiAcquireLock (Lock); } +} - Count = 0; - - while (0 != String[Count]) { - Count++; +// +// This is a temperary function which will be removed +// when EfiAcquireLock in UefiLib can handle the +// the call in UEFI Runtimer driver in RT phase. +// +STATIC +VOID +ReleaseLockOnlyAtBootTime ( + IN EFI_LOCK *Lock + ) +{ + if (!EfiAtRuntime ()) { + EfiReleaseLock (Lock); } - - return (Count * 2) + 2; } +STATIC BOOLEAN EFIAPI IsValidVariableHeader ( @@ -93,6 +90,7 @@ Returns: return TRUE; } +STATIC EFI_STATUS EFIAPI UpdateVariableStore ( @@ -242,6 +240,7 @@ Returns: return EFI_SUCCESS; } +STATIC VARIABLE_STORE_STATUS EFIAPI GetVariableStoreStatus ( @@ -261,7 +260,7 @@ Returns: EfiRaw Variable store status is raw EfiValid Variable store status is valid - EfiInvalid Variable store status is invalid + EfiInvalid Variable store status is invalid --*/ { @@ -283,6 +282,7 @@ Returns: } } +STATIC UINT8 * EFIAPI GetVariableDataPtr ( @@ -310,6 +310,7 @@ Returns: return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize)); } +STATIC VARIABLE_HEADER * EFIAPI GetNextVariablePtr ( @@ -340,6 +341,7 @@ Returns: return (VARIABLE_HEADER *) ((UINTN) GetVariableDataPtr (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize)); } +STATIC VARIABLE_HEADER * EFIAPI GetEndPointer ( @@ -367,6 +369,7 @@ Returns: return (VARIABLE_HEADER *) ((UINTN) VarStoreHeader + VarStoreHeader->Size); } +STATIC EFI_STATUS EFIAPI Reclaim ( @@ -487,6 +490,7 @@ Returns: return Status; } +STATIC EFI_STATUS EFIAPI FindVariable ( @@ -520,6 +524,13 @@ Returns: VARIABLE_STORE_HEADER *VariableStoreHeader[2]; UINTN Index; + // + // We aquire the lock at the entry of FindVariable as GetVariable, GetNextVariableName + // SetVariable all call FindVariable at entry point. Please move "Aquire Lock" to + // the correct places if this assumption does not hold TRUE anymore. + // + AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); + // // 0: Non-Volatile, 1: Volatile // @@ -552,7 +563,7 @@ Returns: return EFI_SUCCESS; } else { if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) { - if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), ArrayLength (VariableName))) { + if (!CompareMem (VariableName, GET_VARIABLE_NAME_PTR (Variable[Index]), Variable[Index]->NameSize)) { PtrTrack->CurrPtr = Variable[Index]; PtrTrack->Volatile = (BOOLEAN) Index; return EFI_SUCCESS; @@ -622,7 +633,7 @@ Returns: Status = FindVariable (VariableName, VendorGuid, &Variable, Global); if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { - return Status; + goto Done; } // // Get data size @@ -630,7 +641,8 @@ Returns: VarDataSize = Variable.CurrPtr->DataSize; if (*DataSize >= VarDataSize) { if (Data == NULL) { - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize); @@ -639,11 +651,17 @@ Returns: } *DataSize = VarDataSize; - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } else { *DataSize = VarDataSize; - return EFI_BUFFER_TOO_SMALL; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; } + +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; } EFI_STATUS @@ -686,7 +704,7 @@ Returns: Status = FindVariable (VariableName, VendorGuid, &Variable, Global); if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) { - return Status; + goto Done; } if (VariableName[0] != 0) { @@ -707,7 +725,8 @@ Returns: Variable.StartPtr = (VARIABLE_HEADER *) ((UINTN) (Global->VolatileVariableBase + sizeof (VARIABLE_STORE_HEADER))); Variable.EndPtr = (VARIABLE_HEADER *) GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase)); } else { - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + goto Done; } Variable.CurrPtr = Variable.StartPtr; @@ -738,14 +757,16 @@ Returns: } *VariableNameSize = VarNameSize; - return Status; + goto Done; } } Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); } - return EFI_NOT_FOUND; +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; } EFI_STATUS @@ -809,41 +830,47 @@ Returns: Status = FindVariable (VariableName, VendorGuid, &Variable, Global); if (Status == EFI_INVALID_PARAMETER) { - return Status; + goto Done; } else if (!EFI_ERROR (Status) && Variable.Volatile && EfiAtRuntime()) { // - // If EfiAtRuntime and the variable is Volatile and Runtime Access, - // the volatile is ReadOnly, and SetVariable should be aborted and + // If EfiAtRuntime and the variable is Volatile and Runtime Access, + // the volatile is ReadOnly, and SetVariable should be aborted and // return EFI_WRITE_PROTECTED. // - return EFI_WRITE_PROTECTED; - } else if (sizeof (VARIABLE_HEADER) + ArrayLength (VariableName) + DataSize > MAX_VARIABLE_SIZE) { + Status = EFI_WRITE_PROTECTED; + goto Done; + } else if (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + DataSize > MAX_VARIABLE_SIZE) { // // The size of the VariableName, including the Unicode Null in bytes plus // the DataSize is limited to maximum size of MAX_VARIABLE_SIZE (1024) bytes. // - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } else if (Attributes == EFI_VARIABLE_NON_VOLATILE) { // - // Make sure not only EFI_VARIABLE_NON_VOLATILE is set + // Make sure not only EFI_VARIABLE_NON_VOLATILE is set // - return EFI_INVALID_PARAMETER; - } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == + Status = EFI_INVALID_PARAMETER; + goto Done; + } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { // // Make sure if runtime bit is set, boot service bit is set also // - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) { // // Runtime but Attribute is not Runtime // - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } else if (EfiAtRuntime () && Attributes && !(Attributes & EFI_VARIABLE_NON_VOLATILE)) { // // Cannot set volatile variable in Runtime // - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } else if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) { // // Setting a data variable with no access, or zero DataSize attributes @@ -863,13 +890,15 @@ Returns: &State ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + goto Done; } else { if (!EFI_ERROR (Status)) { // @@ -879,7 +908,8 @@ Returns: if (Variable.CurrPtr->DataSize == DataSize && !CompareMem (Data, GetVariableDataPtr (Variable.CurrPtr), DataSize) ) { - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } else if (Variable.CurrPtr->State == VAR_ADDED) { // // Mark the old variable as in delete transition @@ -897,7 +927,7 @@ Returns: &State ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } } } @@ -918,7 +948,7 @@ Returns: // NextVariable->Reserved = 0; VarNameOffset = sizeof (VARIABLE_HEADER); - VarNameSize = ArrayLength (VariableName); + VarNameSize = StrSize (VariableName); CopyMem ( (UINT8 *) ((UINTN) NextVariable + VarNameOffset), VariableName, @@ -949,14 +979,15 @@ Returns: ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size ) { if (EfiAtRuntime ()) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Perform garbage collection & reclaim operation // Status = Reclaim (Global->NonVolatileVariableBase, NonVolatileOffset, FALSE); if (EFI_ERROR (Status)) { - return Status; + goto Done; } // // If still no enough space, return out of resources @@ -964,9 +995,10 @@ Returns: if ((UINT32) (VarSize +*NonVolatileOffset) > ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->NonVolatileVariableBase)))->Size ) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } - + Reclaimed = TRUE; } // @@ -989,7 +1021,7 @@ Returns: ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } // // Step 2: @@ -1005,7 +1037,7 @@ Returns: ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } // // Step 3: @@ -1022,14 +1054,15 @@ Returns: ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } *NonVolatileOffset = *NonVolatileOffset + VarSize; } else { if (EfiAtRuntime ()) { - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } if ((UINT32) (VarSize +*VolatileOffset) > @@ -1040,7 +1073,7 @@ Returns: // Status = Reclaim (Global->VolatileVariableBase, VolatileOffset, TRUE); if (EFI_ERROR (Status)) { - return Status; + goto Done; } // // If still no enough space, return out of resources @@ -1048,9 +1081,10 @@ Returns: if ((UINT32) (VarSize +*VolatileOffset) > ((VARIABLE_STORE_HEADER *) ((UINTN) (Global->VolatileVariableBase)))->Size ) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } - + Reclaimed = TRUE; } @@ -1066,7 +1100,7 @@ Returns: ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } *VolatileOffset = *VolatileOffset + VarSize; @@ -1089,15 +1123,17 @@ Returns: ); if (EFI_ERROR (Status)) { - return Status; + goto Done; } } } - return EFI_SUCCESS; + Status = EFI_SUCCESS; +Done: + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); + return Status; } -#if (EFI_SPECIFICATION_VERSION >= 0x00020000) EFI_STATUS EFIAPI QueryVariableInfo ( @@ -1116,11 +1152,11 @@ Routine Description: Arguments: - Attributes Attributes bitmask to specify the type of variables + Attributes Attributes bitmask to specify the type of variables on which to return information. MaximumVariableStorageSize Pointer to the maximum size of the storage space available for the EFI variables associated with the attributes specified. - RemainingVariableStorageSize Pointer to the remaining size of the storage space available + RemainingVariableStorageSize Pointer to the remaining size of the storage space available for the EFI variables associated with the attributes specified. MaximumVariableSize Pointer to the maximum size of the individual EFI variables associated with the attributes specified. @@ -1140,7 +1176,7 @@ Returns: VARIABLE_HEADER *NextVariable; UINT64 VariableSize; VARIABLE_STORE_HEADER *VariableStoreHeader; - + if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL) { return EFI_INVALID_PARAMETER; } @@ -1162,11 +1198,13 @@ Returns: return EFI_INVALID_PARAMETER; } + AcquireLockOnlyAtBootTime(&Global->VariableServicesLock); + if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { // // Query is Volatile related. // - VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) Global->VolatileVariableBase); } else { // // Query is Non-Volatile related. @@ -1175,7 +1213,7 @@ Returns: } // - // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize + // Now let's fill *MaximumVariableStorageSize *RemainingVariableStorageSize // with the storage size (excluding the storage header size). // *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); @@ -1200,15 +1238,15 @@ Returns: if (EfiAtRuntime ()) { // - // we don't take the state of the variables in mind + // we don't take the state of the variables in mind // when calculating RemainingVariableStorageSize, - // since the space occupied by variables not marked with + // since the space occupied by variables not marked with // VAR_ADDED is not allowed to be reclaimed in Runtime. // *RemainingVariableStorageSize -= VariableSize; } else { // - // Only care about Variables with State VAR_ADDED,because + // Only care about Variables with State VAR_ADDED,because // the space not marked as VAR_ADDED is reclaimable now. // if (Variable->State == VAR_ADDED) { @@ -1222,9 +1260,9 @@ Returns: Variable = NextVariable; } + ReleaseLockOnlyAtBootTime (&Global->VariableServicesLock); return EFI_SUCCESS; } -#endif EFI_STATUS EFIAPI @@ -1243,9 +1281,9 @@ Arguments: SystemTable - A pointer to the EFI System Table. Returns: - + Status code. - + EFI_NOT_FOUND - Variable store area not found. EFI_UNSUPPORTED - Currently only one non-volatile variable store is supported. EFI_SUCCESS - Variable services successfully initialized. @@ -1279,6 +1317,9 @@ Returns: if (EFI_ERROR (Status)) { return Status; } + + EfiInitializeLock(&mVariableModuleGlobal->VariableGlobal[Physical].VariableServicesLock, EFI_TPL_NOTIFY); + // // Allocate memory for volatile variable store // @@ -1298,7 +1339,7 @@ Returns: // // Variable Specific Data // - mVariableModuleGlobal->VariableBase[Physical].VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore; + mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore; mVariableModuleGlobal->VolatileLastVariableOffset = sizeof (VARIABLE_STORE_HEADER); VolatileVariableStore->Signature = VARIABLE_STORE_SIGNATURE; @@ -1344,7 +1385,7 @@ Returns: // // Get address of non volatile variable store base // - mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase = VariableStoreEntry.Base; + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = VariableStoreEntry.Base; // // Check Integrity @@ -1353,7 +1394,7 @@ Returns: // Find the Correct Instance of the FV Block Service. // Instance = 0; - CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase); + CurrPtr = (CHAR8 *) ((UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase); while (EfiFvbGetPhysicalAddress (Instance, &FvVolHdr) == EFI_SUCCESS) { FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvVolHdr); if (CurrPtr >= (CHAR8 *) FwVolHeader && CurrPtr < (((CHAR8 *) FwVolHeader) + FwVolHeader->FvLength)) { @@ -1368,7 +1409,7 @@ Returns: if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) { if (~VariableStoreHeader->Size == 0) { Status = UpdateVariableStore ( - &mVariableModuleGlobal->VariableBase[Physical], + &mVariableModuleGlobal->VariableGlobal[Physical], FALSE, FALSE, mVariableModuleGlobal->FvbInstance, @@ -1382,7 +1423,7 @@ Returns: } } - mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr); + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) CurrPtr); // // Parse non-volatile variable data and get last variable offset // @@ -1400,7 +1441,7 @@ Returns: // if ((((VARIABLE_STORE_HEADER *)((UINTN) CurrPtr))->Size - mVariableModuleGlobal->NonVolatileLastVariableOffset) < VARIABLE_RECLAIM_THRESHOLD) { Status = Reclaim ( - mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase, + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE ); @@ -1416,13 +1457,13 @@ Returns: // Check if the free area is really free. // for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < VariableStoreHeader->Size; Index++) { - Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase)[Index]; + Data = ((UINT8 *) (UINTN) mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase)[Index]; if (Data != 0xff) { // // There must be something wrong in variable store, do reclaim operation. // Status = Reclaim ( - mVariableModuleGlobal->VariableBase[Physical].NonVolatileVariableBase, + mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase, &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE );