TianoCore EDK2 master
Loading...
Searching...
No Matches
VariableSmm.c
Go to the documentation of this file.
1
26#include <Protocol/MmEndOfDxe.h>
28
30#include <Library/VariablePolicyLib.h>
31
33#include "Variable.h"
34#include "VariableParsing.h"
36
38
39BOOLEAN mAtRuntime = FALSE;
40UINT8 *mVariableBufferPayload = NULL;
41UINTN mVariableBufferPayloadSize;
42
50VOID
51EFIAPI
53 IN CHAR16 *VariableName,
54 IN EFI_GUID *VendorGuid
55 )
56{
57 return;
58}
59
79EFIAPI
81 IN CHAR16 *VariableName,
82 IN EFI_GUID *VendorGuid,
83 IN UINT32 Attributes,
84 IN UINTN DataSize,
85 IN VOID *Data
86 )
87{
88 EFI_STATUS Status;
89
90 //
91 // Disable write protection when the calling SetVariable() through EFI_SMM_VARIABLE_PROTOCOL.
92 //
93 mRequestSource = VarCheckFromTrusted;
95 VariableName,
96 VendorGuid,
97 Attributes,
98 DataSize,
99 Data
100 );
101 mRequestSource = VarCheckFromUntrusted;
102 return Status;
103}
104
105EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
106 VariableServiceGetVariable,
110};
111
112EDKII_SMM_VAR_CHECK_PROTOCOL mSmmVarCheck = {
116};
117
123BOOLEAN
125 VOID
126 )
127{
128 return mAtRuntime;
129}
130
147EFI_LOCK *
150 IN EFI_TPL Priority
151 )
152{
153 return Lock;
154}
155
168VOID
171 )
172{
173}
174
187VOID
190 )
191{
192}
193
206 OUT VOID **FtwProtocol
207 )
208{
209 EFI_STATUS Status;
210
211 //
212 // Locate Smm Fault Tolerent Write protocol
213 //
214 Status = gMmst->MmLocateProtocol (
215 &gEfiSmmFaultTolerantWriteProtocolGuid,
216 NULL,
217 FtwProtocol
218 );
219 return Status;
220}
221
236 IN EFI_HANDLE FvBlockHandle,
238 )
239{
240 //
241 // To get the SMM FVB protocol interface on the handle
242 //
243 return gMmst->MmHandleProtocol (
244 FvBlockHandle,
245 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
246 (VOID **)FvBlock
247 );
248}
249
267 OUT UINTN *NumberHandles,
268 OUT EFI_HANDLE **Buffer
269 )
270{
271 EFI_STATUS Status;
272 UINTN BufferSize;
273
274 if ((NumberHandles == NULL) || (Buffer == NULL)) {
275 return EFI_INVALID_PARAMETER;
276 }
277
278 BufferSize = 0;
279 *NumberHandles = 0;
280 *Buffer = NULL;
281 Status = gMmst->MmLocateHandle (
283 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
284 NULL,
285 &BufferSize,
286 *Buffer
287 );
288 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
289 return EFI_NOT_FOUND;
290 }
291
292 *Buffer = AllocatePool (BufferSize);
293 if (*Buffer == NULL) {
294 return EFI_OUT_OF_RESOURCES;
295 }
296
297 Status = gMmst->MmLocateHandle (
299 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
300 NULL,
301 &BufferSize,
302 *Buffer
303 );
304
305 *NumberHandles = BufferSize / sizeof (EFI_HANDLE);
306 if (EFI_ERROR (Status)) {
307 *NumberHandles = 0;
308 FreePool (*Buffer);
309 *Buffer = NULL;
310 }
311
312 return Status;
313}
314
337 IN OUT VARIABLE_INFO_ENTRY *InfoEntry,
338 IN OUT UINTN *InfoSize
339 )
340{
341 VARIABLE_INFO_ENTRY *VariableInfo;
342 UINTN NameSize;
343 UINTN StatisticsInfoSize;
344 CHAR16 *InfoName;
345 UINTN InfoNameMaxSize;
346 EFI_GUID VendorGuid;
347
348 if (InfoEntry == NULL) {
349 return EFI_INVALID_PARAMETER;
350 }
351
352 VariableInfo = gVariableInfo;
353 if (VariableInfo == NULL) {
354 return EFI_UNSUPPORTED;
355 }
356
357 StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY);
358 if (*InfoSize < StatisticsInfoSize) {
359 *InfoSize = StatisticsInfoSize;
360 return EFI_BUFFER_TOO_SMALL;
361 }
362
363 InfoName = (CHAR16 *)(InfoEntry + 1);
364 InfoNameMaxSize = (*InfoSize - sizeof (VARIABLE_INFO_ENTRY));
365
366 CopyGuid (&VendorGuid, &InfoEntry->VendorGuid);
367
368 if (IsZeroGuid (&VendorGuid)) {
369 //
370 // Return the first variable info
371 //
372 NameSize = StrSize (VariableInfo->Name);
373 StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + NameSize;
374 if (*InfoSize < StatisticsInfoSize) {
375 *InfoSize = StatisticsInfoSize;
376 return EFI_BUFFER_TOO_SMALL;
377 }
378
379 CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY));
380 CopyMem (InfoName, VariableInfo->Name, NameSize);
381 *InfoSize = StatisticsInfoSize;
382 return EFI_SUCCESS;
383 }
384
385 //
386 // Get the next variable info
387 //
388 while (VariableInfo != NULL) {
389 if (CompareGuid (&VariableInfo->VendorGuid, &VendorGuid)) {
390 NameSize = StrSize (VariableInfo->Name);
391 if (NameSize <= InfoNameMaxSize) {
392 if (CompareMem (VariableInfo->Name, InfoName, NameSize) == 0) {
393 //
394 // Find the match one
395 //
396 VariableInfo = VariableInfo->Next;
397 break;
398 }
399 }
400 }
401
402 VariableInfo = VariableInfo->Next;
403 }
404
405 if (VariableInfo == NULL) {
406 *InfoSize = 0;
407 return EFI_SUCCESS;
408 }
409
410 //
411 // Output the new variable info
412 //
413 NameSize = StrSize (VariableInfo->Name);
414 StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + NameSize;
415 if (*InfoSize < StatisticsInfoSize) {
416 *InfoSize = StatisticsInfoSize;
417 return EFI_BUFFER_TOO_SMALL;
418 }
419
420 CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY));
421 CopyMem (InfoName, VariableInfo->Name, NameSize);
422 *InfoSize = StatisticsInfoSize;
423
424 return EFI_SUCCESS;
425}
426
454EFIAPI
456 IN EFI_HANDLE DispatchHandle,
457 IN CONST VOID *RegisterContext,
458 IN OUT VOID *CommBuffer,
459 IN OUT UINTN *CommBufferSize
460 )
461{
462 EFI_STATUS Status;
463 SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
472 VARIABLE_INFO_ENTRY *VariableInfo;
473 VARIABLE_RUNTIME_CACHE_CONTEXT *VariableCacheContext;
474 VARIABLE_STORE_HEADER *VariableCache;
475 UINTN InfoSize;
476 UINTN NameBufferSize;
477 UINTN CommBufferPayloadSize;
478 UINTN TempCommBufferSize;
479
480 //
481 // If input is invalid, stop processing this SMI
482 //
483 if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
484 return EFI_SUCCESS;
485 }
486
487 TempCommBufferSize = *CommBufferSize;
488
489 if (TempCommBufferSize < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) {
490 DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM communication buffer size invalid!\n"));
491 return EFI_SUCCESS;
492 }
493
494 CommBufferPayloadSize = TempCommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
495 if (CommBufferPayloadSize > mVariableBufferPayloadSize) {
496 DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM communication buffer payload size invalid!\n"));
497 return EFI_SUCCESS;
498 }
499
500 if (!VariableSmmIsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) {
501 DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM Primary Buffer (CommBuffer) is not valid!\n"));
502 return EFI_SUCCESS;
503 }
504
505 SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer;
506 switch (SmmVariableFunctionHeader->Function) {
507 case SMM_VARIABLE_FUNCTION_GET_VARIABLE:
508 if (CommBufferPayloadSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {
509 DEBUG ((DEBUG_ERROR, "GetVariable: SMM communication buffer size invalid!\n"));
510 return EFI_SUCCESS;
511 }
512
513 //
514 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
515 //
516 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
517 SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)mVariableBufferPayload;
518 if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||
519 ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize))
520 {
521 //
522 // Prevent InfoSize overflow happen
523 //
524 Status = EFI_ACCESS_DENIED;
525 goto EXIT;
526 }
527
529 + SmmVariableHeader->DataSize + SmmVariableHeader->NameSize;
530
531 //
532 // SMRAM range check already covered before
533 //
534 if (InfoSize > CommBufferPayloadSize) {
535 DEBUG ((DEBUG_ERROR, "GetVariable: Data size exceed communication buffer size limit!\n"));
536 Status = EFI_ACCESS_DENIED;
537 goto EXIT;
538 }
539
540 //
541 // The VariableSpeculationBarrier() call here is to ensure the previous
542 // range/content checks for the CommBuffer have been completed before the
543 // subsequent consumption of the CommBuffer content.
544 //
546 if ((SmmVariableHeader->NameSize < sizeof (CHAR16)) || (SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0')) {
547 //
548 // Make sure VariableName is A Null-terminated string.
549 //
550 Status = EFI_ACCESS_DENIED;
551 goto EXIT;
552 }
553
554 Status = VariableServiceGetVariable (
555 SmmVariableHeader->Name,
556 &SmmVariableHeader->Guid,
557 &SmmVariableHeader->Attributes,
558 &SmmVariableHeader->DataSize,
559 (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize
560 );
561 CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
562 break;
563
564 case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:
565 if (CommBufferPayloadSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
566 DEBUG ((DEBUG_ERROR, "GetNextVariableName: SMM communication buffer size invalid!\n"));
567 return EFI_SUCCESS;
568 }
569
570 //
571 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
572 //
573 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
574 GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)mVariableBufferPayload;
575 if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
576 //
577 // Prevent InfoSize overflow happen
578 //
579 Status = EFI_ACCESS_DENIED;
580 goto EXIT;
581 }
582
583 InfoSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + GetNextVariableName->NameSize;
584
585 //
586 // SMRAM range check already covered before
587 //
588 if (InfoSize > CommBufferPayloadSize) {
589 DEBUG ((DEBUG_ERROR, "GetNextVariableName: Data size exceed communication buffer size limit!\n"));
590 Status = EFI_ACCESS_DENIED;
591 goto EXIT;
592 }
593
594 NameBufferSize = CommBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name);
595 if ((NameBufferSize < sizeof (CHAR16)) || (GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0')) {
596 //
597 // Make sure input VariableName is A Null-terminated string.
598 //
599 Status = EFI_ACCESS_DENIED;
600 goto EXIT;
601 }
602
604 &GetNextVariableName->NameSize,
605 GetNextVariableName->Name,
606 &GetNextVariableName->Guid
607 );
608 CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
609 break;
610
611 case SMM_VARIABLE_FUNCTION_SET_VARIABLE:
612 if (CommBufferPayloadSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {
613 DEBUG ((DEBUG_ERROR, "SetVariable: SMM communication buffer size invalid!\n"));
614 return EFI_SUCCESS;
615 }
616
617 //
618 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
619 //
620 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
621 SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)mVariableBufferPayload;
622 if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) ||
623 ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize))
624 {
625 //
626 // Prevent InfoSize overflow happen
627 //
628 Status = EFI_ACCESS_DENIED;
629 goto EXIT;
630 }
631
633 + SmmVariableHeader->DataSize + SmmVariableHeader->NameSize;
634
635 //
636 // SMRAM range check already covered before
637 // Data buffer should not contain SMM range
638 //
639 if (InfoSize > CommBufferPayloadSize) {
640 DEBUG ((DEBUG_ERROR, "SetVariable: Data size exceed communication buffer size limit!\n"));
641 Status = EFI_ACCESS_DENIED;
642 goto EXIT;
643 }
644
645 //
646 // The VariableSpeculationBarrier() call here is to ensure the previous
647 // range/content checks for the CommBuffer have been completed before the
648 // subsequent consumption of the CommBuffer content.
649 //
651 if ((SmmVariableHeader->NameSize < sizeof (CHAR16)) || (SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0')) {
652 //
653 // Make sure VariableName is A Null-terminated string.
654 //
655 Status = EFI_ACCESS_DENIED;
656 goto EXIT;
657 }
658
660 SmmVariableHeader->Name,
661 &SmmVariableHeader->Guid,
662 SmmVariableHeader->Attributes,
663 SmmVariableHeader->DataSize,
664 (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize
665 );
666 break;
667
668 case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:
669 if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
670 DEBUG ((DEBUG_ERROR, "QueryVariableInfo: SMM communication buffer size invalid!\n"));
671 return EFI_SUCCESS;
672 }
673
674 QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *)SmmVariableFunctionHeader->Data;
675
677 QueryVariableInfo->Attributes,
678 &QueryVariableInfo->MaximumVariableStorageSize,
679 &QueryVariableInfo->RemainingVariableStorageSize,
680 &QueryVariableInfo->MaximumVariableSize
681 );
682 break;
683
684 case SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE:
685 if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE)) {
686 DEBUG ((DEBUG_ERROR, "GetPayloadSize: SMM communication buffer size invalid!\n"));
687 return EFI_SUCCESS;
688 }
689
690 GetPayloadSize = (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE *)SmmVariableFunctionHeader->Data;
691 GetPayloadSize->VariablePayloadSize = mVariableBufferPayloadSize;
692 Status = EFI_SUCCESS;
693 break;
694
695 case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
696 if (AtRuntime ()) {
697 Status = EFI_UNSUPPORTED;
698 break;
699 }
700
701 if (!mEndOfDxe) {
703 Status = LockVariablePolicy ();
704 ASSERT_EFI_ERROR (Status);
705 mEndOfDxe = TRUE;
707 //
708 // The initialization for variable quota.
709 //
711 }
712
713 ReclaimForOS ();
714 Status = EFI_SUCCESS;
715 break;
716
717 case SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE:
718 mAtRuntime = TRUE;
719 Status = EFI_SUCCESS;
720 break;
721
722 case SMM_VARIABLE_FUNCTION_GET_STATISTICS:
723 VariableInfo = (VARIABLE_INFO_ENTRY *)SmmVariableFunctionHeader->Data;
724 InfoSize = TempCommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
725
726 //
727 // Do not need to check SmmVariableFunctionHeader->Data in SMRAM here.
728 // It is covered by previous CommBuffer check
729 //
730
731 //
732 // Do not need to check CommBufferSize buffer as it should point to SMRAM
733 // that was used by SMM core to cache CommSize from SmmCommunication protocol.
734 //
735
736 Status = SmmVariableGetStatistics (VariableInfo, &InfoSize);
737 *CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
738 break;
739
740 case SMM_VARIABLE_FUNCTION_LOCK_VARIABLE:
741 if (mEndOfDxe) {
742 Status = EFI_ACCESS_DENIED;
743 } else {
744 VariableToLock = (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *)SmmVariableFunctionHeader->Data;
746 NULL,
747 VariableToLock->Name,
748 &VariableToLock->Guid
749 );
750 }
751
752 break;
753 case SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET:
754 if (mEndOfDxe) {
755 Status = EFI_ACCESS_DENIED;
756 } else {
757 CommVariableProperty = (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *)SmmVariableFunctionHeader->Data;
759 CommVariableProperty->Name,
760 &CommVariableProperty->Guid,
761 &CommVariableProperty->VariableProperty
762 );
763 }
764
765 break;
766 case SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET:
767 if (CommBufferPayloadSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
768 DEBUG ((DEBUG_ERROR, "VarCheckVariablePropertyGet: SMM communication buffer size invalid!\n"));
769 return EFI_SUCCESS;
770 }
771
772 //
773 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
774 //
775 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
776 CommVariableProperty = (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *)mVariableBufferPayload;
777 if ((UINTN)(~0) - CommVariableProperty->NameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
778 //
779 // Prevent InfoSize overflow happen
780 //
781 Status = EFI_ACCESS_DENIED;
782 goto EXIT;
783 }
784
785 InfoSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + CommVariableProperty->NameSize;
786
787 //
788 // SMRAM range check already covered before
789 //
790 if (InfoSize > CommBufferPayloadSize) {
791 DEBUG ((DEBUG_ERROR, "VarCheckVariablePropertyGet: Data size exceed communication buffer size limit!\n"));
792 Status = EFI_ACCESS_DENIED;
793 goto EXIT;
794 }
795
796 //
797 // The VariableSpeculationBarrier() call here is to ensure the previous
798 // range/content checks for the CommBuffer have been completed before the
799 // subsequent consumption of the CommBuffer content.
800 //
802 if ((CommVariableProperty->NameSize < sizeof (CHAR16)) || (CommVariableProperty->Name[CommVariableProperty->NameSize/sizeof (CHAR16) - 1] != L'\0')) {
803 //
804 // Make sure VariableName is A Null-terminated string.
805 //
806 Status = EFI_ACCESS_DENIED;
807 goto EXIT;
808 }
809
811 CommVariableProperty->Name,
812 &CommVariableProperty->Guid,
813 &CommVariableProperty->VariableProperty
814 );
815 CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
816 break;
817 case SMM_VARIABLE_FUNCTION_INIT_RUNTIME_VARIABLE_CACHE_CONTEXT:
818 if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_RUNTIME_VARIABLE_CACHE_CONTEXT)) {
819 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: SMM communication buffer size invalid!\n"));
820 Status = EFI_ACCESS_DENIED;
821 goto EXIT;
822 }
823
824 if (mEndOfDxe) {
825 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Cannot init context after end of DXE!\n"));
826 Status = EFI_ACCESS_DENIED;
827 goto EXIT;
828 }
829
830 //
831 // Copy the input communicate buffer payload to the pre-allocated SMM variable payload buffer.
832 //
833 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
834 RuntimeVariableCacheContext = (SMM_VARIABLE_COMMUNICATE_RUNTIME_VARIABLE_CACHE_CONTEXT *)mVariableBufferPayload;
835
836 //
837 // Verify required runtime cache buffers are provided.
838 //
839 if ((RuntimeVariableCacheContext->RuntimeVolatileCache == NULL) ||
840 (RuntimeVariableCacheContext->RuntimeNvCache == NULL) ||
841 (RuntimeVariableCacheContext->PendingUpdate == NULL) ||
842 (RuntimeVariableCacheContext->ReadLock == NULL) ||
843 (RuntimeVariableCacheContext->HobFlushComplete == NULL))
844 {
845 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Required runtime cache buffer is NULL!\n"));
846 Status = EFI_ACCESS_DENIED;
847 goto EXIT;
848 }
849
850 //
851 // Verify minimum size requirements for the runtime variable store buffers.
852 //
853 if (((RuntimeVariableCacheContext->RuntimeHobCache != NULL) &&
854 (RuntimeVariableCacheContext->RuntimeHobCache->Size < sizeof (VARIABLE_STORE_HEADER))) ||
855 (RuntimeVariableCacheContext->RuntimeVolatileCache->Size < sizeof (VARIABLE_STORE_HEADER)) ||
856 (RuntimeVariableCacheContext->RuntimeNvCache->Size < sizeof (VARIABLE_STORE_HEADER)))
857 {
858 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: A runtime cache buffer size is invalid!\n"));
859 Status = EFI_ACCESS_DENIED;
860 goto EXIT;
861 }
862
863 //
864 // Verify runtime buffers do not overlap with SMRAM ranges.
865 //
866 if ((RuntimeVariableCacheContext->RuntimeHobCache != NULL) &&
868 (UINTN)RuntimeVariableCacheContext->RuntimeHobCache,
869 (UINTN)RuntimeVariableCacheContext->RuntimeHobCache->Size
870 ))
871 {
872 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Runtime HOB cache buffer in SMRAM or overflow!\n"));
873 Status = EFI_ACCESS_DENIED;
874 goto EXIT;
875 }
876
878 (UINTN)RuntimeVariableCacheContext->RuntimeVolatileCache,
879 (UINTN)RuntimeVariableCacheContext->RuntimeVolatileCache->Size
880 ))
881 {
882 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Runtime volatile cache buffer in SMRAM or overflow!\n"));
883 Status = EFI_ACCESS_DENIED;
884 goto EXIT;
885 }
886
888 (UINTN)RuntimeVariableCacheContext->RuntimeNvCache,
889 (UINTN)RuntimeVariableCacheContext->RuntimeNvCache->Size
890 ))
891 {
892 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Runtime non-volatile cache buffer in SMRAM or overflow!\n"));
893 Status = EFI_ACCESS_DENIED;
894 goto EXIT;
895 }
896
898 (UINTN)RuntimeVariableCacheContext->PendingUpdate,
899 sizeof (*(RuntimeVariableCacheContext->PendingUpdate))
900 ))
901 {
902 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Runtime cache pending update buffer in SMRAM or overflow!\n"));
903 Status = EFI_ACCESS_DENIED;
904 goto EXIT;
905 }
906
908 (UINTN)RuntimeVariableCacheContext->ReadLock,
909 sizeof (*(RuntimeVariableCacheContext->ReadLock))
910 ))
911 {
912 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Runtime cache read lock buffer in SMRAM or overflow!\n"));
913 Status = EFI_ACCESS_DENIED;
914 goto EXIT;
915 }
916
918 (UINTN)RuntimeVariableCacheContext->HobFlushComplete,
919 sizeof (*(RuntimeVariableCacheContext->HobFlushComplete))
920 ))
921 {
922 DEBUG ((DEBUG_ERROR, "InitRuntimeVariableCacheContext: Runtime cache HOB flush complete buffer in SMRAM or overflow!\n"));
923 Status = EFI_ACCESS_DENIED;
924 goto EXIT;
925 }
926
927 VariableCacheContext = &mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext;
928 VariableCacheContext->VariableRuntimeHobCache.Store = RuntimeVariableCacheContext->RuntimeHobCache;
929 VariableCacheContext->VariableRuntimeVolatileCache.Store = RuntimeVariableCacheContext->RuntimeVolatileCache;
930 VariableCacheContext->VariableRuntimeNvCache.Store = RuntimeVariableCacheContext->RuntimeNvCache;
931 VariableCacheContext->PendingUpdate = RuntimeVariableCacheContext->PendingUpdate;
932 VariableCacheContext->ReadLock = RuntimeVariableCacheContext->ReadLock;
933 VariableCacheContext->HobFlushComplete = RuntimeVariableCacheContext->HobFlushComplete;
934
935 // Set up the intial pending request since the RT cache needs to be in sync with SMM cache
936 VariableCacheContext->VariableRuntimeHobCache.PendingUpdateOffset = 0;
937 VariableCacheContext->VariableRuntimeHobCache.PendingUpdateLength = 0;
938 if ((mVariableModuleGlobal->VariableGlobal.HobVariableBase > 0) &&
939 (VariableCacheContext->VariableRuntimeHobCache.Store != NULL))
940 {
941 VariableCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableModuleGlobal->VariableGlobal.HobVariableBase;
942 VariableCacheContext->VariableRuntimeHobCache.PendingUpdateLength = (UINT32)((UINTN)GetEndPointer (VariableCache) - (UINTN)VariableCache);
943 CopyGuid (&(VariableCacheContext->VariableRuntimeHobCache.Store->Signature), &(VariableCache->Signature));
944 }
945
946 VariableCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableModuleGlobal->VariableGlobal.VolatileVariableBase;
947 VariableCacheContext->VariableRuntimeVolatileCache.PendingUpdateOffset = 0;
948 VariableCacheContext->VariableRuntimeVolatileCache.PendingUpdateLength = (UINT32)((UINTN)GetEndPointer (VariableCache) - (UINTN)VariableCache);
949 CopyGuid (&(VariableCacheContext->VariableRuntimeVolatileCache.Store->Signature), &(VariableCache->Signature));
950
951 VariableCache = (VARIABLE_STORE_HEADER *)(UINTN)mNvVariableCache;
952 VariableCacheContext->VariableRuntimeNvCache.PendingUpdateOffset = 0;
953 VariableCacheContext->VariableRuntimeNvCache.PendingUpdateLength = (UINT32)((UINTN)GetEndPointer (VariableCache) - (UINTN)VariableCache);
954 CopyGuid (&(VariableCacheContext->VariableRuntimeNvCache.Store->Signature), &(VariableCache->Signature));
955
956 *(VariableCacheContext->PendingUpdate) = TRUE;
957 *(VariableCacheContext->ReadLock) = FALSE;
958 *(VariableCacheContext->HobFlushComplete) = FALSE;
959
960 Status = EFI_SUCCESS;
961 break;
962 case SMM_VARIABLE_FUNCTION_SYNC_RUNTIME_CACHE:
964 break;
965 case SMM_VARIABLE_FUNCTION_GET_RUNTIME_CACHE_INFO:
966 if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_GET_RUNTIME_CACHE_INFO)) {
967 DEBUG ((DEBUG_ERROR, "GetRuntimeCacheInfo: SMM communication buffer size invalid!\n"));
968 return EFI_SUCCESS;
969 }
970
971 GetRuntimeCacheInfo = (SMM_VARIABLE_COMMUNICATE_GET_RUNTIME_CACHE_INFO *)SmmVariableFunctionHeader->Data;
972
973 if (mVariableModuleGlobal->VariableGlobal.HobVariableBase > 0) {
974 VariableCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableModuleGlobal->VariableGlobal.HobVariableBase;
975 GetRuntimeCacheInfo->TotalHobStorageSize = VariableCache->Size;
976 } else {
977 GetRuntimeCacheInfo->TotalHobStorageSize = 0;
978 }
979
980 VariableCache = (VARIABLE_STORE_HEADER *)(UINTN)mVariableModuleGlobal->VariableGlobal.VolatileVariableBase;
981 GetRuntimeCacheInfo->TotalVolatileStorageSize = VariableCache->Size;
982 VariableCache = (VARIABLE_STORE_HEADER *)(UINTN)mNvVariableCache;
983 GetRuntimeCacheInfo->TotalNvStorageSize = (UINTN)VariableCache->Size;
984 GetRuntimeCacheInfo->AuthenticatedVariableUsage = mVariableModuleGlobal->VariableGlobal.AuthFormat;
985
986 Status = EFI_SUCCESS;
987 break;
988
989 default:
990 Status = EFI_UNSUPPORTED;
991 }
992
993EXIT:
994
995 SmmVariableFunctionHeader->ReturnStatus = Status;
996
997 return EFI_SUCCESS;
998}
999
1011EFIAPI
1013 IN CONST EFI_GUID *Protocol,
1014 IN VOID *Interface,
1015 IN EFI_HANDLE Handle
1016 )
1017{
1018 EFI_STATUS Status;
1019
1020 DEBUG ((DEBUG_INFO, "[Variable]SMM_END_OF_DXE is signaled\n"));
1022 Status = LockVariablePolicy ();
1023 ASSERT_EFI_ERROR (Status);
1024 mEndOfDxe = TRUE;
1026 //
1027 // The initialization for variable quota.
1028 //
1030 if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
1031 ReclaimForOS ();
1032 }
1033
1034 return EFI_SUCCESS;
1035}
1036
1041VOID
1043 VOID
1044 )
1045{
1046 EFI_STATUS Status;
1047
1049 if (EFI_ERROR (Status)) {
1050 DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
1051 }
1052
1053 //
1054 // Notify the variable wrapper driver the variable write service is ready
1055 //
1057}
1058
1074EFIAPI
1076 IN CONST EFI_GUID *Protocol,
1077 IN VOID *Interface,
1078 IN EFI_HANDLE Handle
1079 )
1080{
1081 EFI_STATUS Status;
1082 EFI_PHYSICAL_ADDRESS VariableStoreBase;
1085 EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
1086 UINTN FtwMaxBlockSize;
1087 UINT32 NvStorageVariableSize;
1088 UINT64 NvStorageVariableSize64;
1089
1090 if (mVariableModuleGlobal->FvbInstance != NULL) {
1091 return EFI_SUCCESS;
1092 }
1093
1094 //
1095 // Ensure SMM FTW protocol is installed.
1096 //
1097 Status = GetFtwProtocol ((VOID **)&FtwProtocol);
1098 if (EFI_ERROR (Status)) {
1099 return Status;
1100 }
1101
1102 Status = GetVariableFlashNvStorageInfo (&NvStorageVariableBase, &NvStorageVariableSize64);
1103 ASSERT_EFI_ERROR (Status);
1104
1105 Status = SafeUint64ToUint32 (NvStorageVariableSize64, &NvStorageVariableSize);
1106 // This driver currently assumes the size will be UINT32 so assert the value is safe for now.
1107 ASSERT_EFI_ERROR (Status);
1108
1109 ASSERT (NvStorageVariableBase != 0);
1110 VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;
1111
1112 Status = FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize);
1113 if (!EFI_ERROR (Status)) {
1114 ASSERT (NvStorageVariableSize <= FtwMaxBlockSize);
1115 }
1116
1117 //
1118 // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.
1119 //
1120 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;
1121
1122 //
1123 // Find the proper FVB protocol for variable.
1124 //
1125 Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);
1126 if (EFI_ERROR (Status)) {
1127 return EFI_NOT_FOUND;
1128 }
1129
1130 mVariableModuleGlobal->FvbInstance = FvbProtocol;
1131
1132 //
1133 // Initializes variable write service after FTW was ready.
1134 //
1136
1137 return EFI_SUCCESS;
1138}
1139
1150EFIAPI
1152 VOID
1153 )
1154{
1155 EFI_STATUS Status;
1156 EFI_HANDLE VariableHandle;
1157 VOID *SmmFtwRegistration;
1158 VOID *SmmEndOfDxeRegistration;
1159
1160 //
1161 // Variable initialize.
1162 //
1163 Status = VariableCommonInitialize ();
1164 ASSERT_EFI_ERROR (Status);
1165
1166 //
1167 // Install the Smm Variable Protocol on a new handle.
1168 //
1169 VariableHandle = NULL;
1170 Status = gMmst->MmInstallProtocolInterface (
1171 &VariableHandle,
1172 &gEfiSmmVariableProtocolGuid,
1174 &gSmmVariable
1175 );
1176 ASSERT_EFI_ERROR (Status);
1177
1178 Status = gMmst->MmInstallProtocolInterface (
1179 &VariableHandle,
1180 &gEdkiiSmmVarCheckProtocolGuid,
1182 &mSmmVarCheck
1183 );
1184 ASSERT_EFI_ERROR (Status);
1185
1186 mVariableBufferPayloadSize = GetMaxVariableSize () +
1188 GetVariableHeaderSize (mVariableModuleGlobal->VariableGlobal.AuthFormat);
1189
1190 Status = gMmst->MmAllocatePool (
1192 mVariableBufferPayloadSize,
1193 (VOID **)&mVariableBufferPayload
1194 );
1195 ASSERT_EFI_ERROR (Status);
1196
1200 VariableHandle = NULL;
1201 Status = gMmst->MmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);
1202 ASSERT_EFI_ERROR (Status);
1203
1204 //
1205 // Notify the variable wrapper driver the variable service is ready
1206 //
1208
1209 //
1210 // Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.
1211 //
1212 Status = gMmst->MmRegisterProtocolNotify (
1213 &gEfiMmEndOfDxeProtocolGuid,
1215 &SmmEndOfDxeRegistration
1216 );
1217 ASSERT_EFI_ERROR (Status);
1218
1219 if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {
1220 //
1221 // Register FtwNotificationEvent () notify function.
1222 //
1223 Status = gMmst->MmRegisterProtocolNotify (
1224 &gEfiSmmFaultTolerantWriteProtocolGuid,
1226 &SmmFtwRegistration
1227 );
1228 ASSERT_EFI_ERROR (Status);
1229
1231 } else {
1232 //
1233 // Emulated non-volatile variable mode does not depend on FVB and FTW.
1234 //
1236 }
1237
1238 return EFI_SUCCESS;
1239}
UINT64 UINTN
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
BOOLEAN VariableSmmIsPrimaryBufferValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
VOID MorLockInitAtEndOfDxe(VOID)
VOID VariableNotifySmmReady(VOID)
BOOLEAN VariableSmmIsNonPrimaryBufferValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
VOID VariableNotifySmmWriteReady(VOID)
VOID VariableSpeculationBarrier(VOID)
RETURN_STATUS EFIAPI SafeUint64ToUint32(IN UINT64 Operand, OUT UINT32 *Result)
Definition: SafeIntLib.c:2698
EFI_STATUS EFIAPI Lock(IN EFI_SMM_ACCESS2_PROTOCOL *This)
Definition: SmmAccessDxe.c:133
#define SMM_VARIABLE_COMMUNICATE_HEADER_SIZE
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ EfiRuntimeServicesData
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ ByProtocol
Definition: UefiSpec.h:1518
VARIABLE_HEADER * GetEndPointer(IN VARIABLE_STORE_HEADER *VarStoreHeader)
Definition: Variable.c:109
UINTN GetVariableHeaderSize(IN BOOLEAN AuthFlag)
Definition: Variable.c:149
EFI_FIRMWARE_VOLUME_HEADER * mNvFvHeaderCache
Definition: Variable.c:44
VARIABLE_INFO_ENTRY * gVariableInfo
Definition: Variable.c:49
UINTN GetMaxVariableSize(VOID)
Definition: Variable.c:3257
VOID InitializeVariableQuota(VOID)
Definition: Variable.c:488
EFI_STATUS VariableWriteServiceInitialize(VOID)
Definition: Variable.c:3415
VOID ReclaimForOS(VOID)
Definition: Variable.c:3202
EFI_STATUS VariableCommonInitialize(VOID)
Definition: Variable.c:3703
EFI_STATUS EFIAPI VariableServiceGetNextVariableName(IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid)
Definition: Variable.c:2502
VAR_CHECK_REQUEST_SOURCE mRequestSource
Definition: Variable.c:60
EFI_STATUS EFIAPI VariableServiceQueryVariableInfo(IN UINT32 Attributes, OUT UINT64 *MaximumVariableStorageSize, OUT UINT64 *RemainingVariableStorageSize, OUT UINT64 *MaximumVariableSize)
Definition: Variable.c:3120
EFI_STATUS GetFvbInfoByAddress(IN EFI_PHYSICAL_ADDRESS Address, OUT EFI_HANDLE *FvbHandle OPTIONAL, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvbProtocol OPTIONAL)
Definition: Variable.c:3811
EFI_STATUS EFIAPI VariableServiceSetVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
Definition: Variable.c:2612
EFI_STATUS EFIAPI VarCheckVariablePropertySet(IN CHAR16 *Name, IN EFI_GUID *Guid, IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty)
Definition: VarCheck.c:59
EFI_STATUS EFIAPI VarCheckRegisterSetVariableCheckHandler(IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler)
Definition: VarCheck.c:29
EFI_STATUS EFIAPI VarCheckVariablePropertyGet(IN CHAR16 *Name, IN EFI_GUID *Guid, OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty)
Definition: VarCheck.c:88
VOID ***EFIAPI VarCheckLibInitializeAtEndOfDxe(IN OUT UINTN *AddressPointerCount OPTIONAL)
Definition: VarCheckLib.c:304
EFI_STATUS EFIAPI GetVariableFlashNvStorageInfo(OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length)
EFI_STATUS EFIAPI VariableLockRequestToLock(IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid)
=== CODE UNDER TEST ===========================================================================
EFI_STATUS FlushPendingRuntimeVariableCacheUpdates(VOID)
EFI_STATUS EFIAPI SmmEndOfDxeCallback(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
Definition: VariableSmm.c:1012
VOID EFIAPI SecureBootHook(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid)
Definition: VariableSmm.c:52
EFI_STATUS GetFvbByHandle(IN EFI_HANDLE FvBlockHandle, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock)
Definition: VariableSmm.c:235
EFI_LOCK * InitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: VariableSmm.c:148
BOOLEAN AtRuntime(VOID)
Definition: VariableSmm.c:124
EFI_STATUS EFIAPI MmVariableServiceInitialize(VOID)
Definition: VariableSmm.c:1151
VARIABLE_STORE_HEADER * mNvVariableCache
Definition: Variable.c:39
EFI_STATUS EFIAPI SmmFtwNotificationEvent(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
Definition: VariableSmm.c:1075
EFI_STATUS EFIAPI SmmVariableHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *RegisterContext, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
Definition: VariableSmm.c:455
VOID ReleaseLockOnlyAtBootTime(IN EFI_LOCK *Lock)
Definition: VariableSmm.c:188
VOID AcquireLockOnlyAtBootTime(IN EFI_LOCK *Lock)
Definition: VariableSmm.c:169
VOID VariableWriteServiceInitializeSmm(VOID)
Definition: VariableSmm.c:1042
EFI_STATUS EFIAPI SmmVariableSetVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
Definition: VariableSmm.c:80
EFI_STATUS GetFtwProtocol(OUT VOID **FtwProtocol)
Definition: VariableSmm.c:205
EFI_STATUS GetFvbCountAndBuffer(OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
Definition: VariableSmm.c:266
EFI_STATUS SmmVariableGetStatistics(IN OUT VARIABLE_INFO_ENTRY *InfoEntry, IN OUT UINTN *InfoSize)
Definition: VariableSmm.c:336
EFI_STATUS GetRuntimeCacheInfo(OUT UINTN *TotalHobStorageSize, OUT UINTN *TotalNvStorageSize, OUT UINTN *TotalVolatileStorageSize, OUT BOOLEAN *AuthenticatedVariableUsage)
EFI_INSTALL_PROTOCOL_INTERFACE MmInstallProtocolInterface
Definition: PiMmCis.h:327
EFI_ALLOCATE_POOL MmAllocatePool
Definition: PiMmCis.h:274
VARIABLE_INFO_ENTRY * Next
Pointer to next entry.
CHAR16 * Name
Name of Variable.
EFI_GUID VendorGuid
Guid of Variable.
Definition: Base.h:213