[RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF

Xiaoyao Li posted 36 patches 3 years, 9 months ago
There is a newer version of this series
[RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Xiaoyao Li 3 years, 9 months ago
TDX VM needs to boot with Trust Domain Virtual Firmware (TDVF). Unlike
that OVMF is mapped as rom device, TDVF needs to be mapped as private
memory. This is because TDX architecture doesn't provide read-only
capability for VMM, and it doesn't support instruction emulation due
to guest memory and registers are not accessible for VMM.

On the other hand, OVMF can work as TDVF, which is usually configured
as pflash device in QEMU. To keep the same usage (QEMU parameter),
introduce ram_mode to pflash for TDVF. When it's creating a TDX VM,
ram_mode will be enabled automatically that map the firmware as RAM.

Note, this implies two things:
 1. TDVF (OVMF) is not read-only (write-protected).

 2. It doesn't support non-volatile UEFI variables as what pflash
    supports that the change to non-volatile UEFI variables won't get
    synced back to backend vars.fd file.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 hw/block/pflash_cfi01.c | 25 ++++++++++++++++++-------
 hw/i386/pc_sysfw.c      | 14 +++++++++++---
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 74c7190302bd..55e8bb2bd5ee 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -87,6 +87,7 @@ struct PFlashCFI01 {
     void *storage;
     VMChangeStateEntry *vmstate;
     bool old_multiple_chip_handling;
+    bool ram_mode;  /* if 1, the flash is mapped as RAM */
 };
 
 static int pflash_post_load(void *opaque, int version_id);
@@ -818,17 +819,24 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
 
     total_len = pfl->sector_len * pfl->nb_blocs;
 
-    memory_region_init_rom_device(
-        &pfl->mem, OBJECT(dev),
-        &pflash_cfi01_ops,
-        pfl,
-        pfl->name, total_len, errp);
+    if (pfl->ram_mode) {
+        memory_region_init_ram(&pfl->mem, OBJECT(dev),pfl->name, total_len, errp);
+    } else {
+        memory_region_init_rom_device(
+            &pfl->mem, OBJECT(dev),
+            &pflash_cfi01_ops,
+            pfl,
+            pfl->name, total_len, errp);
+    }
     if (*errp) {
         return;
     }
 
     pfl->storage = memory_region_get_ram_ptr(&pfl->mem);
-    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
+
+    if (!pfl->ram_mode) {
+        sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
+    }
 
     if (pfl->blk) {
         uint64_t perm;
@@ -879,7 +887,9 @@ static void pflash_cfi01_system_reset(DeviceState *dev)
      */
     pfl->cmd = 0x00;
     pfl->wcycle = 0;
-    memory_region_rom_device_set_romd(&pfl->mem, true);
+    if (!pfl->ram_mode) {
+        memory_region_rom_device_set_romd(&pfl->mem, true);
+    }
     /*
      * The WSM ready timer occurs at most 150ns after system reset.
      * This model deliberately ignores this delay.
@@ -924,6 +934,7 @@ static Property pflash_cfi01_properties[] = {
     DEFINE_PROP_STRING("name", PFlashCFI01, name),
     DEFINE_PROP_BOOL("old-multiple-chip-handling", PFlashCFI01,
                      old_multiple_chip_handling, false),
+    DEFINE_PROP_BOOL("ram-mode", PFlashCFI01, ram_mode, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 75b34d02cb4f..03c84b5aaa32 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -38,6 +38,7 @@
 #include "hw/block/flash.h"
 #include "sysemu/kvm.h"
 #include "sev.h"
+#include "kvm/tdx.h"
 
 #define FLASH_SECTOR_SIZE 4096
 
@@ -184,12 +185,19 @@ static void pc_system_flash_map(PCMachineState *pcms,
         total_size += size;
         qdev_prop_set_uint32(DEVICE(system_flash), "num-blocks",
                              size / FLASH_SECTOR_SIZE);
+        qdev_prop_set_bit(DEVICE(system_flash), "ram-mode", is_tdx_vm());
         sysbus_realize_and_unref(SYS_BUS_DEVICE(system_flash), &error_fatal);
-        sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0,
-                        0x100000000ULL - total_size);
+        flash_mem = pflash_cfi01_get_memory(system_flash);
+        if (is_tdx_vm()) {
+            memory_region_add_subregion(get_system_memory(),
+                                        0x100000000ULL - total_size,
+                                        flash_mem);
+        } else {
+            sysbus_mmio_map(SYS_BUS_DEVICE(system_flash), 0,
+                            0x100000000ULL - total_size);
+        }
 
         if (i == 0) {
-            flash_mem = pflash_cfi01_get_memory(system_flash);
             pc_isa_bios_init(rom_memory, flash_mem, size);
 
             /* Encrypt the pflash boot ROM */
-- 
2.27.0
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Philippe Mathieu-Daudé 3 years, 9 months ago
Hi,

On 17/3/22 14:58, Xiaoyao Li wrote:
> TDX VM needs to boot with Trust Domain Virtual Firmware (TDVF). Unlike
> that OVMF is mapped as rom device, TDVF needs to be mapped as private
> memory. This is because TDX architecture doesn't provide read-only
> capability for VMM, and it doesn't support instruction emulation due
> to guest memory and registers are not accessible for VMM.
> 
> On the other hand, OVMF can work as TDVF, which is usually configured
> as pflash device in QEMU. To keep the same usage (QEMU parameter),
> introduce ram_mode to pflash for TDVF. When it's creating a TDX VM,
> ram_mode will be enabled automatically that map the firmware as RAM.
> 
> Note, this implies two things:
>   1. TDVF (OVMF) is not read-only (write-protected).
> 
>   2. It doesn't support non-volatile UEFI variables as what pflash
>      supports that the change to non-volatile UEFI variables won't get
>      synced back to backend vars.fd file.
> 
> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> ---
>   hw/block/pflash_cfi01.c | 25 ++++++++++++++++++-------
>   hw/i386/pc_sysfw.c      | 14 +++++++++++---
>   2 files changed, 29 insertions(+), 10 deletions(-)

If you don't need a pflash device, don't use it: simply map your nvram
region as ram in your machine. No need to clutter the pflash model like
that.

NAcked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Xiaoyao Li 3 years, 9 months ago
On 3/18/2022 10:07 PM, Philippe Mathieu-Daudé wrote:
> Hi,
> 
> On 17/3/22 14:58, Xiaoyao Li wrote:
>> TDX VM needs to boot with Trust Domain Virtual Firmware (TDVF). Unlike
>> that OVMF is mapped as rom device, TDVF needs to be mapped as private
>> memory. This is because TDX architecture doesn't provide read-only
>> capability for VMM, and it doesn't support instruction emulation due
>> to guest memory and registers are not accessible for VMM.
>>
>> On the other hand, OVMF can work as TDVF, which is usually configured
>> as pflash device in QEMU. To keep the same usage (QEMU parameter),
>> introduce ram_mode to pflash for TDVF. When it's creating a TDX VM,
>> ram_mode will be enabled automatically that map the firmware as RAM.
>>
>> Note, this implies two things:
>>   1. TDVF (OVMF) is not read-only (write-protected).
>>
>>   2. It doesn't support non-volatile UEFI variables as what pflash
>>      supports that the change to non-volatile UEFI variables won't get
>>      synced back to backend vars.fd file.
>>
>> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
>> ---
>>   hw/block/pflash_cfi01.c | 25 ++++++++++++++++++-------
>>   hw/i386/pc_sysfw.c      | 14 +++++++++++---
>>   2 files changed, 29 insertions(+), 10 deletions(-)
> 
> If you don't need a pflash device, don't use it: simply map your nvram
> region as ram in your machine. No need to clutter the pflash model like
> that.

I know it's dirty to hack the pflash device. The purpose is to make the 
user interface unchanged that people can still use

	-drive if=pflash,format=raw,unit=0,file=/path/to/OVMF_CODE.fd
         -drive if=pflash,format=raw,unit=1,file=/path/to/OVMF_VARS.fd

to create TD guest.

I can go back to use generic loader[1] to load TDVF in v2.

[1] 
https://lore.kernel.org/qemu-devel/acaf651389c3f407a9d6d0a2e943daf0a85bb5fc.1625704981.git.isaku.yamahata@intel.com/ 


> NAcked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> 


Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Gerd Hoffmann 3 years, 9 months ago
  Hi,

> > If you don't need a pflash device, don't use it: simply map your nvram
> > region as ram in your machine. No need to clutter the pflash model like
> > that.

Using the pflash device for something which isn't actually flash looks a
bit silly indeed.

> 
> I know it's dirty to hack the pflash device. The purpose is to make the user
> interface unchanged that people can still use
> 
> 	-drive if=pflash,format=raw,unit=0,file=/path/to/OVMF_CODE.fd
>         -drive if=pflash,format=raw,unit=1,file=/path/to/OVMF_VARS.fd
> 
> to create TD guest.

Well, if persistent vars are not supported anyway there is little reason
to split the firmware into CODE and VARS files.  You can use just use
OVMF.fd with a single pflash device.  libvirt recently got support for
that.

Just using -bios OVMF.fd might work too.  Daniel tried that recently for
sev, but ran into problems with wiring up ovmf metadata parsing for
-bios.  Don't remember the details though.

take care,
  Gerd
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Daniel P. Berrangé 3 years, 9 months ago
On Tue, Mar 22, 2022 at 10:21:41AM +0100, Gerd Hoffmann wrote:
>   Hi,
> 
> > > If you don't need a pflash device, don't use it: simply map your nvram
> > > region as ram in your machine. No need to clutter the pflash model like
> > > that.
> 
> Using the pflash device for something which isn't actually flash looks a
> bit silly indeed.
> 
> > 
> > I know it's dirty to hack the pflash device. The purpose is to make the user
> > interface unchanged that people can still use
> > 
> > 	-drive if=pflash,format=raw,unit=0,file=/path/to/OVMF_CODE.fd
> >         -drive if=pflash,format=raw,unit=1,file=/path/to/OVMF_VARS.fd
> > 
> > to create TD guest.
> 
> Well, if persistent vars are not supported anyway there is little reason
> to split the firmware into CODE and VARS files.  You can use just use
> OVMF.fd with a single pflash device.  libvirt recently got support for
> that.

Agreed.

> Just using -bios OVMF.fd might work too.  Daniel tried that recently for
> sev, but ran into problems with wiring up ovmf metadata parsing for
> -bios.  Don't remember the details though.

It was related to the BIOS shadowing, whereby QEMU loads it at one
address, and then when CPUs start it is copied to another address.
This was not compatible with the way AMD SEV wants to do measurement
of the firmware. May or may not be relevant for TDX, I don't know
enough about TDX to say.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Gerd Hoffmann 3 years, 9 months ago
  Hi,

> > Just using -bios OVMF.fd might work too.  Daniel tried that recently for
> > sev, but ran into problems with wiring up ovmf metadata parsing for
> > -bios.  Don't remember the details though.
> 
> It was related to the BIOS shadowing, whereby QEMU loads it at one
> address, and then when CPUs start it is copied to another address.

Is this the top 128k of the firmware being copied below 1M so the
firmware reset vector is available in real mode address space?

> This was not compatible with the way AMD SEV wants to do measurement
> of the firmware. May or may not be relevant for TDX, I don't know
> enough about TDX to say.

TDX boots in 32bit mode, so simply skipping any real mode compatibility
stuff shouldn't cause any problems here.

Not sure about SEV.  There is this SevProcessorReset entry in the ovmf
metadata block.  Is that the SEV reset vector?  If SEV cpu bringup
doesn't go through real mode either we maybe can just skip the BIOS
shadowing setup for confidential computing guests ...

take care,
  Gerd
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Daniel P. Berrangé 3 years, 9 months ago
On Tue, Mar 22, 2022 at 11:35:18AM +0100, Gerd Hoffmann wrote:
>   Hi,
> 
> > > Just using -bios OVMF.fd might work too.  Daniel tried that recently for
> > > sev, but ran into problems with wiring up ovmf metadata parsing for
> > > -bios.  Don't remember the details though.
> > 
> > It was related to the BIOS shadowing, whereby QEMU loads it at one
> > address, and then when CPUs start it is copied to another address.
> 
> Is this the top 128k of the firmware being copied below 1M so the
> firmware reset vector is available in real mode address space?

It was the 'rom_reset' method in hw/core/loader.c that was involved
in the root of the problem, copying the firmware from ROM to RAM.

At the time I did try a gross hack that (IIRC) disabled the
rom_reset logic, and munged x86_bios_rom_init so that it would
force load it straight at the RAM location. I couldn't figure
out an attractive way to make this into something supportable,
so abandoned the whole idea. Messing with this area of code is
a somewhat beyond my level of understanding of x86 boot process
anyway.

> > This was not compatible with the way AMD SEV wants to do measurement
> > of the firmware. May or may not be relevant for TDX, I don't know
> > enough about TDX to say.
> 
> TDX boots in 32bit mode, so simply skipping any real mode compatibility
> stuff shouldn't cause any problems here.
> 
> Not sure about SEV.  There is this SevProcessorReset entry in the ovmf
> metadata block.  Is that the SEV reset vector?  If SEV cpu bringup
> doesn't go through real mode either we maybe can just skip the BIOS
> shadowing setup for confidential computing guests ...


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Gerd Hoffmann 3 years, 9 months ago
  Hi,

> At the time I did try a gross hack that (IIRC) disabled the
> rom_reset logic, and munged x86_bios_rom_init so that it would
> force load it straight at the RAM location.

Sounds reasonable.  The whole rom logic exists to handle resets,
but with confidential guests we don't need that, we can't change
guest state to perform a reset anyway ...

take care,
  Gerd

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 4cf107baea34..169ef96682de 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1115,15 +1115,26 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
         goto bios_error;
     }
     bios = g_malloc(sizeof(*bios));
+
     memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
-    if (!isapc_ram_fw) {
-        memory_region_set_readonly(bios, true);
-    }
-    ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
-    if (ret != 0) {
-    bios_error:
-        fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
-        exit(1);
+    if (1 /* confidential computing */) {
+        /*
+         * The concept of a "reset" simply doesn't exist for
+         * confidential computing guests, we have to destroy and
+         * re-launch them instead.  So there is no need to register
+         * the firmware as rom to properly re-initialize on reset.
+         * Just go for a straight file load instead.
+         */
+        void *ptr = memory_region_get_ram_ptr(bios);
+        load_image_size(filename, ptr, bios_size);
+    } else {
+        if (!isapc_ram_fw) {
+            memory_region_set_readonly(bios, true);
+        }
+        ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
+        if (ret != 0) {
+            goto bios_error;
+        }
     }
     g_free(filename);
 
@@ -1144,6 +1155,11 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
     memory_region_add_subregion(rom_memory,
                                 (uint32_t)(-bios_size),
                                 bios);
+    return;
+
+bios_error:
+    fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
+    exit(1);
 }
 
 bool x86_machine_is_smm_enabled(const X86MachineState *x86ms)
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Gerd Hoffmann 3 years, 9 months ago
On Tue, Mar 22, 2022 at 01:20:24PM +0100, Gerd Hoffmann wrote:
>   Hi,
> 
> > At the time I did try a gross hack that (IIRC) disabled the
> > rom_reset logic, and munged x86_bios_rom_init so that it would
> > force load it straight at the RAM location.
> 
> Sounds reasonable.  The whole rom logic exists to handle resets,
> but with confidential guests we don't need that, we can't change
> guest state to perform a reset anyway ...

Completed, cleaned up a bit, but untested:
  https://git.kraxel.org/cgit/qemu/log/?h=sirius/cc

Any chance you can give this a try?

thanks,
  Gerd
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Xiaoyao Li 3 years, 8 months ago
On 3/24/2022 4:35 PM, Gerd Hoffmann wrote:
> On Tue, Mar 22, 2022 at 01:20:24PM +0100, Gerd Hoffmann wrote:
>>    Hi,
>>
>>> At the time I did try a gross hack that (IIRC) disabled the
>>> rom_reset logic, and munged x86_bios_rom_init so that it would
>>> force load it straight at the RAM location.
>>
>> Sounds reasonable.  The whole rom logic exists to handle resets,
>> but with confidential guests we don't need that, we can't change
>> guest state to perform a reset anyway ...
> 
> Completed, cleaned up a bit, but untested:
>    https://git.kraxel.org/cgit/qemu/log/?h=sirius/cc
> 
> Any chance you can give this a try?

Hi Gred,

I refactor the TDX series to load TDVF via "-bios" option upon it.

No issue hit.

Thanks,
-Xiaoyao

> thanks,
>    Gerd
>
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Xiaoyao Li 3 years, 9 months ago
On 3/22/2022 5:29 PM, Daniel P. Berrangé wrote:
> On Tue, Mar 22, 2022 at 10:21:41AM +0100, Gerd Hoffmann wrote:
>>    Hi,
>>
>>>> If you don't need a pflash device, don't use it: simply map your nvram
>>>> region as ram in your machine. No need to clutter the pflash model like
>>>> that.
>>
>> Using the pflash device for something which isn't actually flash looks a
>> bit silly indeed.
>>
>>>
>>> I know it's dirty to hack the pflash device. The purpose is to make the user
>>> interface unchanged that people can still use
>>>
>>> 	-drive if=pflash,format=raw,unit=0,file=/path/to/OVMF_CODE.fd
>>>          -drive if=pflash,format=raw,unit=1,file=/path/to/OVMF_VARS.fd
>>>
>>> to create TD guest.
>>
>> Well, if persistent vars are not supported anyway there is little reason
>> to split the firmware into CODE and VARS files.  You can use just use
>> OVMF.fd with a single pflash device.  libvirt recently got support for
>> that.
> 
> Agreed.

The purpose of using split firmware is that people can share the same 
code.fd while using different vars.fd




Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Daniel P. Berrangé 3 years, 9 months ago
On Thu, Mar 24, 2022 at 02:13:53PM +0800, Xiaoyao Li wrote:
> On 3/22/2022 5:29 PM, Daniel P. Berrangé wrote:
> > On Tue, Mar 22, 2022 at 10:21:41AM +0100, Gerd Hoffmann wrote:
> > >    Hi,
> > > 
> > > > > If you don't need a pflash device, don't use it: simply map your nvram
> > > > > region as ram in your machine. No need to clutter the pflash model like
> > > > > that.
> > > 
> > > Using the pflash device for something which isn't actually flash looks a
> > > bit silly indeed.
> > > 
> > > > 
> > > > I know it's dirty to hack the pflash device. The purpose is to make the user
> > > > interface unchanged that people can still use
> > > > 
> > > > 	-drive if=pflash,format=raw,unit=0,file=/path/to/OVMF_CODE.fd
> > > >          -drive if=pflash,format=raw,unit=1,file=/path/to/OVMF_VARS.fd
> > > > 
> > > > to create TD guest.
> > > 
> > > Well, if persistent vars are not supported anyway there is little reason
> > > to split the firmware into CODE and VARS files.  You can use just use
> > > OVMF.fd with a single pflash device.  libvirt recently got support for
> > > that.
> > 
> > Agreed.
> 
> The purpose of using split firmware is that people can share the same
> code.fd while using different vars.fd

That's fine for firmware that writes to vars.fd, but it was said earlier
that changes aren't written with TDX (nor are they written with SEV),
so a separate vars.fd serves no pupose in these cases.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Gerd Hoffmann 3 years, 9 months ago
  Hi,

> > > Well, if persistent vars are not supported anyway there is little reason
> > > to split the firmware into CODE and VARS files.  You can use just use
> > > OVMF.fd with a single pflash device.  libvirt recently got support for
> > > that.
> > 
> > Agreed.
> 
> The purpose of using split firmware is that people can share the same
> code.fd while using different vars.fd

Using different vars.fd files is pointless though when changes are never
written back ...

take care,
  Gerd
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Xiaoyao Li 3 years, 9 months ago
On 3/24/2022 3:58 PM, Gerd Hoffmann wrote:
>    Hi,
> 
>>>> Well, if persistent vars are not supported anyway there is little reason
>>>> to split the firmware into CODE and VARS files.  You can use just use
>>>> OVMF.fd with a single pflash device.  libvirt recently got support for
>>>> that.
>>>
>>> Agreed.
>>
>> The purpose of using split firmware is that people can share the same
>> code.fd while using different vars.fd
> 
> Using different vars.fd files is pointless though when changes are never
> written back ...

Yes, I agree on this.

Off the topic. If we really want to NVRAM capability to TDX guest, 1) we 
can use the PV interface issue MMIO write in OVMF, like what SEV does in 
OVMF. 2) map OVMF as shared, thus existing pflash works well.

