mbox series

[v3,00/15] Introduce support for IGVM files

Message ID cover.1718979106.git.roy.hopkins@suse.com
Headers show
Series Introduce support for IGVM files | expand

Message

Roy Hopkins June 21, 2024, 2:29 p.m. UTC
Based-on: 02d9c38236

Here is v3 of the set of patches to add support for IGVM files to QEMU.

Firstly, apologies for the long gap between v2 and v3. This was due to a number
of factors, but particularly holding back until SEV-SNP support landed in QEMU
as well as for some changes to be merged in the upstream IGVM specification and
library. The delay meant that I could include the SEV-SNP IGVM changes that I
had been separately maintaining for COCONUT-SVSM into this series, giving full
support for the full range of SEV technologies.

Thank-you to everyone who reviewed the previous set of patches [1]. I
have hopefully addressed all of the comments in those reviews. Some of these
changes required a reasonable amount of rework. Along with the inclusion of
support for SEV-SNP, this has resulted in a fairly large set of differences from
v2. This v3 patch series is also available on github: [2]

For testing IGVM support in QEMU you need to generate an IGVM file that is
configured for the platform you want to launch. I have updated the `buildigvm`
test tool [3] to allow generation of IGVM files for all currently supported
platforms. 

In my own testing I have launched guests using IGVM files for each supported
platform. In addition, I have verified that the launch measurement for SEV,
SEV-ES and SEV-SNP when using QEMU with IGVM matches the pre-calculated 
measurement using the COCONUT-SVSM `igvmmeasure` tool [4]. This same tool
was used to sign the SEV-SNP IGVM file to verify the correct operation of
the new support for ID_BLOCKs in v3.

This patch series requires version v0.3.2 of the IGVM library to be installed
[5].

Changes in v3:

* Added support for SEV-SNP on top of SEV and SEV-ES.
* Introduced a new `IgvmCfg` user accessible object to configure and process the
  IGVM file, moving this from `ConfidentialGuestSupport` where it resided in v2.
  `ConfidentialGuestSupport` is still used to abstract the implementation of
  guest configuration.
* The IGVM processing code will use the `ConfidentialGuestSupport` functions if
  provided, but will allow processing of a supported subset of directives if a
  CGS instance is not provided, allowing non-confidential guest to be configured
  with an IGVM file.
* Added support for setting platform policy via the IGVM file.
* Added ID_BLOCK support as part of SEV-SNP for using the platform to verify the
  measurement and signature of the IGVM file.
* Update documentation to describe configuring IGVM using the `igvm-cfg` object
  and referring to it from `-machine`.
* Pre-processing of the IGVM file during KVM initialization to determine the
  `sev_features` to pass to the new KVM_SEV_INIT2 ioctl.
* Tidying/rework of code as per previous review comments. In particular, the
  IGVM library dependency has been updated to remove potential namespace
  clashes.

Patch summary:

The patches have been organized so the first patches in the series mostly match
those in v2 but with additional support for SEV-SNP and native platforms.
This hopefully simplifies the review process for those that have already looked
at the previous series.

1-10: Add support and documentation for processing IGVM files for SEV, SEV-ES,
SEV-SNP and native platforms. 

11-14: Processing of policy and SEV-SNP ID_BLOCK from IGVM file. 

15: Add pre-processing of IGVM file to support synchronization of 'SEV_FEATURES'
from IGVM VMSA to KVM.

[1] Link to v2:
https://lore.kernel.org/qemu-devel/cover.1712138654.git.roy.hopkins@suse.com/

[2] v3 patches also available here:
https://github.com/roy-hopkins/qemu/tree/igvm_master_v3

[3] `buildigvm` tool v0.2.0
https://github.com/roy-hopkins/buildigvm/releases/tag/v0.2.0

[4] `igvmmeasure` tool 
https://github.com/coconut-svsm/svsm/tree/main/igvmmeasure

[5] IGVM library v0.3.2
https://github.com/microsoft/igvm/releases/tag/igvm-v0.3.2

