Re: [RFC PATCH v2 20/44] i386/tdx: Parse tdx metadata and store the result into TdxGuestState

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux