When a guest OS does not support unaccepted memory, the unaccepted
memory must be accepted before returning a memory map to the caller.
EfiMemoryAcceptProtocol is defined in MdePkg and is implemented /
Installed in AmdSevDxe for AMD SEV-SNP memory acceptance.
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>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
Message-Id: <20221108164616.3251967-2-dionnaglaze@google.com>
Switching from the ArmPlatformPkg/NorFlashDxe driver to the
OvmfPkg/VirtNorFlashDxe driver had the side effect that flash address
space got registered as EFI_MEMORY_WC instead of EFI_MEMORY_UC.
That confuses the linux kernel's numa code, seems this makes kernel
consider the flash being node memory. "lsmem" changes from ...
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000040000000-0x000000013fffffff 4G online yes 8-39
... to ...
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000000000000-0x0000000007ffffff 128M online yes 0
0x0000000040000000-0x000000013fffffff 4G online yes 8-39
... and in the kernel log got new error lines:
NUMA: Warning: invalid memblk node 512 [mem 0x0000000004000000-0x0000000007ffffff]
NUMA: Faking a node at [mem 0x0000000004000000-0x000000013fffffff]
Changing the attributes back to EFI_MEMORY_UC fixes this.
Fixes: b92298af82 ("ArmVirtPkg/ArmVirtQemu: migrate to OVMF's VirtNorFlashDxe")
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
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>
This reverts commit 4a86424224 as the
commit 73ccde8 introduced CpuPageTableLib dependency which resolved
for OvmfPkg is to be reverted.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4234
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4194
The TdTcg2Dxe lives in the OvmfPkg instead of the SecurityPkg. Having
the TdTcg2Dxe at the same place as Tcg2Dxe will be easier for platforms to
consume.
Definition of PcdCcEventlogAcpiTableLaml and PcdCcEventlogAcpiTableLasa
are also moved from OvmfPkg.dec to SecurityPkg.dec.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Arti Gupta <ARGU@microsoft.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Commit 0426115b67 ("UefiCpuPkg: Remove unused API in
SmmCpuFeaturesLib.h", 2022-12-21) removed the declaration of the function
SmmCpuFeaturesAllocatePageTableMemory() from the "SmmCpuFeaturesLib.h"
library class header.
Remove the API's (null-)implementation from OvmfPkg/SmmCpuFeaturesLib as
well.
Testing: OVMF builds, boots, and suspends/resumes (see earlier in this
series).
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Bugzilla: https://bugzilla.tianocore.org/show_bug.cgi?id=4235
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Similarly to the "cadence" mentioned in commit d272449d9e ("OvmfPkg:
raise DXEFV size to 11 MB", 2018-05-29), it's been ~1.75 years since
commit 5e75c4d1fe ("OvmfPkg: raise DXEFV size to 12 MB", 2020-03-11),
and we've outgrown DXEFV again (with NOOPT builds). Increase the DXEFV
size to 13MB now.
Do not modify all platform FDF files under OvmfPkg. "BhyveX64.fdf" is
still at 11MB, "OvmfXen.fdf" at 10MB. The "AmdSevX64.fdf",
"CloudHvX64.fdf", "IntelTdxX64.fdf" and "MicrovmX64.fdf" flash devices
could be modified similarly (from 12MB to 13MB), but I don't use or build
those platforms.
Tested on:
- IA32, q35, SMM_REQUIRE, Fedora 30 guest
- X64, pc (i440fx), no SMM, RHEL-7.9 guest
- IA32X64, q35, SMM_REQUIRE, RHEL-7.9 guest
Test steps:
- configure 3 VCPUs
- boot
- run "taskset -c $I efibootmgr" with $I covering 0..2
- systemctl suspend
- resume from virt-manager
- run "taskset -c $I efibootmgr" with $I covering 0..2
Cc: Anthony Perard <anthony.perard@citrix.com>
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: Julien Grall <julien@xen.org>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Peter Grehan <grehan@freebsd.org>
Cc: Rebecca Cran <rebecca@bsdio.com>
Cc: Sebastien Boeuf <sebastien.boeuf@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4236
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Per my bisection: nasm broke the parsing of the "--" end-of-options
delimiter in commit 55568c1193df ("nasm: scan the command line twice",
2016-10-03), part of the nasm-2.13 release. The parsing remains broken in
at least nasm-2.15.03. The (invalid) error message is: "more than one
input file specified". I've filed the following ticket for upstream nasm
(and ndisasm): <https://bugzilla.nasm.us/show_bug.cgi?id=3392829>.
Since the delimiter is not necessary in practice (due to $STEM being
"VbeShim", i.e., not starting with a hyphen), simply remove the delimiter.
Tested by enabling DEBUG in "VbeShim.asm", running the script, building
OVMF, booting Windows 7, and checking the firmware log (debug console).
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3876
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Prevent stack underrun in the event of a timer interrupt storm in
LocalApicTimerDxe and 8254TimerDxe interrupt handlers by using the
helper functions provided by NestedInterruptTplLib.
This fixes the same problem as addressed in commit 239b50a86
("OvmfPkg: End timer interrupt later to avoid stack overflow under
load"), but does so without breaking nested timer interrupts.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2815
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4162
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
UEFI requires us to support nested interrupts, but provides no way for
an interrupt handler to call RestoreTPL() without implicitly
re-enabling interrupts. In a virtual machine, it is possible for a
large burst of interrupts to arrive. We must prevent such a burst
from leading to stack underrun, while continuing to allow nested
interrupts to occur.
This can be achieved by allowing, when provably safe to do so, an
inner interrupt handler to return from the interrupt without restoring
the TPL and with interrupts remaining disabled after IRET, with the
deferred call to RestoreTPL() then being issued from the outer
interrupt handler. This is necessarily messy and involves direct
manipulation of the interrupt stack frame, and so should not be
implemented as open-coded logic within each interrupt handler.
Add the Nested Interrupt TPL Library (NestedInterruptTplLib) to
provide helper functions that can be used by nested interrupt handlers
in place of RaiseTPL()/RestoreTPL().
Example call tree for a timer interrupt occurring at TPL_APPLICATION
with a nested timer interrupt that makes its own call to RestoreTPL():
outer TimerInterruptHandler()
InterruptedTPL == TPL_APPLICATION
...
IsrState->InProgressRestoreTPL = TPL_APPLICATION;
gBS->RestoreTPL (TPL_APPLICATION);
EnableInterrupts();
dispatch a TPL_CALLBACK event
gEfiCurrentTpl = TPL_CALLBACK;
nested timer interrupt occurs
inner TimerInterruptHandler()
InterruptedTPL == TPL_CALLBACK
...
IsrState->InProgressRestoreTPL = TPL_CALLBACK;
gBS->RestoreTPL (TPL_CALLBACK);
EnableInterrupts();
DisableInterrupts();
IsrState->InProgressRestoreTPL = TPL_APPLICATION;
IRET re-enables interrupts
... finish dispatching TPL_CALLBACK events ...
gEfiCurrentTpl = TPL_APPLICATION;
DisableInterrupts();
IsrState->InProgressRestoreTPL = 0;
sees IsrState->DeferredRestoreTPL == FALSE and returns
IRET re-enables interrupts
Example call tree for a timer interrupt occurring at TPL_APPLICATION
with a nested timer interrupt that defers its call to RestoreTPL() to
the outer instance of the interrupt handler:
outer TimerInterruptHandler()
InterruptedTPL == TPL_APPLICATION
...
IsrState->InProgressRestoreTPL = TPL_APPLICATION;
gBS->RestoreTPL (TPL_APPLICATION);
EnableInterrupts();
dispatch a TPL_CALLBACK event
... finish dispatching TPL_CALLBACK events ...
gEfiCurrentTpl = TPL_APPLICATION;
nested timer interrupt occurs
inner TimerInterruptHandler()
InterruptedTPL == TPL_APPLICATION;
...
sees InterruptedTPL == IsrState->InProgressRestoreTPL
IsrState->DeferredRestoreTPL = TRUE;
DisableInterruptsOnIret();
IRET returns without re-enabling interrupts
DisableInterrupts();
IsrState->InProgressRestoreTPL = 0;
sees IsrState->DeferredRestoreTPL == TRUE and loops
IsrState->InProgressRestoreTPL = TPL_APPLICATION;
gBS->RestoreTPL (TPL_APPLICATION); <-- deferred call
EnableInterrupts();
DisableInterrupts();
IsrState->InProgressRestoreTPL = 0;
sees IsrState->DeferredRestoreTPL == FALSE and returns
IRET re-enables interrupts
Cc: Paolo Bonzini <pbonzini@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4162
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Deferring the EOI until after the call to RestoreTPL() means that any
callbacks invoked by RestoreTPL() will run with timer interrupt
delivery disabled. If any such callbacks themselves rely on timers to
implement timeout loops, then the callbacks will get stuck in an
infinite loop from which the system will never recover.
This reverts commit 239b50a86 ("OvmfPkg: End timer interrupt later to
avoid stack overflow under load").
Cc: Paolo Bonzini <pbonzini@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4162
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
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>
The Hii form is named "MainFormState" and the EFI variable is named
"PlatformConfig". Take into account the different names.
Fixes: aefcc91805 ("OvmfPkg/PlatformDxe: Handle all requests in ExtractConfig and RouteConfig")
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
PcdConfidentialComputingGuestAttr can be used to check the cc guest
type, including td-guest or sev-guest. CcProbe() can do the same
thing but CcProbeLib should be included in the dsc which uses
AcpiPlatformDxe. The difference between PcdConfidentialComputingGuestAttr
and CcProbe() is that PcdConfidentialComputingGuestAttr cannot be used
in multi-processor scenario but CcProbe() can. But there is no such
issue in AcpiPlatformDxe.
So we use PcdConfidentialComputingGuestAttr instead of CcProbeLib so that
it is simpler.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
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>
Copy the function BuildPlatformInfoHob() from OvmfPkg/PlatformPei.
QemuFwCfgLib expect this HOB to be present, or fails to do anything.
InternalQemuFwCfgIsAvailable() from QemuFwCfgPeiLib module will not
check if the HOB is actually present for example and try to use a NULL
pointer.
Fixes: cda98df162 ("OvmfPkg/QemuFwCfgLib: remove mQemuFwCfgSupported + mQemuFwCfgDmaSupported")
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <jiewen.yao@intel.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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TDVF APs once did nothing but spin around to wait for the Wakeup command.
This patch enables APs to handle the AcceptPages command. Once APs find
the AcceptPages command, it set its stack and jump to the function of
ApAcceptMemoryResourceRange (which will be introduced in the following
patch).
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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
This patch moves the TDX APs nasm code from SecEntry.nasm to
IntelTdxAPs.nasm. IntelTdxX64 and OvmfPkgX64 use the same nasm so that
it can be easier to be managed. In the following patch there will be
AcceptMemory related changes in IntelTdxAPs.nasm.
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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
In the following patches TdxMailboxLib will be included in
PlatformInitLib. While PlatformInitLib is imported by some IA32/X64
platforms (for example AmdSevX64.dsc). So TdxMailboxLibNull is added in
those platforms which don't support TDX feature.
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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TdxMailboxLib is designed only for TDX guest which arch is X64. This
patch set the VALID_ARCHITECTURES of TdxMailboxLib as X64.
Because in the following patches TdxMailboxLib will be included in
PlatformInitLib. While PlatformInitLib is imported by some X64 platforms
(for example AmdSevX64.dsc). So we need a NULL instance of TdxMailboxLib
which VALID_ARCHITECTURES is X64 as well. Based on this consideration
we design TdxMailboxLibNull.
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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4172
TdxMailboxLib once was designed to be used in DXE phase. But now it is
going to be used in SEC/PEI phase (in the following patches). Global
variables are not allowed. The library is refactored after those global
variables are deleted.
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>
Add CpuPageTableLib required by MpInitLib in OvmfPkg.
Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Acked-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>
Add support to use the reserved shared memory within the IoMmu library.
This improves boot times for all SEV guests, with SEV-SNP benefiting the
most as it avoids the page state change call to the hypervisor.
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4171
IoMmuDxe once was designed to support DMA operation when SEV is enabled.
After TDX is enabled in IoMmuDxe, some files' name in IoMmuDxe need to
be more general. So this patch rename:
AmdSevIoMmu.h -> CcIoMmu.h
AmdSevIoMmu.c -> CcIoMmu.c
Accordingly there are some udates in IoMmuDxe.c and IoMmuDxe.inf.
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>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4171
A typical QEMU fw_cfg read bytes with IOMMU for td guest is that:
(QemuFwCfgReadBytes@QemuFwCfgLib.c is the example)
1) Allocate DMA Access buffer
2) Map actual data buffer
3) start the transfer and wait for the transfer to complete
4) Free DMA Access buffer
5) Un-map actual data buffer
In step 1/2, Private memories are allocated, converted to shared memories.
In Step 4/5 the shared memories are converted to private memories and
accepted again. The final step is to free the pages.
This is time-consuming and impacts td guest's boot perf (both direct boot
and grub boot) badly.
In a typical grub boot, there are about 5000 calls of page allocation and
private/share conversion. Most of page size is less than 32KB.
This patch allocates a memory region and initializes it into pieces of
memory with different sizes. A piece of such memory consists of 2 parts:
the first page is of private memory, and the other pages are shared
memory. This is to meet the layout of common buffer.
When allocating bounce buffer in IoMmuMap(), IoMmuAllocateBounceBuffer()
is called to allocate the buffer. Accordingly when freeing bounce buffer
in IoMmuUnmapWorker(), IoMmuFreeBounceBuffer() is called to free the
bounce buffer. CommonBuffer is allocated by IoMmuAllocateCommonBuffer
and accordingly freed by IoMmuFreeCommonBuffer.
This feature is tested in Intel TDX pre-production platform. It saves up
to hundreds of ms in a grub boot.
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>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Adds a reference to the new build instructions on the TianoCore wiki
that currently describe building with containers and Stuart.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Rely on CcProbe() to identify when running on TDX so that ACPI tables
can be retrieved differently for Cloud Hypervisor. Instead of relying on
the PVH structure to find the RSDP pointer, the tables are individually
passed through the HOB.
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>
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>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4186
Commit 079a58276b ("OvmfPkg/AmdSev/SecretPei: Mark SEV launch secret
area as reserved") marked the launch secret area itself (1 page) as
reserved so the guest OS can use it during the lifetime of the OS.
However, the address and size of the secret area held in the
CONFIDENTIAL_COMPUTING_SECRET_LOCATION struct are declared as STATIC in
OVMF (in AmdSev/SecretDxe); therefore there's no guarantee that it will
not be written over by OS data.
Fix this by allocating the memory for the
CONFIDENTIAL_COMPUTING_SECRET_LOCATION struct with the
EfiACPIReclaimMemory memory type to ensure the guest OS will not reuse
this memory.
Fixes: 079a58276b ("OvmfPkg/AmdSev/SecretPei: Mark SEV launch secret ...")
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
When running under SEV-ES, a page of shared memory is allocated for the
GHCB during the SEC phase at address 0x809000. This page of memory is
eventually passed to the OS as EfiConventionalMemory. When running
SEV-SNP, this page is not PVALIDATE'd in the RMP table, meaning that if
the guest OS tries to access the page, it will think that the host has
voilated the security guarantees and will likely crash.
This patch validates this page immediately after EDK2 switches to using
the GHCB page allocated for the PEI phase.
This was tested by writing a UEFI application that reads to and writes
from one byte of each page of memory and checks to see if a #VC
exception is generated indicating that the page was not validated.
Fixes: 6995a1b79b ("OvmfPkg: Create a GHCB page for use during Sec phase")
Signed-off-by: Adam Dunlap <acdunlap@google.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4179
According to UEFI Spec 2.10 it is supposed to return the mapping from PCR
index to CC MR index:
//
// In the current version, we use the below mapping for TDX:
//
// TPM PCR Index | CC Measurement Register Index | TDX-measurement register
// -----------------------------------------------------------------------
// 0 | 0 | MRTD
// 1, 7 | 1 | RTMR[0]
// 2~6 | 2 | RTMR[1]
// 8~15 | 3 | RTMR[2]
In the current implementation TdMapPcrToMrIndex returns the index of RTMR,
not the MR index.
After fix the spec unconsistent, other related codes are updated
accordingly.
1) The index of event log uses the input MrIndex.
2) MrIndex is decreated by 1 before it is sent for RTMR extending.
Cc: Erdem Aktas <erdemaktas@google.com> [ruleof2]
Cc: James Bottomley <jejb@linux.ibm.com> [jejb]
Cc: Jiewen Yao <jiewen.yao@intel.com> [jyao1]
Cc: Tom Lendacky <thomas.lendacky@amd.com> [tlendacky]
Cc: Arti Gupta <ARGU@microsoft.com>
Reported-by: Arti Gupta <ARGU@microsoft.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4184
According to the Uefi spec 2.10 Section 38.2.2.
EFI_CC_MEASUREMENT_PROTOCOL.GetCapability, the minor version of
StructureVersion and ProtocolVersion should be 0.
Cc: Erdem Aktas <erdemaktas@google.com> [ruleof2]
Cc: James Bottomley <jejb@linux.ibm.com> [jejb]
Cc: Jiewen Yao <jiewen.yao@intel.com> [jyao1]
Cc: Tom Lendacky <thomas.lendacky@amd.com> [tlendacky]
Cc: Arti Gupta <ARGU@microsoft.com>
Reported-by: Arti Gupta <ARGU@microsoft.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Remove global variables, store the state in PlatformInfoHob instead.
Probing for fw_cfg happens on first use, at library initialization
time the Hob might not be present yet.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Move the code to a new QemuFwCfgProbe() function. Use direct Io*() calls
instead of indirect QemuFwCfg*() calls to make sure we don't get
recursive calls. Also simplify CC guest detection.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
This variant does not use global variables.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Use PlatformInfoHob->FeatureControlValue instead.
OnMpServicesAvailable() will find PlatformInfoHob using
GetFirstGuidHob() and pass a pointer to the WriteFeatureControl
callback.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable. Let
BuildPlatformInfoHob() allocate and return PlatformInfoHob instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in S3Verification() and
Q35BoardVerification() functions. Pass a pointer to the PlatformInfoHob
instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in NoexecDxeInitialization()
function. Pass a pointer to the PlatformInfoHob instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in MemTypeInfoInitialization()
function. Pass a pointer to the PlatformInfoHob instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in PublishPeiMemory()
and GetPeiMemoryCap() functions. Pass a pointer to the PlatformInfoHob
instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in
Q35TsegMbytesInitialization() and
Q35SmramAtDefaultSmbaseInitialization() ) functions.
Pass a pointer to the PlatformInfoHob instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in PeiFvInitialization()
function. Pass a pointer to the PlatformInfoHob instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Stop using the mPlatformInfoHob global variable in AmdSevInitialize()
and AmdSevEsInitialize() functions. Pass a pointer to the
PlatformInfoHob instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Instead of using hard-coded strings ("0.0.0" for BiosVersion etc)
which is mostly useless read the PCDs (PcdFirmwareVendor,
PcdFirmwareVersionString and PcdFirmwareReleaseDateString) and
build the string table dynamuically at runtime.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>