Roy Hopkins (15):
  meson: Add optional dependency on IGVM library
  backends/confidential-guest-support: Add functions to support IGVM
  backends/igvm: Add IGVM loader and configuration
  hw/core/machine: Add igvm-cfg object and processing for IGVM files
  i386/pc_sysfw: Ensure sysfw flash configuration does not conflict with
    IGVM
  sev: Update launch_update_data functions to use Error handling
  i386/sev: Refactor setting of reset vector and initial CPU state
  i386/sev: Implement ConfidentialGuestSupport functions for SEV
  docs/system: Add documentation on support for IGVM
  docs/interop/firmware.json: Add igvm to FirmwareDevice
  backends/confidential-guest-support: Add set_guest_policy() function
  backends/igvm: Process initialization sections in IGVM file
  backends/igvm: Handle policy for SEV guests
  i386/sev: Add implementation of CGS set_guest_policy()
  sev: Provide sev_features flags from IGVM VMSA to KVM_SEV_INIT2

 docs/interop/firmware.json                 |   9 +-
 docs/system/i386/amd-memory-encryption.rst |   2 +
 docs/system/igvm.rst                       | 157 ++++
 docs/system/index.rst                      |   1 +
 meson.build                                |   8 +
 qapi/qom.json                              |  16 +
 backends/igvm.h                            |  37 +
 include/exec/confidential-guest-support.h  |  96 +++
 include/hw/boards.h                        |   2 +
 include/sysemu/igvm-cfg.h                  |  54 ++
 target/i386/sev.h                          | 124 +++
 backends/confidential-guest-support.c      |  43 +
 backends/igvm-cfg.c                        |  66 ++
 backends/igvm.c                            | 948 +++++++++++++++++++++
 hw/core/machine.c                          |  20 +
 hw/i386/pc_sysfw.c                         |  23 +-
 target/i386/sev.c                          | 830 ++++++++++++++++--
 backends/meson.build                       |   5 +
 meson_options.txt                          |   2 +
 qemu-options.hx                            |  25 +
 scripts/meson-buildoptions.sh              |   3 +
 21 files changed, 2393 insertions(+), 78 deletions(-)
 create mode 100644 docs/system/igvm.rst
 create mode 100644 backends/igvm.h
 create mode 100644 include/sysemu/igvm-cfg.h
 create mode 100644 backends/igvm-cfg.c
 create mode 100644 backends/igvm.c

Comments

Daniel P. Berrangé June 24, 2024, 1:50 p.m. UTC | #1
On Fri, Jun 21, 2024 at 03:29:03PM +0100, Roy Hopkins wrote:
> Based-on: 02d9c38236
> 
> Here is v3 of the set of patches to add support for IGVM files to QEMU.
> 
> Firstly, apologies for the long gap between v2 and v3. This was due to a number
> of factors, but particularly holding back until SEV-SNP support landed in QEMU
> as well as for some changes to be merged in the upstream IGVM specification and
> library. The delay meant that I could include the SEV-SNP IGVM changes that I
> had been separately maintaining for COCONUT-SVSM into this series, giving full
> support for the full range of SEV technologies.
> 
> Thank-you to everyone who reviewed the previous set of patches [1]. I
> have hopefully addressed all of the comments in those reviews. Some of these
> changes required a reasonable amount of rework. Along with the inclusion of
> support for SEV-SNP, this has resulted in a fairly large set of differences from
> v2. This v3 patch series is also available on github: [2]

snip

FYI, I hit some compile problems reporting array bounds issues,
with this posting. I'm using Fedora 40, which has gcc 14 in
case that matters.


In file included from /var/home/berrange/src/virt/qemu/include/sysemu/kvm.h:214,
                 from ../target/i386/sev.c:29:
In function ‘cpu_x86_load_seg_cache’,
    inlined from ‘sev_apply_cpu_context’ at ../target/i386/sev.c:454:13:
../target/i386/cpu.h:2236:20: error: array subscript 6 is above array bounds of ‘SegmentCache[6]’ [-Werror=array-bounds=]
 2236 |     sc = &env->segs[seg_reg];
      |           ~~~~~~~~~^~~~~~~~~
../target/i386/cpu.h: In function ‘sev_apply_cpu_context’:
../target/i386/cpu.h:1682:18: note: while referencing ‘segs’
 1682 |     SegmentCache segs[6]; /* selector values */
      |                  ^~~~
In function ‘cpu_x86_load_seg_cache’,
    inlined from ‘sev_apply_cpu_context’ at ../target/i386/sev.c:454:13:
../target/i386/cpu.h:2236:20: error: array subscript 6 is above array bounds of ‘SegmentCache[6]’ [-Werror=array-bounds=]
 2236 |     sc = &env->segs[seg_reg];
      |           ~~~~~~~~~^~~~~~~~~
../target/i386/cpu.h: In function ‘sev_apply_cpu_context’:
../target/i386/cpu.h:1682:18: note: while referencing ‘segs’
 1682 |     SegmentCache segs[6]; /* selector values */
      |                  ^~~~
In function ‘cpu_x86_load_seg_cache’,
    inlined from ‘sev_apply_cpu_context’ at ../target/i386/sev.c:454:13:
