[PATCH v2 0/3] igvm: Supply MADT via IGVM parameter

Oliver Steffen posted 3 patches 1 month, 4 weeks ago
Failed in applying to current master (apply log)
There is a newer version of this series
backends/igvm-cfg.c       |  8 +++++++-
backends/igvm.c           | 37 ++++++++++++++++++++++++++++++++++++-
hw/acpi/aml-build.c       |  7 +++++--
hw/i386/acpi-build.c      |  8 ++++++++
hw/i386/acpi-build.h      |  2 ++
include/system/igvm-cfg.h |  5 ++++-
include/system/igvm.h     |  2 +-
target/i386/sev.c         |  5 +++--
8 files changed, 66 insertions(+), 8 deletions(-)
[PATCH v2 0/3] igvm: Supply MADT via IGVM parameter
Posted by Oliver Steffen 1 month, 4 weeks ago
When launching using an IGVM file, supply a copy of the MADT (part of the ACPI
tables) via an IGVM parameter (IGVM_VHY_MADT) to the guest, in addition to the
regular fw_cfg mechanism.

The IGVM parameter can be consumed by Coconut SVSM [1], instead of relying on
the fw_cfg interface, which has caused problems before due to unexpected access
[2,3]. Using IGVM parameters is the default way for Coconut SVSM; switching
over would allow removing specialized code paths for QEMU in Coconut.

In any case OVMF, which runs after SVSM has already been initialized, will
continue reading all ACPI tables via fw_cfg and provide fixed up ACPI data to
the OS as before.

This series makes ACPI table building more generic by making the BIOS linker
optional. This allows the MADT to be generated outside of the ACPI build
context. A new function (acpi_build_madt_standalone()) is added for that. With
that, the IGVM MADT parameter field can be filled with the MADT data during
processing of the IGVM file.

Generating the MADT twice (IGVM processing and ACPI table building) seems
acceptable, since there is no infrastructure to obtain the MADT out of the ACPI
table memory area during IGVM processing.

[1] https://github.com/coconut-svsm/svsm/pull/858
[2] https://gitlab.com/qemu-project/qemu/-/issues/2882
[3] https://github.com/coconut-svsm/svsm/issues/646

v2:
- Provide more context in the message of the main commit
- Document the madt parameter of IgvmCfgClass::process()
- Document why no MADT data is provided the the process call in sev.c

Based-On: <20251118122133.1695767-1-kraxel@redhat.com>
Signed-off-by: Oliver Steffen <osteffen@redhat.com>

Oliver Steffen (3):
  hw/acpi: Make BIOS linker optional
  hw/acpi: Add standalone function to build MADT
  igvm: Fill MADT IGVM parameter field

 backends/igvm-cfg.c       |  8 +++++++-
 backends/igvm.c           | 37 ++++++++++++++++++++++++++++++++++++-
 hw/acpi/aml-build.c       |  7 +++++--
 hw/i386/acpi-build.c      |  8 ++++++++
 hw/i386/acpi-build.h      |  2 ++
 include/system/igvm-cfg.h |  5 ++++-
 include/system/igvm.h     |  2 +-
 target/i386/sev.c         |  5 +++--
 8 files changed, 66 insertions(+), 8 deletions(-)

-- 
2.52.0
Re: [PATCH v2 0/3] igvm: Supply MADT via IGVM parameter
Posted by Igor Mammedov 1 month, 3 weeks ago
On Thu, 11 Dec 2025 11:31:33 +0100
Oliver Steffen <osteffen@redhat.com> wrote:

> When launching using an IGVM file, supply a copy of the MADT (part of the ACPI
> tables) via an IGVM parameter (IGVM_VHY_MADT) to the guest, in addition to the
> regular fw_cfg mechanism.
> 
> The IGVM parameter can be consumed by Coconut SVSM [1], instead of relying on
> the fw_cfg interface, which has caused problems before due to unexpected access
> [2,3]. Using IGVM parameters is the default way for Coconut SVSM; switching
> over would allow removing specialized code paths for QEMU in Coconut.
> 
> In any case OVMF, which runs after SVSM has already been initialized, will
> continue reading all ACPI tables via fw_cfg and provide fixed up ACPI data to
> the OS as before.
> 
> This series makes ACPI table building more generic by making the BIOS linker
> optional. This allows the MADT to be generated outside of the ACPI build
> context. A new function (acpi_build_madt_standalone()) is added for that. With
> that, the IGVM MADT parameter field can be filled with the MADT data during
> processing of the IGVM file.
> 
> Generating the MADT twice (IGVM processing and ACPI table building) seems
> acceptable, since there is no infrastructure to obtain the MADT out of the ACPI
> table memory area during IGVM processing.


