Skip to content

Commit

Permalink
MdeModulePkg/Variable: RT UEFI Variable Cache Support
Browse files Browse the repository at this point in the history
This change reduces SMIs for GetVariable () by maintaining a
UEFI variable cache in Runtime DXE in addition to the pre-
existing cache in SMRAM. When the Runtime Service GetVariable()
is invoked a Runtime DXE cache is used instead of triggering an
SMI to VariableSmm. This can improve overall system performance
by servicing variable read requests without rendezvousing all
cores into SMM.

The following points should be kept in mind:

1. All of the non-volatile storage contents are loaded into the
cache upon driver load. This one time load operation from storage
is preferred as opposed to building the cache on demand. An on-
demand cache would require a fallback SMI to load data into the
cache as variables are requested.

2. All SetVariable () requests will trigger an SMI. This occurs
regardless of whether the variable is volatile or non-volatile.

3. Both volatile and non-volatile variables are cached in a runtime
buffer. To reflect the design currently in place in the EDK II
driver, they are cached in separate buffers.

4. The cache in Runtime DXE and SMM are intended to be exact copies
of one another. All SMM variable accesses only return data from the
SMM cache. The runtime caches are only updated after the variable I/O
operation is successful in SMM. The runtime caches are only updated
from SMM.

5. Synchronization mechanisms are in place to ensure the runtime cache
content integrity with the SMM cache. These may result in updates to
runtime cache that are the same in content but different in offset and
size from updates to the SMM cache.

This code is currently in an experimental state and not ready for production
scenarios.

Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
  • Loading branch information
makubacki committed Aug 31, 2019
1 parent 30b4abc commit d812d43
Show file tree
Hide file tree
Showing 19 changed files with 2,083 additions and 1,072 deletions.
58 changes: 37 additions & 21 deletions MdeModulePkg/Include/Guid/SmmVariableCommon.h
@@ -1,14 +1,15 @@
/** @file
The file defined some common structures used for communicating between SMM variable module and SMM variable wrapper module.
Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#ifndef _SMM_VARIABLE_COMMON_H_
#define _SMM_VARIABLE_COMMON_H_

#include <Guid/VariableFormat.h>
#include <Protocol/VarCheck.h>

#define EFI_SMM_VARIABLE_WRITE_GUID \
Expand All @@ -30,42 +31,44 @@ typedef struct {
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE.
//
#define SMM_VARIABLE_FUNCTION_GET_VARIABLE 1
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME.
//
#define SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME 2
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE.
//
#define SMM_VARIABLE_FUNCTION_SET_VARIABLE 3
#define SMM_VARIABLE_FUNCTION_SET_VARIABLE 1
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO.
//
#define SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO 4
#define SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO 2
//
// It is a notify event, no extra payload for this function.
//
#define SMM_VARIABLE_FUNCTION_READY_TO_BOOT 5
#define SMM_VARIABLE_FUNCTION_READY_TO_BOOT 3
//
// It is a notify event, no extra payload for this function.
//
#define SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE 6
#define SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE 4
//
// The payload for this function is VARIABLE_INFO_ENTRY. The GUID in EFI_SMM_COMMUNICATE_HEADER
// is gEfiSmmVariableProtocolGuid.
//
#define SMM_VARIABLE_FUNCTION_GET_STATISTICS 7
#define SMM_VARIABLE_FUNCTION_GET_STATISTICS 5
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE
//
#define SMM_VARIABLE_FUNCTION_LOCK_VARIABLE 8
#define SMM_VARIABLE_FUNCTION_LOCK_VARIABLE 6

#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET 9
#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET 7

#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET 10
#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET 8

#define SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE 11
#define SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE 9
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_RUNTIME_VARIABLE_CACHE_CONTEXT
//
#define SMM_VARIABLE_FUNCTION_INIT_RUNTIME_VARIABLE_CACHE_CONTEXT 10

#define SMM_VARIABLE_FUNCTION_SYNC_RUNTIME_CACHE 11
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_GET_TOTAL_NV_STORAGE_SIZE
//
#define SMM_VARIABLE_FUNCTION_GET_RUNTIME_CACHE_INFO 12

///
/// Size of SMM communicate header, without including the payload.
Expand Down Expand Up @@ -95,7 +98,7 @@ typedef struct {
EFI_GUID Guid;
UINTN NameSize; // Return name buffer size
CHAR16 Name[1];
} SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME;
} SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE;

///
/// This structure is used to communicate with SMI handler by QueryVariableInfo.
Expand All @@ -107,8 +110,6 @@ typedef struct {
UINT32 Attributes;
} SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO;

typedef SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE;

typedef struct {
EFI_GUID Guid;
UINTN NameSize;
Expand All @@ -120,4 +121,19 @@ typedef struct {
UINTN VariablePayloadSize;
} SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE;

typedef struct {
BOOLEAN *ReadLock;
BOOLEAN *PendingUpdate;
VARIABLE_STORE_HEADER *RuntimeHobCache;
VARIABLE_STORE_HEADER *RuntimeNvCache;
VARIABLE_STORE_HEADER *RuntimeVolatileCache;
} SMM_VARIABLE_COMMUNICATE_RUNTIME_VARIABLE_CACHE_CONTEXT;

typedef struct {
UINTN TotalHobStorageSize;
UINTN TotalNvStorageSize;
UINTN TotalVolatileStorageSize;
BOOLEAN AuthenticatedVariableUsage;
} SMM_VARIABLE_COMMUNICATE_GET_RUNTIME_CACHE_INFO;

#endif // _SMM_VARIABLE_COMMON_H_

1 comment on commit d812d43

@JayanthRaghuram
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use: EDKII_PI_SMM_COMMUNICATION_REGION_TABLE from system configuration table, for allocating communication buffer.
This table to declare the generic SMM communication buffer location.
If this table is present, it means the SMM communication buffer is restricted to
EfiReservedMemoryType, EfiACPIMemoryNVS, or EfiRuntimeServicesData.

Please sign in to comment.