In QEMU commit range 4abf70a661a5..69699f3055a5 (later fixed up in QEMU
commit 4318432ccd3f), Phil implemented a QEMU facility for exposing the
host-side TLS cipher suite configuration to OVMF. The purpose is to
control the permitted ciphers in the guest's UEFI HTTPS boot. This
complements the forwarding of the host-side crypto policy from the host to
the guest -- the other facet was the set of CA certificates (for which
p11-kit patches had been upstreamed, on the host side).
Mention the new command line options in "OvmfPkg/README".
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Gary Lin <glin@suse.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2852
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Gary Lin <glin@suse.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200922091827.12617-1-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Updates the DSC's for Ovmf based platforms to add a RngLib that uses the
TimerLib. This is due to a later change that adds TimerLib as a dependency
for OpenSSL. The TimerLib based RngLib mimics the behavior of OpenSSL
previously and it is recommended to switch to a better source of
entropy than the system's performance counter.
Ref: https://github.com/tianocore/edk2/pull/845
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Matthew Carlson <matthewfcarlson@gmail.com>
There is a DEBUG warning printout in VirtioMmioDeviceLib if the current
device's VendorID does not match the traditional 16-bit Red Hat PCIe
vendor ID used with virtio-pci. The virtio-mmio vendor ID is 32-bit and
has no connection to the PCIe registry.
Most specifically, this causes a bunch of noise when booting an AArch64
QEMU platform, since QEMU's virtio-mmio implementation used 'QEMU' as
the vendor ID:
VirtioMmioInit: Warning:
The VendorId (0x554D4551) does not match the VirtIo VendorId (0x1AF4).
Drop the warning message.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Leif Lindholm <leif@nuviainc.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
The "virsh setvcpus" (plural) command may hot-plug several VCPUs in quick
succession -- it means a series of "device_add" QEMU monitor commands,
back-to-back.
If a "device_add" occurs *just after* ACPI raises the broadcast SMI, then:
- the CPU_FOREACH() loop in QEMU's ich9_apm_ctrl_changed() cannot make the
SMI pending for the new CPU -- at that time, the new CPU doesn't even
exist yet,
- OVMF will find the new CPU however (in the CPU hotplug register block),
in QemuCpuhpCollectApicIds().
As a result, when the firmware sends an INIT-SIPI-SIPI to the new CPU in
SmbaseRelocate(), expecting it to boot into SMM (due to the pending SMI),
the new CPU instead boots straight into the post-RSM (normal mode) "pen",
skipping its initial SMI handler.
The CPU halts nicely in the pen, but its SMBASE is never relocated, and
the SMRAM message exchange with the BSP falls apart -- the BSP gets stuck
in the following loop:
//
// Wait until the hot-added CPU is just about to execute RSM.
//
while (Context->AboutToLeaveSmm == 0) {
CpuPause ();
}
because the new CPU's initial SMI handler never sets the flag to nonzero.
Fix this by sending a directed SMI to the new CPU just before sending it
the INIT-SIPI-SIPI. The various scenarios are documented in the code --
the cases affected by the patch are documented under point (2).
Note that this is not considered a security patch, as for a malicious
guest OS, the issue is not exploitable -- the symptom is a hang on the
BSP, in the above-noted loop in SmbaseRelocate(). Instead, the patch fixes
behavior for a benign guest OS.
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Fixes: 51a6fb4118
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2929
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200826222129.25798-3-lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
The "virsh setvcpus" (plural) command may hot-plug several VCPUs in quick
succession -- it means a series of "device_add" QEMU monitor commands,
back-to-back.
If a "device_add" occurs *just before* ACPI raises the broadcast SMI,
then:
- OVMF processes the hot-added CPU well.
- However, QEMU's post-SMI ACPI loop -- which clears the pending events
for the hot-added CPUs that were collected before raising the SMI -- is
unaware of the stray CPU. Thus, the pending event is not cleared for it.
As a result of the stuck event, at the next hot-plug, OVMF tries to re-add
(relocate for the 2nd time) the already-known CPU. At that time, the AP is
already in the normal edk2 SMM busy-wait however, so it doesn't respond to
the exchange that the BSP intends to do in SmbaseRelocate(). Thus the VM
gets stuck in SMM.
(Because of the above symptom, this is not considered a security patch; it
doesn't seem exploitable by a malicious guest OS.)
In CpuHotplugMmi(), skip the supposedly hot-added CPU if it's already
known. The post-SMI ACPI loop will clear the pending event for it this
time.
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Fixes: bc498ac4ca
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2929
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200826222129.25798-2-lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
OvmfPkg is the package, so while there are files to build bhyve
separately, they shouldn't have 'Pkg' in the name.
Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Peter Grehan <grehan@freebsd.org>
Message-Id: <20200818021035.6479-1-rebecca@bsdio.com>
Reviewed-by: Peter Grehan <grehan@freebsd.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
The ICH9_LPC_SMI_F_BROADCAST and ICH9_LPC_SMI_F_CPU_HOTPLUG feature flags
cause QEMU to behave as follows:
BROADCAST CPU_HOTPLUG use case / behavior
--------- ----------- ------------------------------------------------
clear clear OVMF built without SMM_REQUIRE; or very old OVMF
(from before commit a316d7ac91 / 2017-02-07).
QEMU permits CPU hotplug operations, and does
not cause the OS to inject an SMI upon hotplug.
Firmware is not expected to be aware of hotplug
events.
clear set Invalid feature set; QEMU rejects the feature
negotiation.
set clear OVMF after a316d7ac91 / 2017-02-07, built with
SMM_REQUIRE, but no support for CPU hotplug.
QEMU gracefully refuses hotplug operations.
set set OVMF after a316d7ac91 / 2017-02-07, built with
SMM_REQUIRE, and supporting CPU hotplug. QEMU
permits CPU hotplug operations, and causes the
OS to inject an SMI upon hotplug. Firmware is
expected to deal with hotplug events.
Negotiate ICH9_LPC_SMI_F_CPU_HOTPLUG -- but only if SEV is disabled, as
OvmfPkg/CpuHotplugSmm can't deal with SEV yet.
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Liran Alon <liran.alon@oracle.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200714184305.9814-1-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
After having transitioned from UEFI to the OS, the OS will need to boot
the APs. For an SEV-ES guest, the APs will have been parked by UEFI using
GHCB pages allocated by UEFI. The hypervisor will write to the GHCB
SW_EXITINFO2 field of the GHCB when the AP is booted. As a result, the
GHCB pages must be marked reserved so that the OS does not attempt to use
them and experience memory corruption because of the hypervisor write.
Change the GHCB allocation from the default boot services memory to
reserved memory.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
A hypervisor is not allowed to update an SEV-ES guest's register state,
so when booting an SEV-ES guest AP, the hypervisor is not allowed to
set the RIP to the guest requested value. Instead an SEV-ES AP must be
re-directed from within the guest to the actual requested staring location
as specified in the INIT-SIPI-SIPI sequence.
Use the SEV-ES work area for the reset vector code that contains support
to jump to the desired RIP location after having been started. This is
required for only the very first AP reset.
This new OVMF source file, ResetVectorVtf0.asm, is used in place of the
original file through the use of the include path order set in
OvmfPkg/ResetVector/ResetVector.inf under "[BuildOptions]".
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
The flash detection routine will attempt to determine how the flash
device behaves (e.g. ROM, RAM, Flash). But when SEV-ES is enabled and
the flash device behaves as a ROM device (meaning it is marked read-only
by the hypervisor), this check may result in an infinite nested page fault
because of the attempted write. Since the instruction cannot be emulated
when SEV-ES is enabled, the RIP is never advanced, resulting in repeated
nested page faults.
When SEV-ES is enabled, exit the flash detection early and assume that
the FD behaves as Flash. This will result in QemuFlashWrite() being called
to store EFI variables, which will also result in an infinite nested page
fault when the write is performed. In this case, update QemuFlashWrite()
to use the VMGEXIT MMIO write support to have the hypervisor perform the
write without having to emulate the instruction.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Currently, the OVMF code relies on the hypervisor to enable the cache
support on the processor in order to improve the boot speed. However,
with SEV-ES, the hypervisor is not allowed to change the CR0 register
to enable caching.
Update the OVMF Sec support to enable caching in order to improve the
boot speed when running as an SEV-ES guest.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
An SEV-ES guest will generate a #VC exception when it encounters a
non-automatic exit (NAE) event. It is expected that the #VC exception
handler will communicate with the hypervisor using the GHCB to handle
the NAE event.
NAE events can occur during the Sec phase, so initialize exception
handling early in the OVMF Sec support.
Before establishing the exception handling, validate that the supported
version of the SEV-ES protocol in OVMF is supported by the hypervisor.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
During BSP startup, the reset vector code will issue a CPUID instruction
while in 32-bit mode. When running as an SEV-ES guest, this will trigger
a #VC exception.
Add exception handling support to the early reset vector code to catch
these exceptions. Also, since the guest is in 32-bit mode at this point,
writes to the GHCB will be encrypted and thus not able to be read by the
hypervisor, so use the GHCB CPUID request/response protocol to obtain the
requested CPUID function values and provide these to the guest.
The exception handling support is active during the SEV check and uses the
OVMF temporary RAM space for a stack. After the SEV check is complete, the
exception handling support is removed and the stack pointer cleared.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Protect the SEV-ES work area memory used by an SEV-ES guest.
Regarding the lifecycle of the SEV-ES memory area:
PcdSevEsWorkArea
(a) when and how it is initialized after first boot of the VM
If SEV-ES is enabled, the SEV-ES area is initialized during
the SEC phase [OvmfPkg/ResetVector/Ia32/PageTables64.asm].
(b) how it is protected from memory allocations during DXE
If SEV-ES is enabled, then InitializeRamRegions()
[OvmfPkg/PlatformPei/MemDetect.c] protects the ranges with either
an AcpiNVS (S3 enabled) or BootServicesData (S3 disabled) memory
allocation HOB, in PEI.
(c) how it is protected from the OS
If S3 is enabled, then (b) reserves it from the OS too.
If S3 is disabled, then the range needs no protection.
(d) how it is accessed on the S3 resume path
It is rewritten same as in (a), which is fine because (b) reserved it.
(e) how it is accessed on the warm reset path
It is rewritten same as in (a).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Reserve a fixed area of memory for SEV-ES use and set a fixed PCD,
PcdSevEsWorkAreaBase, to this value.
This area will be used by SEV-ES support for two purposes:
1. Communicating the SEV-ES status during BSP boot to SEC:
Using a byte of memory from the page, the BSP reset vector code can
communicate the SEV-ES status to SEC for use before exception
handling can be enabled in SEC. After SEC, this field is no longer
valid and the standard way of determine if SEV-ES is active should
be used.
2. Establishing an area of memory for AP boot support:
A hypervisor is not allowed to update an SEV-ES guest's register
state, so when booting an SEV-ES guest AP, the hypervisor is not
allowed to set the RIP to the guest requested value. Instead an
SEV-ES AP must be re-directed from within the guest to the actual
requested staring location as specified in the INIT-SIPI-SIPI
sequence.
Use this memory for reset vector code that can be programmed to have
the AP jump to the desired RIP location after starting the AP. This
is required for only the very first AP reset.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
The SEV support will clear the C-bit from non-RAM areas. The early GDT
lives in a non-RAM area, so when an exception occurs (like a #VC) the GDT
will be read as un-encrypted even though it is encrypted. This will result
in a failure to be able to handle the exception.
Move the GDT into RAM so it can be accessed without error when running as
an SEV-ES guest.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Allocate memory for the GHCB pages and the per-CPU variable pages during
SEV initialization for use during Pei and Dxe phases. The GHCB page(s)
must be shared pages, so clear the encryption mask from the current page
table entries. Upon successful allocation, set the GHCB PCDs (PcdGhcbBase
and PcdGhcbSize).
The per-CPU variable page needs to be unique per AP. Using the page after
the GHCB ensures that it is unique per AP. Only the GHCB page is marked as
shared, keeping the per-CPU variable page encyrpted. The same logic is
used in DXE using CreateIdentityMappingPageTables() before switching to
the DXE pagetables.
The GHCB pages (one per vCPU) will be used by the PEI and DXE #VC
exception handlers. The #VC exception handler will fill in the necessary
fields of the GHCB and exit to the hypervisor using the VMGEXIT
instruction. The hypervisor then accesses the GHCB associated with the
vCPU in order to perform the requested function.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Protect the memory used by an SEV-ES guest when S3 is supported. This
includes the page table used to break down the 2MB page that contains
the GHCB so that it can be marked un-encrypted, as well as the GHCB
area.
Regarding the lifecycle of the GHCB-related memory areas:
PcdOvmfSecGhcbPageTableBase
PcdOvmfSecGhcbBase
(a) when and how it is initialized after first boot of the VM
If SEV-ES is enabled, the GHCB-related areas are initialized during
the SEC phase [OvmfPkg/ResetVector/Ia32/PageTables64.asm].
(b) how it is protected from memory allocations during DXE
If S3 and SEV-ES are enabled, then InitializeRamRegions()
[OvmfPkg/PlatformPei/MemDetect.c] protects the ranges with an AcpiNVS
memory allocation HOB, in PEI.
If S3 is disabled, then these ranges are not protected. DXE's own page
tables are first built while still in PEI (see HandOffToDxeCore()
[MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c]). Those tables are
located in permanent PEI memory. After CR3 is switched over to them
(which occurs before jumping to the DXE core entry point), we don't have
to preserve PcdOvmfSecGhcbPageTableBase. PEI switches to GHCB pages in
permanent PEI memory and DXE will use these PEI GHCB pages, so we don't
have to preserve PcdOvmfSecGhcbBase.
(c) how it is protected from the OS
If S3 is enabled, then (b) reserves it from the OS too.
If S3 is disabled, then the range needs no protection.
(d) how it is accessed on the S3 resume path
It is rewritten same as in (a), which is fine because (b) reserved it.
(e) how it is accessed on the warm reset path
It is rewritten same as in (a).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
A GHCB page is needed during the Sec phase, so this new page must be
created. Since the #VC exception handler routines assume that a per-CPU
variable area is immediately after the GHCB, this per-CPU variable area
must also be created. Since the GHCB must be marked as an un-encrypted,
or shared, page, an additional pagetable page is required to break down
the 2MB region where the GHCB page lives into 4K pagetable entries.
Create a new entry in the OVMF memory layout for the new page table
page and for the SEC GHCB and per-CPU variable pages. After breaking down
the 2MB page, update the GHCB page table entry to remove the encryption
mask.
The GHCB page will be used by the SEC #VC exception handler. The #VC
exception handler will fill in the necessary fields of the GHCB and exit
to the hypervisor using the VMGEXIT instruction. The hypervisor then
accesses the GHCB in order to perform the requested function.
Four new fixed PCDs are needed to support the SEC GHCB page:
- PcdOvmfSecGhcbBase UINT32 value that is the base address of the
GHCB used during the SEC phase.
- PcdOvmfSecGhcbSize UINT32 value that is the size, in bytes, of the
GHCB area used during the SEC phase.
- PcdOvmfSecGhcbPageTableBase UINT32 value that is address of a page
table page used to break down the 2MB page into
512 4K pages.
- PcdOvmfSecGhcbPageTableSize UINT32 value that is the size, in bytes,
of the page table page.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
When SEV-ES is enabled, then SEV is also enabled. Add support to the SEV
initialization function to also check for SEV-ES being enabled, and if
enabled, set the SEV-ES enabled PCD (PcdSevEsIsEnabled).
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Create a function that can be used to determine if the VM is running
as an SEV-ES guest.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a DR7 read or write intercept generates a #VC exception.
The #VC handler must provide special support to the guest for this. On
a DR7 write, the #VC handler must cache the value and issue a VMGEXIT
to notify the hypervisor of the write. However, the #VC handler must
not actually set the value of the DR7 register. On a DR7 read, the #VC
handler must return the cached value of the DR7 register to the guest.
VMGEXIT is not invoked for a DR7 register read.
The caching of the DR7 values will make use of the per-CPU data pages
that are allocated along with the GHCB pages. The per-CPU page for a
vCPU is the page that immediately follows the vCPU's GHCB page. Since
each GHCB page is unique for a vCPU, the page that follows becomes
unique for that vCPU. The SEC phase will reserves an area of memory for
a single GHCB and per-CPU page for use by the BSP. After transitioning
to the PEI phase, new GHCB and per-CPU pages are allocated for the BSP
and all APs.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a MWAIT/MWAITX intercept generates a #VC exception.
VMGEXIT must be used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a MONITOR/MONITORX intercept generates a #VC exception.
VMGEXIT must be used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a RDTSCP intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a VMMCALL intercept generates a #VC exception. VMGEXIT must
be used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a INVD intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a RDPMC intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a RDTSC intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a WBINVD intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a NPF intercept for an NPT entry with a reserved bit set
generates a #VC exception. This condition is assumed to be an MMIO access.
VMGEXIT must be used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support a NPF NAE
event for MMIO. Parse the instruction that generated the #VC exception,
setting the required register values in the GHCB and creating the proper
SW_EXIT_INFO1, SW_EXITINFO2 and SW_SCRATCH values in the GHCB.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a MSR_PROT intercept generates a #VC exception. VMGEXIT must
be used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support an MSR_PROT
NAE event. Parse the instruction that generated the #VC exception to
determine whether it is RDMSR or WRMSR, setting the required register
register values in the GHCB and creating the proper SW_EXIT_INFO1 value in
the GHCB.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a CPUID intercept generates a #VC exception. VMGEXIT must be
used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support a CPUID NAE
event. Additionally, CPUID 0x0000_000d (CPUID_EXTENDED_STATE) requires
XCR0 to be supplied in the GHCB, so add support to issue the XGETBV
instruction.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Add support to the #VC exception handler to handle string IO. This
requires expanding the IO instruction parsing to recognize string based
IO instructions as well as preparing an un-encrypted buffer to be used
to transfer (either to or from the guest) the string contents for the IO
operation. The SW_EXITINFO2 and SW_SCRATCH fields of the GHCB are set
appropriately for the operation. Multiple VMGEXIT invocations may be
needed to complete the string IO operation.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Under SEV-ES, a IOIO_PROT intercept generates a #VC exception. VMGEXIT
must be used to allow the hypervisor to handle this intercept.
Add support to construct the required GHCB values to support a IOIO_PROT
NAE event. Parse the instruction that generated the #VC exception,
setting the required register values in the GHCB and creating the proper
SW_EXITINFO1 value in the GHCB.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
The base VmgExitLib library provides a default limited interface. As it
does not provide full support, create an OVMF version of this library to
begin the process of providing full support of SEV-ES within OVMF.
SEV-ES support is only provided for X64 builds, so only OvmfPkgX64.dsc is
updated to make use of the OvmfPkg version of the library.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198
Various CpuExceptionHandlerLib libraries will updated to use the new
VmgExitLib library. To prevent any build breakage, update the OvmfPkg
DSC files that use a form of the CpuExceptionHandlerLib library to
include the VmgExitLib library.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien@xen.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Sean reports that having two DEC files under OvmfPkg violates the DEC
spec:
> An EDK II Package (directory) is a directory that contains an EDK II
> package declaration (DEC) file. Only one DEC file is permitted per
> directory. EDK II Packages cannot be nested within other EDK II
> Packages.
This issue originates from commit 656419f922 ("Add BhyvePkg, to support
the bhyve hypervisor", 2020-07-31).
Remedy the problem as follows. (Note that these steps are not split to
multiple patches in order to keep Bhyve buildable across the transition.)
(1) Delete "OvmfPkg/Bhyve/BhyvePkg.dec".
(2) Point the [Packages] sections of the Bhyve-specific AcpiPlatformDxe,
BhyveRfbDxe, and BhyveFwCtlLib INF files to "OvmfPkg.dec".
(3) Migrate the artifacts that "BhyvePkg.dec" used to have on top of
"OvmfPkg.dec" as follows:
(3a) Merge the copyright notices from Rebecca Cran and Pluribus Networks
into "OvmfPkg.dec".
(3b) Merge the "BhyveFwCtlLib" class header definition into "OvmfPkg.dec".
(3c) Merge value 0x2F8 for the fixed PcdDebugIoPort into
"BhyvePkgX64.dsc".
(4) Unnest the the Include/Library/ and Library/ subtrees from under
OvmfPkg/Bhyve to the corresponding, preexistent subtrees in OvmfPkg.
The goal is to keep the [Includes] section in the "OvmfPkg.dec" file
unchanged, plus simplify references in "BhyvePkgX64.dsc". Non-library
modules remain under "OvmfPkg/Bhyve/".
(4a) The BhyveFwCtlLib class header, and sole instance, are already
uniquely named, so their movements need not involve file renames.
(4b) Rename the Bhyve-specific PlatformBootManagerLib instance to
PlatformBootManagerLibBhyve, in additon to moving it, for
distinguishing it from OvmfPkg's preexistent lib instance. Apply the
name change to all three of the lib instance directory name, the INF
file, and the BASE_NAME define in the INF file.
(4c) Update lib class resolutions in "BhyvePkgX64.dsc" accordingly.
(5) Replace the "ACPI table storage" FILE_GUID in
"OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf" with a new GUID, and
open-code the "ACPI table storage" GUID in the "ACPITABLE" FDF rule
instead, replacing $(NAMED_GUID). This step is necessary because CI
requires unique FILE_GUIDs over all INF files, and OVMF's original
"AcpiTables.inf" already uses the "ACPI table storage" GUID as
FILE_GUID.
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Rebecca Cran <rebecca@bsdio.com>
Cc: Sean Brogan <spbrogan@outlook.com>
Fixes: 656419f922
Reported-by: Sean Brogan <spbrogan@outlook.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200801155024.16439-1-lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Rebecca Cran <rebecca@bsdio.com>
BhyvePkg supports the bhyve hypervisor, which is a hypervisor/virtual
machine manager available on FreeBSD, macOS and Illumos.
Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
Message-Id: <20200713054131.479627-2-rebecca@bsdio.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Add configuration IgnoreFiles for package config files.
So users can rely on this to skip license conflict for
some generated files.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Shenglei Zhang <shenglei.zhang@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This is the second part of LsiScsiPassThru(). LsiScsiProcessRequest() is
added to translate the SCSI Request Packet into the LSI 53C895A
commands. This function utilizes the so-called Script buffer to transmit
a series of commands to the chip and then polls the DMA Status (DSTAT)
register until the Scripts Interrupt Instruction Received (SIR) bit
sets. Once the script is done, the SCSI Request Packet will be modified
to reflect the result of the script. The Cumulative SCSI Byte Count
(CSBC) register is fetched before and after the script to calculate the
transferred bytes and update InTransferLength/OutTransferLength if
necessary.
v3:
- Set DStat, SIst0, and SIst1 to 0 before using them
- Amend the if statements for the DMA data instruction and add the
assertions for the data direction
- Also set SenseDataLength to 0 on the error path
- Fix typos and amend comments
- Amend the error handling of the calculation of transferred bytes
v2:
- Use the BITx macros for the most of LSI_* constants
- Fix a typo: contorller => controller
- Add SeaBIOS lsi-scsi driver as one of the references of the script
- Cast the result of sizeof to UINT32 for the instructions of the
script
- Drop the backslashes
- Replace LSI_SCSI_DMA_ADDR_LOW with LSI_SCSI_DMA_ADDR since we
already removed DUAL_ADDRESS_CYCLE
- Add more comments for the script
- Fix the check of the script size at the end of the script
- Always set SenseDataLength to 0 to avoid the caller to access
SenseData
- Improve the error handling in LsiScsiProcessRequest()
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Message-Id: <20200717061130.8881-11-glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
This is the first part of LsiScsiPassThru(). Before processing the SCSI
Request packet, we have to make sure whether the packet is valid or not.
v2: Make LsiScsiPassThru() return EFI_UNSUPPORTED since this function is
half-implemented
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200717061130.8881-10-glin@suse.com>
Map DMA buffer and perpare for the implementation of LsiScsiPassThru().
v2:
- Replace 0x10000 with SIZE_64KB macro for the DMA buffer data array
- Remove DUAL_ADDRESS_CYCLE from PciIo since we don't really need
64-bit DMA address
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200717061130.8881-9-glin@suse.com>
Open PciIo protocol and use it to initialize the device. The
initialization of LSI 53C895A is simple: just set the SRST bit in
Interrupt Status Zero register to reset the device.
v2:
- Use the BITx macros for the bit constants
- Add the closing of PciIo protocol in LsiScsiControllerStop()
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Message-Id: <20200717061130.8881-8-glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Implement LsiScsiGetNextTargetLun(), LsiScsiBuildDevicePath(),
LsiScsiGetTargetLun(), and LsiScsiGetNextTarget() to report Targets and
LUNs and build the device path.
This commit also introduces two PCD value: PcdLsiScsiMaxTargetLimit and
PcdLsiScsiMaxLunLimit as the limits for Targets and LUNs.
v3:
- Update the range of LUN in the assertioin
- Squash the spurious newline into the previous commit
v2:
- Zero out (*Target) in LsiScsiGetTargetLun()
- Use CopyMem() instead of the one-byte shortcut to copy target from
ScsiDevicePath->Pun
- Add asserts for PcdLsiScsiMaxTargetLimit and PcdLsiScsiMaxLunLimit
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Message-Id: <20200717061130.8881-7-glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Partially implement LsiScsiControllerStart() and LsiScsiControllerStop()
to insert the scaffolding of EXT_SCSI_PASS_THRU functions.
v3: Squash the newline below the declaration of LSI_SCSI_FROM_PASS_THRU
v2: Remove the closing of PciIo protocol from LsiScsiControllerStop().
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200717061130.8881-6-glin@suse.com>
Implement LsiScsiControllerSupported() to probe the PCI ID and look for
LSI 53C895A.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200717061130.8881-5-glin@suse.com>