X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FSec%2FSecMain.c;h=f7fec3d8c03b93d73042e480e4400be41f22ce32;hp=670ad8d763aab0dc3a5f8215ee57c96a3cf7c6dd;hb=89796c69d9fdaa9bd13d37b6b1687df5e0104ed5;hpb=a781f7099bc2584fd065f1947bedd49adfea0fa5 diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index 670ad8d763..f7fec3d8c0 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -1,7 +1,8 @@ /** @file Main SEC phase code. Transitions to PEI. - Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -28,6 +29,7 @@ #include #include #include +#include #include @@ -331,11 +333,13 @@ DecompressMemFvs ( UINT32 AuthenticationStatus; VOID *OutputBuffer; VOID *ScratchBuffer; - EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FvSection; + EFI_COMMON_SECTION_HEADER *FvSection; EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv; EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv; + UINT32 FvHeaderSize; + UINT32 FvSectionSize; - FvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL; + FvSection = (EFI_COMMON_SECTION_HEADER*) NULL; Status = FindFfsFileAndSection ( *Fv, @@ -361,6 +365,14 @@ DecompressMemFvs ( OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB); ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB); + + DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x " + "PcdOvmfDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer, + OutputBufferSize, ScratchBuffer, ScratchBufferSize, + PcdGet32 (PcdOvmfDecompressionScratchEnd))); + ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize == + PcdGet32 (PcdOvmfDecompressionScratchEnd)); + Status = ExtractGuidedSectionDecode ( Section, &OutputBuffer, @@ -377,7 +389,7 @@ DecompressMemFvs ( OutputBufferSize, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, 0, - (EFI_COMMON_SECTION_HEADER**) &FvSection + &FvSection ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n")); @@ -402,7 +414,7 @@ DecompressMemFvs ( OutputBufferSize, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, 1, - (EFI_COMMON_SECTION_HEADER**) &FvSection + &FvSection ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n")); @@ -410,11 +422,19 @@ DecompressMemFvs ( } ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE); - ASSERT (SECTION_SIZE (FvSection) == - (PcdGet32 (PcdOvmfDxeMemFvSize) + sizeof (*FvSection))); + + if (IS_SECTION2 (FvSection)) { + FvSectionSize = SECTION2_SIZE (FvSection); + FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2); + } else { + FvSectionSize = SECTION_SIZE (FvSection); + FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER); + } + + ASSERT (FvSectionSize == (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderSize)); DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase); - CopyMem (DxeMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfDxeMemFvSize)); + CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdOvmfDxeMemFvSize)); if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) { DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv)); @@ -530,13 +550,25 @@ FindPeiCoreImageBase ( OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase ) { + BOOLEAN S3Resume; + *PeiCoreImageBase = 0; - if (IsS3Resume ()) { + S3Resume = IsS3Resume (); + if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) { + // + // A malicious runtime OS may have injected something into our previously + // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required. + // DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n")); GetS3ResumePeiFv (BootFv); } else { - DEBUG ((EFI_D_VERBOSE, "SEC: Normal boot\n")); + // + // We're either not resuming, or resuming "securely" -- we'll decompress + // both PEI FV and DXE FV from pristine flash. + // + DEBUG ((EFI_D_VERBOSE, "SEC: %a\n", + S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot")); FindMainFv (BootFv); DecompressMemFvs (BootFv); @@ -637,7 +669,7 @@ FindImageBase ( /* Find and return Pei Core entry point. - It also find SEC and PEI Core file debug inforamtion. It will report them if + It also find SEC and PEI Core file debug information. It will report them if remote debug is enabled. **/ @@ -697,6 +729,19 @@ SecCoreStartupWithStack ( SEC_IDT_TABLE IdtTableInStack; IA32_DESCRIPTOR IdtDescriptor; UINT32 Index; + volatile UINT8 *Table; + + // + // To ensure SMM can't be compromised on S3 resume, we must force re-init of + // the BaseExtractGuidedSectionLib. Since this is before library contructors + // are called, we must use a loop rather than SetMem. + // + Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress); + for (Index = 0; + Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize); + ++Index) { + Table[Index] = 0; + } ProcessLibraryConstructorList (NULL, NULL); @@ -767,6 +812,14 @@ SecCoreStartupWithStack ( // IoWrite8 (0x21, 0xff); IoWrite8 (0xA1, 0xff); + + // + // Initialize Local APIC Timer hardware and disable Local APIC Timer + // interrupts before initializing the Debug Agent and the debug timer is + // enabled. + // + InitializeApicTimer (0, MAX_UINT32, TRUE, 5); + DisableApicTimerInterrupt (); // // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. @@ -836,10 +889,10 @@ TemporaryRamMigration ( BASE_LIBRARY_JUMP_BUFFER JumpBuffer; DEBUG ((EFI_D_INFO, - "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", - (UINTN) TemporaryMemoryBase, - (UINTN) PermanentMemoryBase, - CopySize + "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n", + TemporaryMemoryBase, + PermanentMemoryBase, + (UINT64)CopySize )); OldHeap = (VOID*)(UINTN)TemporaryMemoryBase; @@ -878,9 +931,11 @@ TemporaryRamMigration ( if (SetJump (&JumpBuffer) == 0) { #if defined (MDE_CPU_IA32) JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset; + JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset; #endif #if defined (MDE_CPU_X64) JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset; + JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset; #endif LongJump (&JumpBuffer, (UINTN)-1); }