public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] The OVMF packages can not work properly when it was compiled with "-D SECURE_BOOT_ENABLE=TRUE"
@ 2024-07-10 13:24 wojiaohanliyang
  2024-07-11  6:42 ` wojiaohanliyang
  0 siblings, 1 reply; 2+ messages in thread
From: wojiaohanliyang @ 2024-07-10 13:24 UTC (permalink / raw)
  To: devel

[-- Attachment #1: Type: text/plain, Size: 4703 bytes --]

When I compile the OVMF packages with "-D SECURE_BOOT_ENABLE=TRUE -D DEBUG_ON_SERIAL_PORT=TRUE", I found the OVMF can not work properly.

*First, I boot a Qemu VM with only OVMF_CODE.fd but not OVMF_VARS.fd:*

a. For Non-encrypted VM, the guest hungs in OVMF with the following assert message.

----------------------------------------------
Reserved variable store memory: 0xBFD7C000; size: 528kb
NvVarStore FV headers were invalid.
ASSERT [PlatformPei] /dev/shm/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(932): ((BOOLEAN)(0==1))
----------------------------------------------

b. For SEV VM, the guest reset in the OVMF in an infinite loop.

----------------------------------------------
SecCoreStartupWithStack(0xFFFCC000, 0x820000)
Register PPI Notify: DCD0BE23-9586-40F4-B643-06522CED4EDE
......
Reserved variable store memory: 0xBFD7C000; size: 528kb
SecCoreStartupWithStack(0xFFFCC000, 0x820000)
Register PPI Notify: DCD0BE23-9586-40F4-B643-06522CED4EDE
......
Reserved variable store memory: 0xBFD7C000; size: 528kb
SecCoreStartupWithStack(0xFFFCC000, 0x820000)
Register PPI Notify: DCD0BE23-9586-40F4-B643-06522CED4EDE
......
Reserved variable store memory: 0xBFD7C000; size: 528kb
SecCoreStartupWithStack(0xFFFCC000, 0x820000)
......
......
----------------------------------------------

c. For SEV-ES VM, the guest hungs in OVMF with the following assert message.

----------------------------------------------
Reserved variable store memory: 0xBFD7C000; size: 528kb
Invalid MMIO opcode (AF)
ASSERT [SecMain] /dev/shm/edk2/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c(507): ((BOOLEAN)(0==1))
----------------------------------------------

*Then, I boot a Qemu VM with OVMF.fd (the OVMF_VARS.fd part is included in OVMF.fd):*

a. For SEV/SEV-ES VM, the guest hungs in OVMF with following dump messages.

----------------------------------------------
Loading driver at 0x000BDB92000 EntryPoint=0x000BDB95EF4 FaultTolerantWriteDxe.efi
InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF BDE01D98
ProtectUefiImageCommon - 0xBDE01040
- 0x00000000BDB92000 - 0x0000000000005B00
Ftw: FtwWorkSpaceLba - 0x40, WorkBlockSize  - 0x1000, FtwWorkSpaceBase - 0x0
Ftw: FtwSpareLba     - 0x42, SpareBlockSize - 0x1000
Ftw: NumberOfWorkBlock - 0x1, FtwWorkBlockLba - 0x40
Ftw: WorkSpaceLbaInSpare - 0x0, WorkSpaceBaseInSpare - 0x0
Ftw: Remaining work space size - FE0
!!!! X64 Exception Type - 0D(#GP - General Protection)  CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000
RIP  - 00000000BDB92459, CS  - 0000000000000038, RFLAGS - 0000000000010286
RAX  - 587E3201A019FB0C, RCX - 587E3200E238F994, RDX - 0000000000000001
RBX  - 00000000BDE10018, RSP - 00000000BFB79AD8, RBP - 0000000000000FE0
RSI  - 00000000BDE100A8, RDI - 00000000BDE10128
R8   - D4642A9DFB7C79BE, R9  - 00000000000003F8, R10 - 00000000BDB96602
R11  - 0000000000000002, R12 - 00000000BDE100A0, R13 - 0000000000000000
R14  - 0000000000000001, R15 - 00000000BFBA76C0
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - 0000000000000000, CR3 - 00000000BF801000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000BF5DC000 0000000000000047, LDTR - 0000000000000000
IDTR - 00000000BEF0C018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 00000000BFB79730
!!!! Find image based on IP(0xBDB92459) /dev/shm/edk2/Build/OvmfX64/DEBUG_GCC5/X64/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe/DEBUG/FaultTolerantWriteDxe.dll (ImageBase=00000000BDB92000, EntryPoint=00000000BDB95EF4) !!!!
----------------------------------------------

*Last, I boot a Qemu VM with OVMF_CODE.fd and OVMF_VARS.fd:*

a. For SEV/SEV-ES VM, the guest hungs in OVMF with the following assert message.

----------------------------------------------
Reserved variable store memory: 0xBFD7C000; size: 528kb
NvVarStore FV headers were invalid.
ASSERT [PlatformPei] /dev/shm/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(932): ((BOOLEAN)(0==1))
----------------------------------------------


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119885): https://edk2.groups.io/g/devel/message/119885
Mute This Topic: https://groups.io/mt/107157379/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



[-- Attachment #2: Type: text/html, Size: 7403 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [edk2-devel] The OVMF packages can not work properly when it was compiled with "-D SECURE_BOOT_ENABLE=TRUE"
  2024-07-10 13:24 [edk2-devel] The OVMF packages can not work properly when it was compiled with "-D SECURE_BOOT_ENABLE=TRUE" wojiaohanliyang
@ 2024-07-11  6:42 ` wojiaohanliyang
  0 siblings, 0 replies; 2+ messages in thread
