EFI_RESOURCE_MEMORY_UNACCEPTED has been officially defined in the PI
1.8 specification. So all temporary solutions have been replaced with
the actual definition.
Cc: Felix Polyudov <felixp@ami.com>
Cc: Dhanaraj V <vdhanaraj@ami.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Sachin Ganesh <sachinganesh@ami.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
This patch refines the SmmAccess implementation:
1. SmramMap will be retrieved from the
gEfiSmmSmramMemoryGuid instead of original from
the TSEG Memory Base register.
2. Remove the gEfiAcpiVariableGuid creation, thus
the DESCRIPTOR_INDEX definition can be also cleaned.
3. The gEfiAcpiVariableGuid HOB is moved to the
OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
In the PiSmmCpuDxeSmm driver, SMRAM allocation for SMI
handlers and processor Save State areas was traditionally
performed using the Smst->AllocatePages() function during
the DXE phase. The introduction of SmmRelocationLib
changes this process by moving the allocation to the PEI
phase, where Smst->AllocatePages() is not accessible.
Instead, the allocation is now handled by partitioning
the SMRAM based on the information provided by a GUID HOB
(identified by gEfiSmmSMramMemoryGuid).
This patch is to ensure that OVMF produces the
gEfiSmmSMramMemoryGuid HOB, allowing SmmRelocationLib to
reserve the necessary memory for SMBASE relocation.
More info for the change:
1. The EFI_SMM_SMRAM_MEMORY_GUID HOB, as defined in the PI
specification, vol.3, section 5, which is used to describe
the SMRAM memory regions supported by the platform. This HOB
should be produced during the memory detection phase to
align with the PI spec.
2. In addition to the memory reserved for ACPI S3 resume,
an increasing number of features require reserving SMRAM
for specific purposes, such as SmmRelocation. Other
advanced features in Intel platforms also necessitate
this. The implementation of these features varies and is
entirely dependent on the platform. This is why an
increasing number of platforms are adopting the
EFI_SMM_SMRAM_MEMORY_GUID HOB for SMRAM description.
3. It is crucial that the SMRAM information remains
consistent when retrieved from the platform, whether
through the SMM ACCESS PPI/Protocol or the
EFI_SMM_SMRAM_MEMORY_GUID HOB. Inconsistencies can lead
to unexpected issues, most commonly memory region conflicts.
4. The SMM ACCESS PPI/Protocol can be naturally
implemented for general use. The common approach is to
utilize the EFI_SMM_SMRAM_MEMORY_GUID HOB. For reference,
see the existing implementation in the EDK2 repository at
edk2/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf and
edk2-platforms/Silicon/Intel/IntelSiliconPkg/Feature/
SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf.
Next patch will refine the OVMF SMM Access to consume
the EFI_SMM_SMRAM_MEMORY_GUID HOB.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Adjust physical address space logic for la57 mode (5-level paging).
With a larger logical address space we can identity-map a larger
physical address space.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Message-Id: <20240222105407.75735-4-kraxel@redhat.com>
Cc: Michael Roth <michael.roth@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: Oliver Steffen <osteffen@redhat.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list
posting into "Cc:" tags in the commit message, in order to pacify
"PatchCheck.py"]
In addition to initializing the PhysMemAddressWidth and
FirstNonAddress fields in PlatformInfoHob, the
PlatformAddressWidthInitialization function is responsible
for initializing the PcdPciMmio64Base and PcdPciMmio64Size
fields.
Currently, for CloudHv guests, the PcdPciMmio64Base is
placed immediately after either the 4G boundary or the
last RAM region, whichever is greater. We do not change
this behavior.
Previously, when booting CloudHv guests with greater than
1TiB of high memory, the PlatformAddressWidthInitialization
function incorrect calculates the amount of RAM using the
overflowed 24-bit CMOS register.
Now, we update the PlatformAddressWidthInitialization
behavior on CloudHv to scan the E820 entries to detect
the amount of RAM. This allows CloudHv guests to boot with
greater than 1TiB of RAM
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
The PlatformScanE820 utility function is not currently compatible
with CloudHv since it relies on the prescence of the "etc/e820"
QemuFwCfg file. Update the PlatformScanE820 to iterate through the
PVH e820 entries when running on a CloudHv guest.
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Older linux kernels have problems with phys-bits larger than 46,
ubuntu 18.04 (kernel 4.15) has been reported to be affected.
Reduce phys-bits limit from 47 to 46.
Reported-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
If PcdUse1GPageTable is not enabled restrict the physical address space
used to 1TB, to limit the amount of memory needed for identity mapping
page tables.
The same already happens in case the processor has no support for
gigabyte pages.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
__FUNCTION__ is a pre-standard extension that gcc and Visual C++ among
others support, while __func__ was standardized in C99.
Since it's more standard, replace __FUNCTION__ with __func__ throughout
OvmfPkg.
Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
Replace the static struct initialization with a call to ZeroMem to avoid
generating a call to memset in certain build configurations.
Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Oliver Smith-Denny <osd@smith-denny.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
With the new mmconfig location at 0xe0000000 above the 32-bit PCI MMIO
window we don't have to special-case the mmconfig xbar any more. We'll
just add a mtrr uncachable entry starting at MMIO window base and ending
at 4GB.
Update comments to match reality.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Also swap the ordering of 32bit PCI MMIO window on q35, i.e. use the
room between end of low memory and the start of the mmconfig bar.
With a typical configuration on modern qemu with gigabyte-aligned memory
the MMIO window start at 0x8000000, sized 1532 MB. In case there is
memory present above 0x80000000 the window will start at 0xc0000000
instead, with 512 MB size.
This depends on qemu commit 4a4418369d6d ("q35: fix mmconfig and
PCI0._CRS"), so it raises the bar for the lowest supported version
to qemu 4.1 (released Aug 2019).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Move the commment up so it is placed just before the address space
calculations start. Also add q35 memory layout.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243
ProcessHobList once was implemented in PlatformInitLib and it walks thru
TdHob list and accept un-accepted memories.
This patch moves the codes to SecTdxHelperLib and rename ProcessHobList
as TdxHelperProcessTdHob
After TdxHelperProcessTdHob is introduced, below changes are applied:
- Call TdxHelperProcessTdHob instead of ProcessHobList in SecMain.c
(in both OvmfPkgX64/Sec and IntelTdx/Sec).
- Delete the duplicated codes in PlatformInitLib
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.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>
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>
In QEMU v5.1.0, the CPU hotplug register block misbehaves: the negotiation
protocol is (effectively) broken such that it suggests that switching from
the legacy interface to the modern interface works, but in reality the
switch never happens. The symptom has been witnessed when using TCG
acceleration; KVM seems to mask the issue. The issue persists with the
following (latest) stable QEMU releases: v5.2.0, v6.2.0, v7.2.0. Currently
there is no stable release that addresses the problem.
The QEMU bug confuses the Present and Possible counting in function
PlatformMaxCpuCountInitialization(), in
"OvmfPkg/Library/PlatformInitLib/Platform.c". OVMF ends up with Present=0
Possible=1. This in turn further confuses MpInitLib in UefiCpuPkg (hence
firmware-time multiprocessing will be broken). Worse, CPU hot(un)plug with
SMI will be summarily broken in OvmfPkg/CpuHotplugSmm, which (considering
the privilege level of SMM) is not that great.
Detect the issue in PlatformCpuCountBugCheck(), and print an error message
and *hang* if the issue is present.
Users willing to take risks can override the hang with the experimental
QEMU command line option
-fw_cfg name=opt/org.tianocore/X-Cpuhp-Bugcheck-Override,string=yes
(The "-fw_cfg" QEMU option itself is not experimental; its above argument,
as far it concerns the firmware, is experimental.)
The problem was originally reported by Ard [0]. We analyzed it at [1] and
[2]. A QEMU patch was sent at [3]; now merged as commit dab30fbef389
("acpi: cpuhp: fix guest-visible maximum access size to the legacy reg
block", 2023-01-08), to be included in QEMU v8.0.0.
[0] https://bugzilla.tianocore.org/show_bug.cgi?id=4234#c2
[1] https://bugzilla.tianocore.org/show_bug.cgi?id=4234#c3
[2] IO port write width clamping differs between TCG and KVM
http://mid.mail-archive.com/aaedee84-d3ed-a4f9-21e7-d221a28d1683@redhat.comhttps://lists.gnu.org/archive/html/qemu-devel/2023-01/msg00199.html
[3] acpi: cpuhp: fix guest-visible maximum access size to the legacy reg block
http://mid.mail-archive.com/20230104090138.214862-1-lersek@redhat.comhttps://lists.gnu.org/archive/html/qemu-devel/2023-01/msg00278.html
NOTE: PlatformInitLib is used in the following platform DSCs:
OvmfPkg/AmdSev/AmdSevX64.dsc
OvmfPkg/CloudHv/CloudHvX64.dsc
OvmfPkg/IntelTdx/IntelTdxX64.dsc
OvmfPkg/Microvm/MicrovmX64.dsc
OvmfPkg/OvmfPkgIa32.dsc
OvmfPkg/OvmfPkgIa32X64.dsc
OvmfPkg/OvmfPkgX64.dsc
but I can only test this change with the last three platforms, running on
QEMU.
Test results:
TCG QEMU OVMF override result
patched patched
--- ------- ------- -------- --------------------------------------
0 0 0 0 CPU counts OK (KVM masks the QEMU bug)
0 0 1 0 CPU counts OK (KVM masks the QEMU bug)
0 1 0 0 CPU counts OK (QEMU fix, but KVM masks
the QEMU bug anyway)
0 1 1 0 CPU counts OK (QEMU fix, but KVM masks
the QEMU bug anyway)
1 0 0 0 boot with broken CPU counts (original
QEMU bug)
1 0 1 0 broken CPU count caught (boot hangs)
1 0 1 1 broken CPU count caught, bug check
overridden, boot continues
1 1 0 0 CPU counts OK (QEMU fix)
1 1 1 0 CPU counts OK (QEMU fix)
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
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: Jordan Justen <jordan.l.justen@intel.com>
Cc: Michael Brown <mcb30@ipxe.org>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Oliver Steffen <osteffen@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4250
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20230119110131.91923-3-lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Hugely-appreciated-by: Michael Brown <mcb30@ipxe.org>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Move the QEMU v2.7 reset bug check/workaround to a separate function, as
we'll need to detect further issues.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
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: Jordan Justen <jordan.l.justen@intel.com>
Cc: Michael Brown <mcb30@ipxe.org>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Oliver Steffen <osteffen@redhat.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4250
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20230119110131.91923-2-lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Hugely-appreciated-by: Michael Brown <mcb30@ipxe.org>
Acked-by: Gerd Hoffmann <kraxel@redhat.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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TDVF once accepts memory only by BSP. To improve the boot performance
this patch introduce the multi-core accpet memory. Multi-core means
BSP and APs work together to accept memory.
TDVF leverages mailbox to wake up APs. It is not enabled in MpInitLib
(Which requires SIPI). So multi-core accept memory cannot leverages
MpInitLib to coordinate BSP and APs to work together.
So TDVF split the accept memory into 2 phases.
- AcceptMemoryForAPsStack:
BSP accepts a small piece of memory which is then used by APs to setup
stack. We assign a 16KB stack for each AP. So a td-guest with 256 vCPU
requires 255*16KB = 4080KB.
- AcceptMemory:
After above small piece of memory is accepted, BSP commands APs to
accept memory by sending AcceptPages command in td-mailbox. Together
with the command and accpet-function, the APsStack address is send
as well. APs then set the stack and jump to accept-function to accept
memory.
AcceptMemoryForAPsStack accepts as small memory as possible and then jump
to AcceptMemory. It fully takes advantage of BSP/APs to work together.
After accept memory is done, the memory region for APsStack is not used
anymore. It can be used as other private memory. Because accept-memory
is in the very beginning of boot process and it will not impact other
phases.
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>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
In the commit 4f173db8b4 "OvmfPkg/PlatformInitLib: Add functions for
EmuVariableNvStore", it introduced a PlatformValidateNvVarStore() function
for checking the integrity of NvVarStore.
In some cases when the VariableHeader->StartId is VARIABLE_DATA, the
VariableHeader->State is not just one of the four primary states:
VAR_IN_DELETED_TRANSITION, VAR_DELETED, VAR_HEADER_VALID_ONLY, VAR_ADDED.
The state may combined two or three states, e.g.
0x3C = (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED
or
0x3D = VAR_ADDED & VAR_DELETED
When the variable store has those variables, system booting/rebooting will
hangs in a ASSERT:
NvVarStore Variable header State was invalid.
ASSERT
/mnt/working/source_code-git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819):
((BOOLEAN)(0==1))
Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we
saw some variables which have 0x3C or 0x3D state in store.
e.g.
UpdateVariable(), VariableName=BootOrder
L1871, State=0000003F <-- VAR_ADDED
State &= VAR_DELETED=0000003D
FlushHobVariableToFlash(), VariableName=BootOrder
...
UpdateVariable(), VariableName=InitialAttemptOrder
L1977, State=0000003F
State &= VAR_IN_DELETED_TRANSITION=0000003E
L2376, State=0000003E
State &= VAR_DELETED=0000003C
FlushHobVariableToFlash(), VariableName=InitialAttemptOrder
...
UpdateVariable(), VariableName=ConIn
L1977, State=0000003F
State &= VAR_IN_DELETED_TRANSITION=0000003E
L2376, State=0000003E
State &= VAR_DELETED=0000003C
FlushHobVariableToFlash(), VariableName=ConIn
...
So, only allowing the four primary states is not enough. This patch changes
the falid states list (Follow Jiewen Yao's suggestion):
1. VAR_HEADER_VALID_ONLY (0x7F)
- Header added (*)
2. VAR_ADDED (0x3F)
- Header + data added
3. VAR_ADDED & VAR_IN_DELETED_TRANSITION (0x3E)
- marked as deleted, but still valid, before new data is added. (*)
4. VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED (0x3C)
- deleted, after new data is added.
5. VAR_ADDED & VAR_DELETED (0x3D)
- deleted directly, without new data.
(*) means to support surprise shutdown.
And removed (VAR_IN_DELETED_TRANSITION) and (VAR_DELETED) because they are
invalid states.
v2:
Follow Jiewen Yao's suggestion to add the following valid states:
VAR_ADDED & VAR_DELETED (0x3D)
VAR_ADDED & VAR_IN_DELETED_TRANSITION (0x3E)
VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED (0x3C)
and removed the following invalid states:
VAR_IN_DELETED_TRANSITION
VAR_DELETED
Signed-off-by: Chun-Yi Lee <jlee@suse.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This is required for passing the ACPI tables from the VMM up to the
guest OS. They are transferred through this GUID extension.
Signed-off-by: Jiaqi Gao <jiaqi.gao@intel.com>
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>
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>
There should be a check that the FV HeaderLength cannot be an odd
number. Otherwise in the following CalculateSum16 there would be an
ASSERT.
In ValidateFvHeader@QemuFlashFvbServicesRuntimeDxe/FwBlockServices.c
there a is similar check to the FwVolHeader->HeaderLength.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-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>
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3937
BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED is defined in MdeModulePkg. The
files which use the definition are updated as well.
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>
There are 3 functions added for EmuVariableNvStore:
- PlatformReserveEmuVariableNvStore
- PlatformInitEmuVariableNvStore
- PlatformValidateNvVarStore
PlatformReserveEmuVariableNvStore allocate storage for NV variables early
on so it will be at a consistent address.
PlatformInitEmuVariableNvStore copies the content in
PcdOvmfFlashNvStorageVariableBase to the storage allocated by
PlatformReserveEmuVariableNvStore. This is used in the case that OVMF is
launched with -bios parameter. Because in that situation UEFI variables
will be partially emulated, and non-volatile variables may lose their
contents after a reboot. This makes the secure boot feature not working.
PlatformValidateNvVarStore is renamed from TdxValidateCfv and it is used
to validate the integrity of FlashNvVarStore
(PcdOvmfFlashNvStorageVariableBase). It should be called before
PlatformInitEmuVariableNvStore is called to copy over the content.
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>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
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>
Since Cloud Hypervisor doesn't emulate an A20 gate register on I/O port
0x92, it's better to avoid accessing it when the platform is identified
as Cloud Hypervisor.
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Acked-by: Jiewen Yao <jiewen.yao@intel.com>
There are few places in the codebase assuming QemuFwCfg will be present
and supported, which can cause some issues when trying to rely on the
QemuFwCfgLibNull implementation of QemuFwCfgLib.
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Acked-by: Jiewen Yao <jiewen.yao@intel.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>
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3429
When host VMM create the Td guest, the system memory informations are
stored in TdHob, which is a memory region described in Tdx metadata.
The system memory region in TdHob should be accepted before it can be
accessed. So the newly added function (ProcessTdxHobList) is to process
the TdHobList to accept the memory. Because TdHobList is provided by
host VMM which is not trusted, so its content should be checked before
it is consumed by TDVF.
Because ProcessTdxHobList is to be called in SEC phase, so
PlatformInitLib.inf is updated to support SEC.
Note: In this patch it is BSP which accepts the pages. So there maybe
boot performance issue. There are some mitigations to this issue, such
as lazy accept, 2M accept page size, etc. We will re-visit here in the
future.
EFI_RESOURCE_MEMORY_UNACCEPTED is a new ResourceType in
EFI_HOB_RESOURCE_DESCRIPTOR. It is defined for the unaccepted memory
passed from Host VMM. This is proposed in microsoft/mu_basecore#66
files#diff-b20a11152d1ce9249c691be5690b4baf52069efadf2e2546cdd2eb663d80c9
e4R237 according to UEFI-Code-First. The proposal was approved in 2021
in UEFI Mantis, and will be added to the new PI.next specification.
Per the MdePkg reviewer's comments, before this new ResourceType is
added in the PI spec, it should not be in MdePkg. So it is now
defined as an internal implementation and will be moved to
MdePkg/Include/Pi/PiHob.h after it is added in PI spec.
See https://edk2.groups.io/g/devel/message/87641
PcdTdxAcceptPageSize is added for page accepting. Currently TDX supports
4K and 2M accept page size. The default value is 2M.
Tdx guest is only supported in X64. So for IA32 ProcessTdxHobList
just returns EFI_UNSUPPORTED.
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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3863
There are 3 variants of PlatformPei in OvmfPkg:
- OvmfPkg/PlatformPei
- OvmfPkg/XenPlatformPei
- OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf
These PlatformPeis can share many common codes, such as
Cmos / Hob / Memory / Platform related functions. This commit
(and its following several patches) are to create a PlatformInitLib
which wraps the common code called in above PlatformPeis.
In this initial version of PlatformInitLib, below Cmos related functions
are introduced:
- PlatformCmosRead8
- PlatformCmosWrite8
- PlatformDebugDumpCmos
They correspond to the functions in OvmfPkg/PlatformPei:
- CmosRead8
- CmosWrite8
- DebugDumpCmos
Considering this PlatformInitLib will be used in SEC phase, global
variables and dynamic PCDs are avoided. We use PlatformInfoHob
to exchange information between functions.
EFI_HOB_PLATFORM_INFO is the data struct which contains the platform
information, such as HostBridgeDevId, BootMode, S3Supported,
SmmSmramRequire, etc.
After PlatformInitLib is created, OvmfPkg/PlatformPei is refactored
with this library.
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>