Commit Graph

20 Commits

Author SHA1 Message Date
Laszlo Ersek ad43bc6b2e OvmfPkg: PlatformPei: protect SEC's GUIDed section handler table thru S3
OVMF's SecMain is unique in the sense that it links against the following
two libraries *in combination*:

- IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/
                                               LzmaCustomDecompressLib.inf
- MdePkg/Library/BaseExtractGuidedSectionLib/
                                           BaseExtractGuidedSectionLib.inf

The ExtractGuidedSectionLib library class allows decompressor modules to
register themselves (keyed by GUID) with it, and it allows clients to
decompress file sections with a registered decompressor module that
matches the section's GUID.

BaseExtractGuidedSectionLib is a library instance (of type BASE) for this
library class. It has no constructor function.

LzmaCustomDecompressLib is a compatible decompressor module (of type
BASE). Its section type GUID is

  gLzmaCustomDecompressGuid == EE4E5898-3914-4259-9D6E-DC7BD79403CF

When OVMF's SecMain module starts, the LzmaCustomDecompressLib constructor
function is executed, which registers its LZMA decompressor with the above
GUID, by calling into BaseExtractGuidedSectionLib:

  LzmaDecompressLibConstructor() [GuidedSectionExtraction.c]
    ExtractGuidedSectionRegisterHandlers() [BaseExtractGuidedSectionLib.c]
      GetExtractGuidedSectionHandlerInfo()
        PcdGet64 (PcdGuidedExtractHandlerTableAddress) -- NOTE THIS

Later, during a normal (non-S3) boot, SecMain utilizes this decompressor
to get information about, and to decompress, sections of the OVMF firmware
image:

  SecCoreStartupWithStack() [OvmfPkg/Sec/SecMain.c]
    SecStartupPhase2()
      FindAndReportEntryPoints()
        FindPeiCoreImageBase()
          DecompressMemFvs()
            ExtractGuidedSectionGetInfo() [BaseExtractGuidedSectionLib.c]
            ExtractGuidedSectionDecode() [BaseExtractGuidedSectionLib.c]

Notably, only the extraction depends on full-config-boot; the registration
of LzmaCustomDecompressLib occurs unconditionally in the SecMain EFI
binary, triggered by the library constructor function.

This is where the bug happens. BaseExtractGuidedSectionLib maintains the
table of GUIDed decompressors (section handlers) at a fixed memory
location; selected by PcdGuidedExtractHandlerTableAddress (declared in
MdePkg.dec). The default value of this PCD is 0x1000000 (16 MB).

This causes SecMain to corrupt guest OS memory during S3, leading to
random crashes. Compare the following two memory dumps, the first taken
right before suspending, the second taken right after resuming a RHEL-7
guest:

crash> rd -8 -p 1000000 0x50
1000000: c0 00 08 00 02 00 00 00 00 00 00 00 00 00 00 00  ................
1000010: d0 33 0c 00 00 c9 ff ff c0 10 00 01 00 88 ff ff  .3..............
1000020: 0a 6d 57 32 0f 00 00 00 38 00 00 01 00 88 ff ff  .mW2....8.......
1000030: 00 00 00 00 00 00 00 00 73 69 67 6e 61 6c 6d 6f  ........signalmo
1000040: 64 75 6c 65 2e 73 6f 00 00 00 00 00 00 00 00 00  dule.so.........

vs.