From: wojiaohanliyang @ 2024-07-11  6:42 UTC (permalink / raw)
  To: wojiaohanliyang, devel

[-- Attachment #1: Type: text/plain, Size: 5351 bytes --]

The root cause of these issues are that the following patchset rename the function from TdxValidateCfv() to PlatformInitEmuVariableNvStore().

39596c41c8 OvmfPkg: Add build-flag SECURE_BOOT_FEATURE_ENABLED
3abaa281d3 OvmfPkg/TdxDxe: Set PcdEmuVariableNvStoreReserved
70165fa6e2 OvmfPkg/NvVarsFileLib: Shortcut ConnectNvVarsToFileSystem in secure-boot
ee91d9ef24 OvmfPkg: Reserve and init EmuVariableNvStore in Pei-less Startup
*58eb8517ad OvmfPkg/PlatformPei: Update ReserveEmuVariableNvStore*
*4f173db8b4 OvmfPkg/PlatformInitLib: Add functions for EmuVariableNvStore*
*0e72e8762a OvmfPkg/PeilessStartupLib: Delete TdxValidateCfv*
fb008dbe01 EmbeddedPkg: Add AllocateRuntimePages in PrePiMemoryAllocationLib
7cc7c52670 OvmfPkg: Set default Pci PCDs in Tdx guest
1b1c58ab32 OvmfPkg: Update CcProbeLib to DxeCcProbeLib
c4bc1a9498 OvmfPkg: Add SecPeiCcProbeLib

Before the patchset is merged, the TdxValidateCfv() is invoked only in Tdx guest. After the patchset is merged, the PlatformInitEmuVariableNvStore() becomes a common code and is invoked in any guest. The code path is as below.
PlatformPei/InitializePlatform()
-> ReserveEmuVarabileNvStore()
*-> PlatformInitEmuVariableNvStore() if 'SECURE_BOOT_ENABLE=TRUE'*
*-> PlatformValidateNvVarStore()*

The function PlatformValidateNvVarStore() will access the OvmfFlashNvStorage which is mapped in the address range specified by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000) and 'PcdFlashNvStorageVariableSize' (typically 0x40000). But the function PlatformValidateNvVarStore() doesn't consider any combination of OVMF files and Non-CoCo/CoCo guest.

*1.* *When we boot a Qemu VM with only OVMF_CODE.fd but not OVMF_VARS.fd,* the address range specified by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000) and '2 * PcdFlashNvStorageFtwSpareSize' (typically 0x84000) is mmio address range but without corresponding device.
a. If the VM is a non-encrypted VM, the 0x0 is returned when PlatformValidateNvVarStore() read from the mmio address range,  this will cause validation of OvmfFlashNvStorage to fail and trigger ASSERT (FALSE).
b. If the VM is a SEV VM, the PlatformValidateNvVarStore() calls IsZeroBuffer() which execute instruction scasX to check that first 16 bytes of the OvmfFlashNvStorage are all zeros. On Linux host side, KVM will inject #PF when it emulate scasX on MMIO address range, when VmEnter the guest, the guest will trigger shutdown event because the exception handler can't deal with #PF at this time.
c. If the VM is a SEV-ES VM, the PlatformValidateNvVarStore() calls IsZeroBuffer() which execute instruction scasX to check that first 16 bytes of the OvmfFlashNvStorage are all zeros. The instruction scasX will trigger #VC handler to handle MMIO NPF event, the #VC handler can't decode scasX and trigger ASSERT (FALSE).

*2. When we boot a Qemu VM with OVMF.fd ( the OVMF_VARS.fd part is included in OVMF.fd),* the address range specified by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000) and '2 * PcdFlashNvStorageFtwSpareSize' (typically 0x84000) is mmio address range and the KVM will mapping the mmio address range to system physical memory with read-only attribute in the NPT when guest read from this address range.
a. If the VM is a SEV/SEV-ES VM, the PlaformValidateNvVarStore() can return as expected, because at this time, the guest can direct read system physical memory for data in the mmio address range. But in this situation, PlatformValidateNvVarStore() only initialize the first part (this part is specified by 'PcdFlashNvStorageVariableSize' in length) of EmuVariableNvStore buffer, *the Fault Tolerant Write part of EmuVariableNvStore buffer isn't initialized at this time*. If the first part of EmuVariableNvStore is initilaized at here, then VariableRuntimeDxe will not initialize EmuVariableNvStore, and FaultTolerantWriteDxe will get garble data from Fault Tolerant Write part of EmuVariableNvStore, the FaultTolerantWriteDxe read data from the address specified by the garble data will cause invalid access and crash.

*3. When boot a Qemu VM with OVMF_CODE.fd and OVMF_VARS.fd,* the address range specified by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000) and '2 * PcdFlashNvStorageFtwSpareSize' (typically 0x84000) is mmio address range and the KVM will mapping the mmio address range to system physical memory with read-only attribute in the NPT when guest read from this address range.
a. If the VM is a SEV/SEV-ES VM, the PlatformValidateNvVarStore() invokes IsZeroBuffer() and find the first 16 bytes of the OvmfFlashNvStorage are not all zeros, and then trigger ASSERT (FALSE). In this situation, the OvmfFlashNvStorage is OVMF_VARS.fd,the OVMF_VARS.fd is plaintext on the host side, while at this time, the guest mapping these address range with C-bit (i.e. mapping as encrypted). The guest get garble data when it read the first 16 bytes of the OvmfFlashNvStorage,  the validation will fail.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119888): https://edk2.groups.io/g/devel/message/119888
Mute This Topic: https://groups.io/mt/107157379/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



[-- Attachment #2: Type: text/html, Size: 6615 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-07-11  6:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-10 13:24 [edk2-devel] The OVMF packages can not work properly when it was compiled with "-D SECURE_BOOT_ENABLE=TRUE" wojiaohanliyang
2024-07-11  6:42 ` wojiaohanliyang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox