]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeCache.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / VariableRuntimeCache.c
CommitLineData
aab3b9b9
MK
1/** @file\r
2 Functions related to managing the UEFI variable runtime cache. This file should only include functions\r
3 used by the SMM UEFI variable driver.\r
4\r
5 Caution: This module requires additional review when modified.\r
6 This driver will have external input - variable data. They may be input in SMM mode.\r
7 This external input must be validated carefully to avoid security issue like\r
8 buffer overflow, integer overflow.\r
9\r
10Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
11SPDX-License-Identifier: BSD-2-Clause-Patent\r
12\r
13**/\r
14\r
15#include "VariableParsing.h"\r
16#include "VariableRuntimeCache.h"\r
17\r
1436aea4
MK
18extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;\r
19extern VARIABLE_STORE_HEADER *mNvVariableCache;\r
aab3b9b9
MK
20\r
21/**\r
22 Copies any pending updates to runtime variable caches.\r
23\r
24 @retval EFI_UNSUPPORTED The volatile store to be updated is not initialized properly.\r
25 @retval EFI_SUCCESS The volatile store was updated successfully.\r
26\r
27**/\r
28EFI_STATUS\r
29FlushPendingRuntimeVariableCacheUpdates (\r
30 VOID\r
31 )\r
32{\r
1436aea4 33 VARIABLE_RUNTIME_CACHE_CONTEXT *VariableRuntimeCacheContext;\r
aab3b9b9
MK
34\r
35 VariableRuntimeCacheContext = &mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext;\r
36\r
1436aea4
MK
37 if ((VariableRuntimeCacheContext->VariableRuntimeNvCache.Store == NULL) ||\r
38 (VariableRuntimeCacheContext->VariableRuntimeVolatileCache.Store == NULL) ||\r
39 (VariableRuntimeCacheContext->PendingUpdate == NULL))\r
40 {\r
aab3b9b9
MK
41 return EFI_UNSUPPORTED;\r
42 }\r
43\r
44 if (*(VariableRuntimeCacheContext->PendingUpdate)) {\r
1436aea4
MK
45 if ((VariableRuntimeCacheContext->VariableRuntimeHobCache.Store != NULL) &&\r
46 (mVariableModuleGlobal->VariableGlobal.HobVariableBase > 0))\r
47 {\r
aab3b9b9 48 CopyMem (\r
1436aea4
MK
49 (VOID *)(\r
50 ((UINT8 *)(UINTN)VariableRuntimeCacheContext->VariableRuntimeHobCache.Store) +\r
51 VariableRuntimeCacheContext->VariableRuntimeHobCache.PendingUpdateOffset\r
52 ),\r
53 (VOID *)(\r
54 ((UINT8 *)(UINTN)mVariableModuleGlobal->VariableGlobal.HobVariableBase) +\r
55 VariableRuntimeCacheContext->VariableRuntimeHobCache.PendingUpdateOffset\r
56 ),\r
aab3b9b9
MK
57 VariableRuntimeCacheContext->VariableRuntimeHobCache.PendingUpdateLength\r
58 );\r
59 VariableRuntimeCacheContext->VariableRuntimeHobCache.PendingUpdateLength = 0;\r
60 VariableRuntimeCacheContext->VariableRuntimeHobCache.PendingUpdateOffset = 0;\r
61 }\r
62\r
63 CopyMem (\r
1436aea4
MK
64 (VOID *)(\r
65 ((UINT8 *)(UINTN)VariableRuntimeCacheContext->VariableRuntimeNvCache.Store) +\r
66 VariableRuntimeCacheContext->VariableRuntimeNvCache.PendingUpdateOffset\r
67 ),\r
68 (VOID *)(\r
69 ((UINT8 *)(UINTN)mNvVariableCache) +\r
70 VariableRuntimeCacheContext->VariableRuntimeNvCache.PendingUpdateOffset\r
71 ),\r
aab3b9b9
MK
72 VariableRuntimeCacheContext->VariableRuntimeNvCache.PendingUpdateLength\r
73 );\r
74 VariableRuntimeCacheContext->VariableRuntimeNvCache.PendingUpdateLength = 0;\r
75 VariableRuntimeCacheContext->VariableRuntimeNvCache.PendingUpdateOffset = 0;\r
76\r
77 CopyMem (\r
1436aea4
MK
78 (VOID *)(\r
79 ((UINT8 *)(UINTN)VariableRuntimeCacheContext->VariableRuntimeVolatileCache.Store) +\r
80 VariableRuntimeCacheContext->VariableRuntimeVolatileCache.PendingUpdateOffset\r
81 ),\r
82 (VOID *)(\r
83 ((UINT8 *)(UINTN)mVariableModuleGlobal->VariableGlobal.VolatileVariableBase) +\r
84 VariableRuntimeCacheContext->VariableRuntimeVolatileCache.PendingUpdateOffset\r
85 ),\r
aab3b9b9
MK
86 VariableRuntimeCacheContext->VariableRuntimeVolatileCache.PendingUpdateLength\r
87 );\r
88 VariableRuntimeCacheContext->VariableRuntimeVolatileCache.PendingUpdateLength = 0;\r
89 VariableRuntimeCacheContext->VariableRuntimeVolatileCache.PendingUpdateOffset = 0;\r
1436aea4 90 *(VariableRuntimeCacheContext->PendingUpdate) = FALSE;\r
aab3b9b9
MK
91 }\r
92\r
93 return EFI_SUCCESS;\r
94}\r
95\r
96/**\r
97 Synchronizes the runtime variable caches with all pending updates outside runtime.\r
98\r
99 Ensures all conditions are met to maintain coherency for runtime cache updates. This function will attempt\r
100 to write the given update (and any other pending updates) if the ReadLock is available. Otherwise, the\r
101 update is added as a pending update for the given variable store and it will be flushed to the runtime cache\r
102 at the next opportunity the ReadLock is available.\r
103\r
104 @param[in] VariableRuntimeCache Variable runtime cache structure for the runtime cache being synchronized.\r
105 @param[in] Offset Offset in bytes to apply the update.\r
106 @param[in] Length Length of data in bytes of the update.\r
107\r
108 @retval EFI_SUCCESS The update was added as a pending update successfully. If the variable runtime\r
109 cache ReadLock was available, the runtime cache was updated successfully.\r
110 @retval EFI_UNSUPPORTED The volatile store to be updated is not initialized properly.\r
111\r
112**/\r
113EFI_STATUS\r
114SynchronizeRuntimeVariableCache (\r
1436aea4
MK
115 IN VARIABLE_RUNTIME_CACHE *VariableRuntimeCache,\r
116 IN UINTN Offset,\r
117 IN UINTN Length\r
aab3b9b9
MK
118 )\r
119{\r
120 if (VariableRuntimeCache == NULL) {\r
121 return EFI_INVALID_PARAMETER;\r
122 } else if (VariableRuntimeCache->Store == NULL) {\r
123 // The runtime cache may not be active or allocated yet.\r
124 // In either case, return EFI_SUCCESS instead of EFI_NOT_AVAILABLE_YET.\r
125 return EFI_SUCCESS;\r
126 }\r
127\r
1436aea4
MK
128 if ((mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.PendingUpdate == NULL) ||\r
129 (mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.ReadLock == NULL))\r
130 {\r
aab3b9b9
MK
131 return EFI_UNSUPPORTED;\r
132 }\r
133\r
134 if (*(mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.PendingUpdate) &&\r
1436aea4
MK
135 (VariableRuntimeCache->PendingUpdateLength > 0))\r
136 {\r
aab3b9b9 137 VariableRuntimeCache->PendingUpdateLength =\r
1436aea4
MK
138 (UINT32)(\r
139 MAX (\r
140 (UINTN)(VariableRuntimeCache->PendingUpdateOffset + VariableRuntimeCache->PendingUpdateLength),\r
141 Offset + Length\r
142 ) - MIN ((UINTN)VariableRuntimeCache->PendingUpdateOffset, Offset)\r
143 );\r
aab3b9b9 144 VariableRuntimeCache->PendingUpdateOffset =\r
1436aea4 145 (UINT32)MIN ((UINTN)VariableRuntimeCache->PendingUpdateOffset, Offset);\r
aab3b9b9 146 } else {\r
1436aea4
MK
147 VariableRuntimeCache->PendingUpdateLength = (UINT32)Length;\r
148 VariableRuntimeCache->PendingUpdateOffset = (UINT32)Offset;\r
aab3b9b9 149 }\r
1436aea4 150\r
aab3b9b9
MK
151 *(mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.PendingUpdate) = TRUE;\r
152\r
153 if (*(mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.ReadLock) == FALSE) {\r
154 return FlushPendingRuntimeVariableCacheUpdates ();\r
155 }\r
156\r
157 return EFI_SUCCESS;\r
158}\r