X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FPiSmmCpuDxeSmm%2FPiSmmCpuDxeSmm.c;h=19979d5418e85dabac919c3268136b4de975b70d;hb=31fb333431da1dfdd49ed4e12a7866e467a17030;hp=d06148263c8e565a2081f044a0234ef6df1873b2;hpb=8491e302e1450db96822838a83c283962c6a35f7;p=mirror_edk2.git
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
old mode 100755
new mode 100644
index d06148263c..19979d5418
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -1,7 +1,7 @@
/** @file
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
-Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
This program and the accompanying materials
@@ -76,6 +76,15 @@ EFI_SMM_CPU_PROTOCOL mSmmCpu = {
SmmWriteSaveState
};
+///
+/// SMM Memory Attribute Protocol instance
+///
+EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = {
+ EdkiiSmmGetMemoryAttributes,
+ EdkiiSmmSetMemoryAttributes,
+ EdkiiSmmClearMemoryAttributes
+};
+
EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];
//
@@ -108,6 +117,20 @@ UINT64 mAddressEncMask = 0;
//
SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
+//
+// Saved SMM ranges information
+//
+EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
+UINTN mSmmCpuSmramRangeCount;
+
+UINT8 mPhysicalAddressBits;
+
+//
+// Control register contents saved for SMM S3 resume state initialization.
+//
+UINT32 mSmmCr0;
+UINT32 mSmmCr4;
+
/**
Initialize IDT to setup exception handlers for SMM.
@@ -167,48 +190,17 @@ DumpModuleInfoByIp (
)
{
UINTN Pe32Data;
- EFI_IMAGE_DOS_HEADER *DosHdr;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
VOID *PdbPointer;
- UINT64 DumpIpAddress;
//
// Find Image Base
//
- Pe32Data = CallerIpAddress & ~(SIZE_4KB - 1);
- while (Pe32Data != 0) {
- DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
- //
- // DOS image header is present, so read the PE header after the DOS image header.
- //
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
- //
- // Make sure PE header address does not overflow and is less than the initial address.
- //
- if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < CallerIpAddress)) {
- if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
- //
- // It's PE image.
- //
- break;
- }
- }
- }
-
- //
- // Not found the image base, check the previous aligned address
- //
- Pe32Data -= SIZE_4KB;
- }
-
- DumpIpAddress = CallerIpAddress;
- DEBUG ((EFI_D_ERROR, "It is invoked from the instruction before IP(0x%lx)", DumpIpAddress));
-
+ Pe32Data = PeCoffSearchImageBase (CallerIpAddress);
if (Pe32Data != 0) {
+ DEBUG ((DEBUG_ERROR, "It is invoked from the instruction before IP(0x%p)", (VOID *) CallerIpAddress));
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
if (PdbPointer != NULL) {
- DEBUG ((EFI_D_ERROR, " in module (%a)", PdbPointer));
+ DEBUG ((DEBUG_ERROR, " in module (%a)\n", PdbPointer));
}
}
}
@@ -245,6 +237,11 @@ SmmReadSaveState (
if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) {
return EFI_INVALID_PARAMETER;
}
+ //
+ // The AsmLfence() call here is to ensure the above check for the CpuIndex
+ // has been completed before the execution of subsequent codes.
+ //
+ AsmLfence ();
//
// Check for special EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID
@@ -419,9 +416,11 @@ SmmRelocateBases (
//
// Patch ASM code template with current CR0, CR3, and CR4 values
//
- gSmmCr0 = (UINT32)AsmReadCr0 ();
- gSmmCr3 = (UINT32)AsmReadCr3 ();
- gSmmCr4 = (UINT32)AsmReadCr4 ();
+ mSmmCr0 = (UINT32)AsmReadCr0 ();
+ PatchInstructionX86 (gPatchSmmCr0, mSmmCr0, 4);
+ PatchInstructionX86 (gPatchSmmCr3, AsmReadCr3 (), 4);
+ mSmmCr4 = (UINT32)AsmReadCr4 ();
+ PatchInstructionX86 (gPatchSmmCr4, mSmmCr4, 4);
//
// Patch GDTR for SMM base relocation
@@ -556,6 +555,12 @@ PiCpuSmmEntry (
UINTN ModelId;
UINT32 Cr3;
+ //
+ // Initialize address fixup
+ //
+ PiSmmCpuSmmInitFixupAddress ();
+ PiSmmCpuSmiEntryFixupAddress ();
+
//
// Initialize Debug Agent to support source level debug in SMM code
//
@@ -569,13 +574,6 @@ PiCpuSmmEntry (
EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT
);
- //
- // Fix segment address of the long-mode-switch jump
- //
- if (sizeof (UINTN) == sizeof (UINT64)) {
- gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT;
- }
-
//
// Find out SMRR Base and SMRR Size
//
@@ -855,7 +853,11 @@ PiCpuSmmEntry (
//
// Set SMI stack for SMM base relocation
//
- gSmmInitStack = (UINTN) (Stacks + mSmmStackSize - sizeof (UINTN));
+ PatchInstructionX86 (
+ gPatchSmmInitStack,
+ (UINTN) (Stacks + mSmmStackSize - sizeof (UINTN)),
+ sizeof (UINTN)
+ );
//
// Initialize IDT
@@ -916,6 +918,17 @@ PiCpuSmmEntry (
);
ASSERT_EFI_ERROR (Status);
+ //
+ // Install the SMM Memory Attribute Protocol into SMM protocol database
+ //
+ Status = gSmst->SmmInstallProtocolInterface (
+ &mSmmCpuHandle,
+ &gEdkiiSmmMemoryAttributeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmMemoryAttribute
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Expose address of CPU Hot Plug Data structure if CPU hot plug is supported.
//
@@ -971,8 +984,6 @@ FindSmramInfo (
UINTN Size;
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
EFI_SMRAM_DESCRIPTOR *CurrentSmramRange;
- EFI_SMRAM_DESCRIPTOR *SmramRanges;
- UINTN SmramRangeCount;
UINTN Index;
UINT64 MaxSize;
BOOLEAN Found;
@@ -990,31 +1001,31 @@ FindSmramInfo (
Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
- SmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
- ASSERT (SmramRanges != NULL);
+ mSmmCpuSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
+ ASSERT (mSmmCpuSmramRanges != NULL);
- Status = SmmAccess->GetCapabilities (SmmAccess, &Size, SmramRanges);
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmCpuSmramRanges);
ASSERT_EFI_ERROR (Status);
- SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+ mSmmCpuSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
//
// Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size
//
CurrentSmramRange = NULL;
- for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < SmramRangeCount; Index++) {
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < mSmmCpuSmramRangeCount; Index++) {
//
// Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
//
- if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ if ((mSmmCpuSmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
continue;
}
- if (SmramRanges[Index].CpuStart >= BASE_1MB) {
- if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {
- if (SmramRanges[Index].PhysicalSize >= MaxSize) {
- MaxSize = SmramRanges[Index].PhysicalSize;
- CurrentSmramRange = &SmramRanges[Index];
+ if (mSmmCpuSmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) <= SMRR_MAX_ADDRESS) {
+ if (mSmmCpuSmramRanges[Index].PhysicalSize >= MaxSize) {
+ MaxSize = mSmmCpuSmramRanges[Index].PhysicalSize;
+ CurrentSmramRange = &mSmmCpuSmramRanges[Index];
}
}
}
@@ -1027,19 +1038,19 @@ FindSmramInfo (
do {
Found = FALSE;
- for (Index = 0; Index < SmramRangeCount; Index++) {
- if (SmramRanges[Index].CpuStart < *SmrrBase && *SmrrBase == (SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize)) {
- *SmrrBase = (UINT32)SmramRanges[Index].CpuStart;
- *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if (mSmmCpuSmramRanges[Index].CpuStart < *SmrrBase &&
+ *SmrrBase == (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize)) {
+ *SmrrBase = (UINT32)mSmmCpuSmramRanges[Index].CpuStart;
+ *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
Found = TRUE;
- } else if ((*SmrrBase + *SmrrSize) == SmramRanges[Index].CpuStart && SmramRanges[Index].PhysicalSize > 0) {
- *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
+ } else if ((*SmrrBase + *SmrrSize) == mSmmCpuSmramRanges[Index].CpuStart && mSmmCpuSmramRanges[Index].PhysicalSize > 0) {
+ *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
Found = TRUE;
}
}
} while (Found);
- FreePool (SmramRanges);
DEBUG ((EFI_D_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize));
}
@@ -1144,7 +1155,12 @@ ConfigSmmCodeAccessCheck (
//
for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
-
+ if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) {
+ //
+ // If this processor does not exist
+ //
+ continue;
+ }
//
// Acquire Config SMM Code Access Check spin lock. The AP will release the
// spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().