../target/i386/cpu.h:2236:20: error: array subscript 6 is above array bounds of ‘SegmentCache[6]’ [-Werror=array-bounds=]
 2236 |     sc = &env->segs[seg_reg];
      |           ~~~~~~~~~^~~~~~~~~
../target/i386/cpu.h: In function ‘sev_apply_cpu_context’:
../target/i386/cpu.h:1682:18: note: while referencing ‘segs’
 1682 |     SegmentCache segs[6]; /* selector values */
      |                  ^~~~
...cut many more similar warnings...


With regards,
Daniel
Roy Hopkins June 28, 2024, 10:56 a.m. UTC | #2
On Mon, 2024-06-24 at 14:50 +0100, Daniel P. Berrangé wrote:
> On Fri, Jun 21, 2024 at 03:29:03PM +0100, Roy Hopkins wrote:
> > Based-on: 02d9c38236
> > 
> > Here is v3 of the set of patches to add support for IGVM files to QEMU.
> > 
> > Firstly, apologies for the long gap between v2 and v3. This was due to a
> > number
> > of factors, but particularly holding back until SEV-SNP support landed in
> > QEMU
> > as well as for some changes to be merged in the upstream IGVM specification
> > and
> > library. The delay meant that I could include the SEV-SNP IGVM changes that
> > I
> > had been separately maintaining for COCONUT-SVSM into this series, giving
> > full
> > support for the full range of SEV technologies.
> > 
> > Thank-you to everyone who reviewed the previous set of patches [1]. I
> > have hopefully addressed all of the comments in those reviews. Some of these
> > changes required a reasonable amount of rework. Along with the inclusion of
> > support for SEV-SNP, this has resulted in a fairly large set of differences
> > from
> > v2. This v3 patch series is also available on github: [2]
> 
> snip
> 
> FYI, I hit some compile problems reporting array bounds issues,
> with this posting. I'm using Fedora 40, which has gcc 14 in
> case that matters.
> 

The reason I was not seeing this was because I included `--enable-debug` which
apparently hides the problem.

There is technically a bounds issue with the function overflowing the end of the
array for the TR and LDTR registers but, coincidently or not, it overflows into
the correct register storage meaning the code works correctly.

I've added a patch to fix this for v4.

> 
> In file included from
> /var/home/berrange/src/virt/qemu/include/sysemu/kvm.h:214,
>                  from ../target/i386/sev.c:29:
> In function ‘cpu_x86_load_seg_cache’,
>     inlined from ‘sev_apply_cpu_context’ at ../target/i386/sev.c:454:13:
> ../target/i386/cpu.h:2236:20: error: array subscript 6 is above array bounds
> of ‘SegmentCache[6]’ [-Werror=array-bounds=]
>  2236 |     sc = &env->segs[seg_reg];
>       |           ~~~~~~~~~^~~~~~~~~
> ../target/i386/cpu.h: In function ‘sev_apply_cpu_context’:
> ../target/i386/cpu.h:1682:18: note: while referencing ‘segs’
>  1682 |     SegmentCache segs[6]; /* selector values */
>       |                  ^~~~
> In function ‘cpu_x86_load_seg_cache’,
>     inlined from ‘sev_apply_cpu_context’ at ../target/i386/sev.c:454:13:
> ../target/i386/cpu.h:2236:20: error: array subscript 6 is above array bounds
> of ‘SegmentCache[6]’ [-Werror=array-bounds=]
>  2236 |     sc = &env->segs[seg_reg];
>       |           ~~~~~~~~~^~~~~~~~~
> ../target/i386/cpu.h: In function ‘sev_apply_cpu_context’:
> ../target/i386/cpu.h:1682:18: note: while referencing ‘segs’
>  1682 |     SegmentCache segs[6]; /* selector values */
>       |                  ^~~~
> In function ‘cpu_x86_load_seg_cache’,
>     inlined from ‘sev_apply_cpu_context’ at ../target/i386/sev.c:454:13:
> ../target/i386/cpu.h:2236:20: error: array subscript 6 is above array bounds
> of ‘SegmentCache[6]’ [-Werror=array-bounds=]
>  2236 |     sc = &env->segs[seg_reg];
>       |           ~~~~~~~~~^~~~~~~~~
> ../target/i386/cpu.h: In function ‘sev_apply_cpu_context’:
> ../target/i386/cpu.h:1682:18: note: while referencing ‘segs’
>  1682 |     SegmentCache segs[6]; /* selector values */
>       |                  ^~~~
> ...cut many more similar warnings...
> 
> 
> With regards,
> Daniel


Regards,
Roy