crash> rd -8 -p 1000000 0x50
1000000: 45 47 53 49 01 00 00 00 20 00 00 01 00 00 00 00  EGSI.... .......
1000010: 20 01 00 01 00 00 00 00 a0 01 00 01 00 00 00 00   ...............
1000020: 98 58 4e ee 14 39 59 42 9d 6e dc 7b d7 94 03 cf  .XN..9YB.n.{....
1000030: 00 00 00 00 00 00 00 00 73 69 67 6e 61 6c 6d 6f  ........signalmo
1000040: 64 75 6c 65 2e 73 6f 00 00 00 00 00 00 00 00 00  dule.so.........

The "EGSI" signature corresponds to EXTRACT_HANDLER_INFO_SIGNATURE
declared in
MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.c.

Additionally, the gLzmaCustomDecompressGuid (quoted above) is visible at
guest-phys offset 0x1000020.

Fix the problem as follows:
- Carve out 4KB from the 36KB gap that we currently have between

  PcdOvmfLockBoxStorageBase + PcdOvmfLockBoxStorageSize == 8220 KB
  and
  PcdOvmfSecPeiTempRamBase                              == 8256 KB.

- Point PcdGuidedExtractHandlerTableAddress to 8220 KB (0x00807000).

- Cover the area with an EfiACPIMemoryNVS type memalloc HOB, if S3 is
  supported and we're not currently resuming.

The 4KB size that we pick is an upper estimate for
BaseExtractGuidedSectionLib's internal storage size. The latter is
calculated as follows (see GetExtractGuidedSectionHandlerInfo()):

  sizeof(EXTRACT_GUIDED_SECTION_HANDLER_INFO) +         // 32
  PcdMaximumGuidedExtractHandler * (
    sizeof(GUID) +                                      // 16
    sizeof(EXTRACT_GUIDED_SECTION_DECODE_HANDLER) +     //  8
    sizeof(EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER)     //  8
    )

OVMF sets PcdMaximumGuidedExtractHandler to 16 decimal (which is the
MdePkg default too), yielding 32 + 16 * (16 + 8 + 8) == 544 bytes.

Regarding the lifecycle of the new area:

(a) when and how it is initialized after first boot of the VM

  The library linked into SecMain finds that the area lacks the signature.
  It initializes the signature, plus the rest of the structure. This is
  independent of S3 support.

  Consumption of the area is also limited to SEC (but consumption does
  depend on full-config-boot).

(b) how it is protected from memory allocations during DXE

  It is not, in the general case; and we don't need to. Nothing else links
  against BaseExtractGuidedSectionLib; it's OK if DXE overwrites the area.

(c) how it is protected from the OS

  When S3 is enabled, we cover it with AcpiNVS in InitializeRamRegions().

  When S3 is not supported, the range is not protected.

(d) how it is accessed on the S3 resume path

  Examined by the library linked into SecMain. Registrations update the
  table in-place (based on GUID matches).

(e) how it is accessed on the warm reset path

  If S3 is enabled, then the OS won't damage the table (due to (c)), hence
  see (d).

  If S3 is unsupported, then the OS may or may not overwrite the
  signature. (It likely will.) This is identical to the pre-patch status.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15433 6f19259b-4bc3-4df7-8a09-765794883524
2014-04-05 21:26:09 +00:00
Laszlo Ersek 6a7cba79b7 OvmfPkg: implement LockBoxLib
The S3 suspend/resume infrastructure depends on the LockBox library class.
The edk2 tree currently contains Null and SMM instances. The Null instance
is useless, and the SMM instance would require SMM emulation by including
the SMM core and adding several new drivers, which is deemed too complex.

Hence add a simple LockBoxLib instance for OVMF.

jordan.l.justen@intel.com:
 * use PCDs instead of EmuNvramLib
   - clear memory in PlatformPei on non S3 boots
 * allocate NVS memory and store a pointer to that memory
   - reduces memory use at fixed locations

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15301 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 08:03:23 +00:00
Laszlo Ersek 78a38b73c3 OvmfPkg: PlatformPei: reserve early page tables on X64
On X64, the reset vector code in
"OvmfPkg/ResetVector/Ia32/PageTables64.asm" identity maps the first 4GB of
RAM for PEI, consuming six frames starting at 8MB.

This range is declared by the PcdOvmfSecPageTablesBase/Size PCDs.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
[jordan.l.justen@intel.com: Move to MemDetect.c; use PCDs]
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15298 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 08:02:52 +00:00
Laszlo Ersek e249f906f1 OvmfPkg: PlatformPei: reserve SEC/PEI temp RAM for S3 resume
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
[jordan.l.justen@intel.com: move to MemDetect.c; use PCDs]
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15297 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 08:02:45 +00:00
Jordan Justen 8e54500fd4 OvmfPkg: Add section of memory to use for PEI on S3 resume
This 32k section of RAM will be declared to the PEI Core on
S3 resume to allow memory allocations during S3 resume PEI.

If the boot mode is BOOT_ON_S3_RESUME, then we publish
the pre-reserved PcdS3AcpiReservedMemory range to PEI.

If the boot mode is not BOOT_ON_S3_RESUME, then we reserve
this range as ACPI NVS so the OS will not use it.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15294 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 08:02:16 +00:00
Jordan Justen 7cdba6346b OvmfPkg/PlatformPei: Detect S3 support for QEMU / KVM
QEMU indicates whether S3 is supported or not in the
fw-cfg interface.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15293 6f19259b-4bc3-4df7-8a09-765794883524
2014-03-04 08:01:58 +00:00
Jordan Justen b36f701d4f OvmfPkg: Split MAINFV into a separate PEI and DXE FVs
By splitting the PEI and DXE phases into separate FVs,
we can only reserve the PEI FV for ACPI S3 support.
This should save about 7MB.

Unfortunately, this all has to happen in a single commit.

DEC:
* Remove PcdOvmfMemFv(Base|Size)
* Add PcdOvmfPeiMemFv(Base|Size)
* Add PcdOvmfDxeMemFv(Base|Size)

FDF:
* Add new PEIFV. Move PEI modules here.
* Remove MAINFV
* Add PEIFV and DXEFV into FVMAIN_COMPACT
   - They are added as 2 sections of a file, and compressed
     together so they should retain good compression
* PcdOvmf(Pei|Dxe)MemFv(Base|Size) are set

SEC:
* Find both the PEI and DXE FVs after decompression.
   - Copy them separately to their memory locations.

Platform PEI driver:
* Fv.c: Publish both FVs as appropriate
* MemDetect.c: PcdOvmfMemFv(Base|Size) =>
                PcdOvmfDxeMemFv(Base|Size)

OVMF.fd before:

  Non-volatile data storage
  FVMAIN_COMPACT                    uncompressed
    FV FFS file                     LZMA compressed
      MAINFV                        uncompressed
        individual PEI modules      uncompressed
        FV FFS file                 compressed with PI_NONE
          DXEFV                     uncompressed
            individual DXE modules  uncompressed
  SECFV                             uncompressed

OVMF.fd after:

  Non-volatile data storage
  FVMAIN_COMPACT                    uncompressed
    FV FFS file                     LZMA compressed
      PEIFV                         uncompressed
        individual PEI modules      uncompressed
      DXEFV                         uncompressed
        individual DXE modules      uncompressed
  SECFV                             uncompressed

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15151 6f19259b-4bc3-4df7-8a09-765794883524
2014-01-21 19:39:13 +00:00
Wei Liu 447d264115 OvmfPkg: enable Xen specific path
This patch sets PcdPciDisableBusEnumeration to true then makes use of
PublishPeiMemory and XenMemMapInitialization to construct memory map for
Xen guest.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14946 6f19259b-4bc3-4df7-8a09-765794883524
2013-12-08 01:36:25 +00:00
jljusten 931a0c74ed OvmfPkg: enable PIIX4 IO space in the PEI phase
I. There are at least three locations in OvmfPkg that manipulate the PMBA
and related PIIX4 registers.

1. MiscInitialization() [OvmfPkg/PlatformPei/Platform.c]
   module type: PEIM -- Pre-EFI Initialization Module
   (a) currently sets the PMBA only: 00.01.3 / 0x40 bits [15:6]

2. AcpiTimerLibConstructor() [OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c]
   module type: BASE -- probably callable anywhere after PEI
   (a) sets the PMBA if needed:      00.01.3 / 0x40 bits [15:6]
   (b) sets PCICMD/IOSE if needed:   00.01.3 / 0x04 bit  0
   (c) sets PMREGMISC/PMIOSE:        00.01.3 / 0x80 bit  0

3. AcpiInitialization() [OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c]
   module type: DXE_DRIVER -- Driver eXecution Environment
   (a) sets SCI_EN, which depends on correct PMBA setting from earlier

(
  The relative order of #1 and #3 is dictated minimally by their module
  types. Said relative order can be verified with the boot log:

       27 Loading PEIM at 0x00000822320 EntryPoint=0x00000822580
          PlatformPei.efi
       28 Platform PEIM Loaded
     1259 PlatformBdsInit
     1270 PlatformBdsPolicyBehavior

  Line 28 is printed by InitializePlatform()
  [OvmfPkg/PlatformPei/Platform.c] which is the entry point of that
  module. The other two lines are printed by the corresponding functions
  in "OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c".
)

Currently #2 (AcpiTimerLibConstructor()) is called in a random spot
(whenever it gets loaded from the firmware image) and masks the
insufficient setup in #1. We shouldn't depend on that, PEI should finish
with IO space being fully accessibe. In addition, PEI should program the
same PMBA value as AcpiTimerLib.

II. The PEI change notwithstanding, AcpiTimerLib should stay defensive and
ensure proper PM configuration for itself (either by confirming or by
doing).

III. Considering a possible cleanup/unification of #2 and #3: timer
functions relying on AcpiTimerLibConstructor(),

- MicroSecondDelay()
- NanoSecondDelay()
- GetPerformanceCounter()
- GetPerformanceCounterProperties()
- GetTimeInNanoSecond()

may be called before #3 is reached (in Boot Device Selection phase), so we
should not move the initialization from #2 to #3. (Again, AcpiTimerLib
should contain its own setup.)