looking at #2 and #3, it seems that root cause is still unknown,
one should be able read tables multiple times from fw_cg.
(so there is a but in QEMU or guest doesn't load ACPI tables correctly).

Also seeing that regenerating tables every time helps,
it hints that PCI subsystem is not configured when tables read 1st time.
Why that causes guest kernel errors is still unclear.

Main conditions to get acpi blob representing is that they should be read
after guest firmware enumerated/configured PCI subsystem and
firmware should use BIOSlinker workflow to load/postprocess
tables otherwise all bets are off (even if this series works for now,
it's subject to break without notice since user doesn't follow proper
procedures for reading/processing ACPI blob).
Hence I dislike this approach.

Alternatively, instead of ACPI tables one can use FW_CFG_MAX_CPUS
like old SeaBIOS used to do if all you need is APIC IDs.
Limitation of this approach is that one can't use sparse APIC ID
configs.
Benefit is that no QEMU change is required whatsoever.

If you still wish to proceed with standalone MADT approach,
please add to justification exact root cause of what corrupts
ACPI tables blob later on. With that, It would be easier to decide if
standalone MADT is an acceptable hack. 

> [1] https://github.com/coconut-svsm/svsm/pull/858
> [2] https://gitlab.com/qemu-project/qemu/-/issues/2882
> [3] https://github.com/coconut-svsm/svsm/issues/646
> 
> v2:
> - Provide more context in the message of the main commit
> - Document the madt parameter of IgvmCfgClass::process()
> - Document why no MADT data is provided the the process call in sev.c
> 
> Based-On: <20251118122133.1695767-1-kraxel@redhat.com>
> Signed-off-by: Oliver Steffen <osteffen@redhat.com>
> 
> Oliver Steffen (3):
>   hw/acpi: Make BIOS linker optional
>   hw/acpi: Add standalone function to build MADT
>   igvm: Fill MADT IGVM parameter field
> 
>  backends/igvm-cfg.c       |  8 +++++++-
>  backends/igvm.c           | 37 ++++++++++++++++++++++++++++++++++++-
>  hw/acpi/aml-build.c       |  7 +++++--
>  hw/i386/acpi-build.c      |  8 ++++++++
>  hw/i386/acpi-build.h      |  2 ++
>  include/system/igvm-cfg.h |  5 ++++-
>  include/system/igvm.h     |  2 +-
>  target/i386/sev.c         |  5 +++--
>  8 files changed, 66 insertions(+), 8 deletions(-)
>
Re: [PATCH v2 0/3] igvm: Supply MADT via IGVM parameter
Posted by Gerd Hoffmann 3 weeks, 5 days ago
  Hi,

> Also seeing that regenerating tables every time helps,
> it hints that PCI subsystem is not configured when tables read 1st time.

This is the case.

> Main conditions to get acpi blob representing is that they should be read
> after guest firmware enumerated/configured PCI subsystem and
> firmware should use BIOSlinker workflow to load/postprocess
> tables otherwise all bets are off (even if this series works for now,
> it's subject to break without notice since user doesn't follow proper
> procedures for reading/processing ACPI blob).
> Hence I dislike this approach.

Well, the use case which needs this is a confidential VM with SVSM.  So
the SVSM firmware is the first thing which boots, sets up SVSM and the
services it provides (vTPM, in the future UEFI variable store), then
goes boot OVMF firmware which handles PCI initialization etc.

SVSM needs to know the SMP configuration, but it does not even look at
the PCI bus.

The MADT is static:  Nothing in there changes if the guest changes
hardware registers (such as pci bridge windows), nothing requires the
bios linker for cross-table references.  Given that I fail to see how
this can possibly break in the future.

> Alternatively, instead of ACPI tables one can use FW_CFG_MAX_CPUS
> like old SeaBIOS used to do if all you need is APIC IDs.
> Limitation of this approach is that one can't use sparse APIC ID
> configs.

Thats why the idea is to just use the MADT table for SMP discovery.
The APIC IDs are in there, and it also removes qemu-specific code from
SVSM.

take care,
  Gerd