summaryrefslogtreecommitdiff
path: root/OvmfPkg/CpuHotplugSmm
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/CpuHotplugSmm')
-rw-r--r--OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf4
-rw-r--r--OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm26
-rw-r--r--OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h8
-rw-r--r--OvmfPkg/CpuHotplugSmm/Smbase.c24
4 files changed, 58 insertions, 4 deletions
diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf b/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
index ebcc7e2..0996968 100644
--- a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
+++ b/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
@@ -42,6 +42,7 @@
BaseMemoryLib
CpuLib
DebugLib
+ HobLib
LocalApicLib
MmServicesTableLib
PcdLib
@@ -53,6 +54,9 @@
gEfiMmCpuIoProtocolGuid ## CONSUMES
gEfiSmmCpuServiceProtocolGuid ## CONSUMES
+[Guids]
+ gUefiOvmfPkgPlatformInfoGuid ## CONSUMES
+
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## CONSUMES
gUefiOvmfPkgTokenSpaceGuid.PcdCpuHotEjectDataAddress ## CONSUMES
diff --git a/OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm b/OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm
index 5399b5f..b38f94c 100644
--- a/OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm
+++ b/OvmfPkg/CpuHotplugSmm/FirstSmiHandler.nasm
@@ -41,9 +41,12 @@ SMM_DEFAULT_SMBASE: equ 0x3_0000
; Field offsets in FIRST_SMI_HANDLER_CONTEXT, which resides at
; SMM_DEFAULT_SMBASE.
;
-ApicIdGate: equ 0 ; UINT64
-NewSmbase: equ 8 ; UINT32
-AboutToLeaveSmm: equ 12 ; UINT8
+ApicIdGate: equ 0 ; UINT64
+NewSmbase: equ 8 ; UINT32
+FeatureControlHighValue: equ 12 ; UINT32
+FeatureControlLowValue: equ 16 ; UINT32
+FeatureControl: equ 20 ; UINT8
+AboutToLeaveSmm: equ 21 ; UINT8
;
; SMRAM Save State Map field offsets, per the AMD (not Intel) layout that QEMU
@@ -60,6 +63,11 @@ CPUID_SIGNATURE: equ 0x00
CPUID_EXTENDED_TOPOLOGY: equ 0x0B
CPUID_VERSION_INFO: equ 0x01
+;
+; MSR constants, from "MdePkg/Include/Register/Intel/ArchitecturalMsr.h".
+;
+MSR_IA32_FEATURE_CONTROL: equ 0x0000003A
+
GLOBAL ASM_PFX (mFirstSmiHandler) ; UINT8[]
GLOBAL ASM_PFX (mFirstSmiHandlerSize) ; UINT16
@@ -141,6 +149,18 @@ UpdateSmbase:
; Save it to the SMBASE field whose address we calculated in EBX.
;
mov dword [ds : dword ebx], eax
+
+ ;
+ ; Set MSR_IA32_FEATURE_CONTROL if requested.
+ ;
+ cmp byte [ds : dword (SMM_DEFAULT_SMBASE + FeatureControl)], 0
+ je NoFeatureControl
+ mov ecx, MSR_IA32_FEATURE_CONTROL
+ mov edx, dword [ds : dword (SMM_DEFAULT_SMBASE + FeatureControlHighValue)]
+ mov eax, dword [ds : dword (SMM_DEFAULT_SMBASE + FeatureControlLowValue)]
+ wrmsr
+
+NoFeatureControl:
;
; Set AboutToLeaveSmm.
;
diff --git a/OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h b/OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h
index 6039532..0c6deed 100644
--- a/OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h
+++ b/OvmfPkg/CpuHotplugSmm/FirstSmiHandlerContext.h
@@ -36,6 +36,14 @@ typedef struct {
//
UINT32 NewSmbase;
//
+ // The High:Low value for the hot-added CPU to store in
+ // MSR_IA32_FEATURE_CONTROL, assuming MSR_IA32_FEATURE_CONTROL setting is
+ // enabled (i.e., if "FeatureControl" is nonzero).
+ //
+ UINT32 FeatureControlHighValue;
+ UINT32 FeatureControlLowValue;
+ UINT8 FeatureControl;
+ //
// The hot-added CPU sets this field to 1 right before executing the RSM
// instruction. This tells the SMM Monarch to proceed to polling the last
// byte of the normal RAM reserved page (Post-SMM Pen).
diff --git a/OvmfPkg/CpuHotplugSmm/Smbase.c b/OvmfPkg/CpuHotplugSmm/Smbase.c
index dc6f4f4..433633d 100644
--- a/OvmfPkg/CpuHotplugSmm/Smbase.c
+++ b/OvmfPkg/CpuHotplugSmm/Smbase.c
@@ -10,7 +10,9 @@
#include <Library/BaseLib.h> // CpuPause()
#include <Library/BaseMemoryLib.h> // CopyMem()
#include <Library/DebugLib.h> // DEBUG()
+#include <Library/HobLib.h> // GetFirstGuidHob()
#include <Library/LocalApicLib.h> // SendInitSipiSipi()
+#include <Library/PlatformInitLib.h> // EFI_HOB_PLATFORM_INFO
#include <Library/SynchronizationLib.h> // InterlockedCompareExchange64()
#include <Register/Intel/SmramSaveStateMap.h> // SMM_DEFAULT_SMBASE
@@ -132,7 +134,10 @@ SmbaseReleasePostSmmPen (
Note that this effects an "SMRAM to SMRAM" copy.
- Additionally, shut the APIC ID gate in FIRST_SMI_HANDLER_CONTEXT.
+ Additionally, shut the APIC ID gate in FIRST_SMI_HANDLER_CONTEXT, and prepare
+ for configuring MSR_IA32_FEATURE_CONTROL. (The latter depends on a GUID HOB,
+ which does not live in SMRAM; however, if we can't trust the HOB list at this
+ stage, we're doomed anyway.)
This function may only be called from the entry point function of the driver,
and only after PcdQ35SmramAtDefaultSmbase has been determined to be TRUE.
@@ -143,6 +148,7 @@ SmbaseInstallFirstSmiHandler (
)
{
FIRST_SMI_HANDLER_CONTEXT *Context;
+ EFI_HOB_GUID_TYPE *GuidHob;
CopyMem (
(VOID *)(UINTN)(SMM_DEFAULT_SMBASE + SMM_HANDLER_OFFSET),
@@ -152,6 +158,22 @@ SmbaseInstallFirstSmiHandler (
Context = (VOID *)(UINTN)SMM_DEFAULT_SMBASE;
Context->ApicIdGate = MAX_UINT64;
+
+ Context->FeatureControl = 0;
+ GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
+ if (GuidHob != NULL) {
+ EFI_HOB_PLATFORM_INFO *Info;
+
+ Info = GET_GUID_HOB_DATA (GuidHob);
+ if (Info->FeatureControl) {
+ Context->FeatureControlHighValue = (UINT32)RShiftU64 (
+ Info->FeatureControlValue,
+ 32
+ );
+ Context->FeatureControlLowValue = (UINT32)Info->FeatureControlValue;
+ Context->FeatureControl = 1;
+ }
+ }
}
/**