We should also not move #3 to an earlier phase -- SCI_EN is premature
unless we're about to boot real soon ("enable generation of SCI upon
assertion of PWRBTN_STS, LID_STS, THRM_STS, or GPI_STS bits").

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13722 6f19259b-4bc3-4df7-8a09-765794883524
2012-09-12 07:19:16 +00:00
jljusten cb678aa85e OvmfPkg: clean up memory map
Fix IO-APIC range size.
Add HPET.
Take LAPIC base from PCD and fix range size.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13572 6f19259b-4bc3-4df7-8a09-765794883524
2012-07-31 18:17:37 +00:00
vanjeff e8e5cd4a5e Set MTRR registers.
Signed-off-by: vanjeff
Reviewed-by: rsun3


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12589 6f19259b-4bc3-4df7-8a09-765794883524
2011-10-28 06:04:01 +00:00
jljusten eec7d42017 OvmfPkg/PlatformPei: Add Xen support
* Make PlatformPei aware of Xen
* Fix assigned PIO and MMIO ranges to be compatible with Xen
* Reserve Xen HVM address range
* Publish XenInfo HOB
* Don't program PIIX4 PMBA for Xen

Signed-off-by: Andrei Warkentin <andreiw@motorola.com>
Reviewed-by: gavinguan
Signed-off-by: jljusten

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12091 6f19259b-4bc3-4df7-8a09-765794883524
2011-08-05 15:43:05 +00:00
jljusten 9ed65b1005 OvmfPkg/PlatformPei: Set BootMode, install MasterBootMode PPI
MdeModulePkg/Core/DxeIplPeim is now dependent on
gEfiPeiMasterBootModePpiGuid in order to run.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11412 6f19259b-4bc3-4df7-8a09-765794883524
2011-03-22 01:55:08 +00:00
jljusten c756b2ab80 OvmfPkg/PlatformPei: Set PM base address OVMF
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11250 6f19259b-4bc3-4df7-8a09-765794883524
2011-01-13 05:46:24 +00:00
hhtian 56d7640a53 Update the copyright notice format
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10439 6f19259b-4bc3-4df7-8a09-765794883524
2010-04-28 12:43:04 +00:00
lgao4 7b202cb0f9 1. Correct File header to ## @file
2. Remove unnecessary .common] postfix on section.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10051 6f19259b-4bc3-4df7-8a09-765794883524
2010-02-23 23:58:38 +00:00
mdkinney 29a3f13989 Remove unnecessary use of FixedPcdxxx() functions and [FixedPcd] INF sections. These should only be used for PCDs that are used to pre-init global variables, pre-init global structures, or size arrays.
Do some minor clean ups to INF files
 


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9870 6f19259b-4bc3-4df7-8a09-765794883524
2010-01-30 00:10:44 +00:00
jljusten c1c2669c6b OVMF: Update OVMF FD/FV build to minimize ROM size
* Only SEC is uncompressed now
* The MAIN FV with PEI & DXE can easily shrink and grow as needed
* The final output will now be OVMF.Fv rather than OVMF.fd
* The final output size will be a multiple of 64kb

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9672 6f19259b-4bc3-4df7-8a09-765794883524
2010-01-04 16:17:59 +00:00
jljusten 77ba993c88 OVMF: Add support for more persistent NV variables which can survive a system reboot.
Make use of EMU Variable driver's PcdEmuVariableNvStoreReserved to allow
NV variables to persist a VM system reset.  The contents of the NV variables
will still be lost when the VM is shut down, but they appear to persist
when the efi shell reset command is run.  (Tested with QEMU 0.10.0.)

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9241 6f19259b-4bc3-4df7-8a09-765794883524
2009-09-07 20:18:17 +00:00
jljusten 49ba9447c9 Add initial version of Open Virtual Machine Firmware (OVMF) platform.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8398 6f19259b-4bc3-4df7-8a09-765794883524
2009-05-27 21:10:18 +00:00