BuildResourceDescriptorHob() expects the third parameter be the Length,
not the End address.
Fixes: 328076cfdf ("OvmfPkg/PlatformInitLib: Add PlatformAddHobCB")
Reported-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
First handle the cases which do not need know the value of
PlatformInfoHob->LowMemory (microvm and cloudhv). Then call
PlatformGetSystemMemorySizeBelow4gb() to get LowMemory. Finally handle
the cases (q35 and pc) which need to look at LowMemory,
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Add PlatformReservationConflictCB() callback function for use with
PlatformScanE820(). It checks whenever the 64bit PCI MMIO window
overlaps with a reservation from qemu. If so move down the MMIO window
to resolve the conflict.
Write any actions done (moving mmio window) to the firmware log with
INFO loglevel.
This happens on (virtual) AMD machines with 1TB address space,
because the AMD IOMMU uses an address window just below 1TB.
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4251
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Add PlatformAddHobCB() callback function for use with
PlatformScanE820(). It adds HOBs for high memory and reservations (low
memory is handled elsewhere because there are some special cases to
consider). This replaces calls to PlatformScanOrAdd64BitE820Ram() with
AddHighHobs = TRUE.
Write any actions done (adding HOBs, skip unknown types) to the firmware
log with INFO loglevel.
Also remove PlatformScanOrAdd64BitE820Ram() which is not used any more.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Add PlatformGetLowMemoryCB() callback function for use with
PlatformScanE820(). It stores the low memory size in
PlatformInfoHob->LowMemory. This replaces calls to
PlatformScanOrAdd64BitE820Ram() with non-NULL LowMemory.
Write any actions done (setting LowMemory) to the firmware log
with INFO loglevel.
Also change PlatformGetSystemMemorySizeBelow4gb() to likewise set
PlatformInfoHob->LowMemory instead of returning the value. Update
all Callers to the new convention.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
First step replacing the PlatformScanOrAdd64BitE820Ram() function.
Add a PlatformScanE820() function which loops over the e280 entries
from FwCfg and calls a callback for each of them.
Add a GetFirstNonAddressCB() function which will store the first free
address (right after the last RAM block) in
PlatformInfoHob->FirstNonAddress. This replaces calls to
PlatformScanOrAdd64BitE820Ram() with non-NULL MaxAddress.
Write any actions done (setting FirstNonAddress) to the firmware log
with INFO loglevel.
Also drop local FirstNonAddress variables and use
PlatformInfoHob->FirstNonAddress instead everywhere.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
In commit 49edde1523 ("OvmfPkg/PlatformPei: set 32-bit UC area at
PciBase / PciExBarBase (pc/q35)", 2019-06-03), I forgot to update the
comment. Do it now.
Fixes: 49edde1523
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
qemu uses the etc/e820 fw_cfg file not only for memory, but
also for reservations. Handle reservations by adding resource
descriptor hobs for them.
A typical qemu configuration has a small reservation between
lapic and flash:
# sudo cat /proc/iomem
[ ... ]
fee00000-fee00fff : Local APIC
feffc000-feffffff : Reserved <= HERE
ffc00000-ffffffff : Reserved
[ ... ]
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Rely on the CcProbe() function to identify when running on TDX. This
allows the firmware to follow a different codepath for Cloud Hypervisor,
which means it doesn't rely on PVH to find out about memory below 4GiB.
instead it falls back onto the CMOS to retrieve that information.
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Reviewed-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937
There are below major changes in PlatformInitLib/PlatformPei
1. ProcessHobList
The unaccepted memory is accepted if it is under 4G address.
Please be noted: in current stage, we only accept the memory under 4G.
We will re-visit here in the future when on-demand accept memory is
required.
2. TransferTdxHobList
Transfer the unaccepted memory hob to EFI_RESOURCE_SYSTEM_MEMORY hob
if it is accepted.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
In case we have a reliable PhysMemAddressWidth use that to dynamically
size the 64bit address window. Allocate 1/8 of the physical address
space and place the window at the upper end of the address space.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Try detect physical address space, when successful use it.
Otherwise go continue using the current guesswork code path.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Add some qemu specific quirks to PlatformAddressWidthFromCpuid()
to figure whenever the PhysBits value returned by CPUID is
something real we can work with or not.
See the source code comment for details on the logic.
Also apply some limits to the address space we are going to use:
* Place a hard cap at 47 PhysBits (128 TB) to avoid using addresses
which require 5-level paging support.
* Cap at 40 PhysBits (1 TB) in case the CPU has no support for
gigabyte pages, to avoid excessive amounts of pages being
used for page tables.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Traditional q35 memory layout is 2.75 GB of low memory, leaving room
for the pcie mmconfig at 0xb0000000 and the 32-bit pci mmio window at
0xc0000000. Because of that OVMF tags the memory range above
0xb0000000 as uncachable via mtrr.
A while ago qemu started to gigabyte-align memory by default (to make
huge pages more effective) and q35 uses only 2G of low memory in that
case. Which effectively makes the 32-bit pci mmio window start at
0x80000000.
This patch updates the mtrr setup code accordingly.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Read the "hardware-info" item from fw-cfg to extract specifications
of PCI host bridges and analyze the 64-bit apertures of them to
find out the highest 64-bit MMIO address required which determines
the address space required by the guest, and, consequently, the
FirstNonAddress used to calculate size of physical addresses.
Using the static PeiHardwareInfoLib, read the fw-cfg file of
hardware information to extract, one by one, all the host
bridges. Find the last 64-bit MMIO address of each host bridge,
using the HardwareInfoPciHostBridgeLib API, and compare it to an
accumulate value to discover the highest address used, which
corresponds to the highest value that must be included in the
guest's physical address space.
Given that platforms with multiple host bridges may provide the PCI
apertures' addresses, the memory detection logic must take into
account that, if the host provided the MMIO windows that can and must
be used, the guest needs to take those values. Therefore, if the
MMIO windows are found in the host-provided fw-cfg file, skip all the
logic calculating the physical address size and just use the value
provided. Since each PCI host bridge corresponds to an element in
the information provided by the host, each of these must be analyzed
looking for the highest address used.
Cc: Alexander Graf <graf@amazon.de>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Nicolas Ojeda Leon <ncoleon@amazon.com>
microvm places the 64bit mmio space at the end of the physical address
space. So mPhysMemAddressWidth must be correct, otherwise the pci host
bridge setup throws an error because it thinks the 64bit mmio window is
not addressable.
On microvm we can simply use standard cpuid to figure the address width
because the host-phys-bits option (-cpu ${name},host-phys-bits=on) is
forced to be enabled. Side note: For 'pc' and 'q35' this is not the
case for backward compatibility reasons.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429
There are below changes in PlatformInitLib for Tdx guest:
1. Publish ram regions
In Tdx guest, the system memory is passed in TdHob by host VMM. So
the major task of PlatformTdxPublishRamRegions is to walk thru the
TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob
to the hobs in DXE phase.
2. Build MemoryAllocationHob for Tdx Mailbox and Ovmf work area.
3. Update of PlatformAddressWidthInitialization. The physical
address width that Tdx guest supports is either 48 or 52.
4. Update of PlatformMemMapInitialization.
0xA0000 - 0xFFFFF is VGA bios region. Platform initialization marks the
region as MMIO region. Dxe code maps MMIO region as IO region.
As TDX guest, MMIO region is maps as shared. However VGA BIOS doesn't need
to be shared. Guest TDX Linux maps VGA BIOS as private and accesses for
BIOS and stuck on repeating EPT violation. VGA BIOS (more generally ROM
region) should be private. Skip marking VGA BIOA region [0xa000, 0xfffff]
as MMIO in HOB.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>