However, both options will expose the content to VMM, which loses 
confidentiality.

> take care,
>    Gerd
>
Re: [RFC PATCH v3 17/36] pflash_cfi01/tdx: Introduce ram_mode of pflash for TDVF
Posted by Isaku Yamahata 3 years, 9 months ago
On Mon, Mar 21, 2022 at 04:54:51PM +0800,
Xiaoyao Li <xiaoyao.li@intel.com> wrote:

> On 3/18/2022 10:07 PM, Philippe Mathieu-Daudé wrote:
> > Hi,
> > 
> > On 17/3/22 14:58, Xiaoyao Li wrote:
> > > TDX VM needs to boot with Trust Domain Virtual Firmware (TDVF). Unlike
> > > that OVMF is mapped as rom device, TDVF needs to be mapped as private
> > > memory. This is because TDX architecture doesn't provide read-only
> > > capability for VMM, and it doesn't support instruction emulation due
> > > to guest memory and registers are not accessible for VMM.
> > > 
> > > On the other hand, OVMF can work as TDVF, which is usually configured
> > > as pflash device in QEMU. To keep the same usage (QEMU parameter),
> > > introduce ram_mode to pflash for TDVF. When it's creating a TDX VM,
> > > ram_mode will be enabled automatically that map the firmware as RAM.
> > > 
> > > Note, this implies two things:
> > > ?? 1. TDVF (OVMF) is not read-only (write-protected).
> > > 
> > > ?? 2. It doesn't support non-volatile UEFI variables as what pflash
> > > ???????? supports that the change to non-volatile UEFI variables won't get
> > > ???????? synced back to backend vars.fd file.
> > > 
> > > Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> > > ---
> > > ?? hw/block/pflash_cfi01.c | 25 ++++++++++++++++++-------
> > > ?? hw/i386/pc_sysfw.c?????????? | 14 +++++++++++---
> > > ?? 2 files changed, 29 insertions(+), 10 deletions(-)
> > 
> > If you don't need a pflash device, don't use it: simply map your nvram
> > region as ram in your machine. No need to clutter the pflash model like
> > that.
> 
> I know it's dirty to hack the pflash device. The purpose is to make the user
> interface unchanged that people can still use
> 
> 	-drive if=pflash,format=raw,unit=0,file=/path/to/OVMF_CODE.fd
>         -drive if=pflash,format=raw,unit=1,file=/path/to/OVMF_VARS.fd
> 
> to create TD guest.

For the compatibility for qemu command line, you don't have to modify pflash
device.  Don't instantiate pflash at pc_system_flash_create(), and at
pc_system_firmware_init(), you can retrieve necessary parameters, and then
populate memory.  Although it's still hacky, it would be cleaner a bit.
-- 
Isaku Yamahata <isaku.yamahata@gmail.com>