[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH v2 20/44] i386/tdx: Parse tdx metadata and store the resu
|
From: |
Laszlo Ersek |
|
Subject: |
Re: [RFC PATCH v2 20/44] i386/tdx: Parse tdx metadata and store the result into TdxGuestState |
|
Date: |
Tue, 11 Jan 2022 09:19:53 +0100 |
On 01/10/22 13:09, Xiaoyao Li wrote:
> On 1/10/2022 7:01 PM, Gerd Hoffmann wrote:
>>>> If you go without pflash, then you likely will not have a
>>>> standards-conformant UEFI variable store. (Unless you reimplement
>>>> the variable arch protocols in edk2 on top of something else than
>>>> the Fault Tolerant Write and Firmware Volume Block protocols.)
>>>> Whether a conformant UEFI varstore matters to you (or to TDX in
>>>> general) is something I can't comment on.
>>>
>>> Thanks for your reply! Laszlo
>>>
>>> regarding "standards-conformant UEFI variable store", I guess you
>>> mean the
>>> change to UEFI non-volatile variables needs to be synced back to the
>>> OVMF_VARS.fd file. right?
>>
>> Yes. UEFI variables are expected to be persistent, and syncing to
>> OVMF_VARS.fd handles that.
>
> Further question.
>
> Is it achieved via read-only memslot that when UEFI variable gets
> changed, it exits to QEMU with KVM_EXIT_MMIO due to read-only memslot
> so QEMU can sync the change to OVMF_VAR.fd?
Yes.
When the flash device is in "romd_mode", that's when a readonly KVM
memslot is used. In this case, the guest can read and execute from the
memory region in question, only writes trap to QEMU. Such a write
(WRITE_BYTE_CMD) is what the guest's flash driver uses to flip the flash
device out of "romd_mode".
When the flash device is not in "romd_mode", then no KVM memslot is used
at all, and both reads and writes trap to QEMU. Once the flash
programming is done, the guest's flash driver issues a particular write
command (READ_ARRAY_CMD) that flips the device back to "romd_mode" (and
then the readonly KVM memslot is re-established).
Here's a rough call tree (for the non-SMM case, updating a
non-authenticated non-volatile variable):
VariableServiceSetVariable()
[MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c]
UpdateVariable()
[MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c]
UpdateVariableStore()
[MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c]
FvbProtocolWrite()
[OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c]
QemuFlashWrite()
[OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c]
QemuFlashPtrWrite (WRITE_BYTE_CMD /* 0x10 */)
QEMU:
pflash_write()
[hw/block/pflash_cfi01.c]
(wcycle == 0)
memory_region_rom_device_set_romd(false) [softmmu/memory.c]
...
kvm_region_del() [accel/kvm/kvm-all.c]
kvm_set_phys_mem(false) [accel/kvm/kvm-all.c]
/* unregister the slot */
/* Single Byte Program */
wcycle++
QemuFlashPtrWrite (Buffer[Loop])
QEMU:
pflash_write()
[hw/block/pflash_cfi01.c]
(wcycle == 1)
/* Single Byte Program */
pflash_data_write()
[hw/block/pflash_cfi01.c]
pflash_update()
[hw/block/pflash_cfi01.c]
blk_pwrite()
[block/block-backend.c]
wcycle = 0
QemuFlashPtrWrite (READ_ARRAY_CMD /* 0xff */)
QEMU:
pflash_write()
[hw/block/pflash_cfi01.c]
(wcycle == 0)
memory_region_rom_device_set_romd(false) [softmmu/memory.c]
/* no actual change */
/* Read Array */
memory_region_rom_device_set_romd(true) [softmmu/memory.c]
kvm_region_add() [accel/kvm/kvm-all.c]
kvm_set_phys_mem(true) [accel/kvm/kvm-all.c]
/* register the new slot */
kvm_mem_flags() [accel/kvm/kvm-all.c]
... memory_region_is_romd() ...
[include/exec/memory.h]
flags |= KVM_MEM_READONLY
Thanks
Laszlo