Merge tag 'firmware-20260704-pull-request' of https://gitlab.com/kraxel/qemu into staging

igvm: add device tree support

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmpIkaMACgkQTLbY7tPo
# cTg4NA/8CB9HEZG6kKV1fh/7N5ev0iL5S1K3HCxKYcHoyMfkkhDvORSa5oF8gYoP
# HiJC4D+8X+523YFOzvxsaRgTC0J6iRucktIz2PNHBpy7npcQpiRjI1l9Z4FPEH0b
# iPSuKgpliOYIUi/ckeTKK4q2GwYsxIaLhu/uGsEr10cCf62JkXigkc5t1ZXa/ggv
# HYBVNE9HM6CG6SWQKEqrfuSYex8Xa4+x/euzsAgDkuEBfYykHt4duDD1iObEJ6Cy
# 3UXodgkcLrnz5baWbtTNjmVRsQfyjtD7/kfo4yPNvzC80UIjdvxg4COXF6YxId5P
# gDBWl8bY9rqYah8zQ4QzxbVZ7HWJDCILLWc0O2Mlw70KdUQ7g5JA1Gjf6Ms5YgB6
# PEH+rJ9ir09MJ9Z7AWRo3Ry91opDGrKUos2maQHdf8AADV9afmJVQ1frnDgUjF/3
# PXZVVCSpVoLBP5GLT+2l60qFYzJPqd/HsK5cWGaZEJyfvejrZjEVI6l9FliQFJ9l
# HiLEo2yhWVtRzruy7Uv16tU42xODmDMBKU12HZfQLvYbKUaBf24YpLiBprEzUM72
# snXGhZX7wQl6ghQ7mxdLncECRRvFwuknZPeLBPWyp6rm5IuTvxkhRtgCHS4RFYbr
# 7NDjzJ3/gg9YXy3z0cJjRkaBfJvwdYTUTpuq0yDVOfNL53L0jbA=
# =7c95
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 04 Jul 2026 06:52:51 CEST
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* tag 'firmware-20260704-pull-request' of https://gitlab.com/kraxel/qemu:
  igvm: add device tree parameter support
  igvm: use idiomatic meson conditional for IGVM build files
  igvm: Report error on missing parameter area in directive handlers

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2026-07-05 08:42:47 +02:00
4 changed files with 77 additions and 18 deletions

View File

@@ -26,6 +26,10 @@
#include <igvm/igvm.h>
#include <igvm/igvm_defs.h>
#ifdef CONFIG_FDT
#include <libfdt.h>
#endif
#ifndef IGVM_VHT_OPTIONAL_BIT
#define IGVM_VHT_OPTIONAL_BIT (1U << 31)
#endif
@@ -81,7 +85,8 @@ struct QEMU_PACKED sev_id_authentication {
#define IGVM_SEV_ID_BLOCK_VERSION 1
QIgvmParameterData*
qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index)
qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index,
Error **errp)
{
QIgvmParameterData *param_entry;
QTAILQ_FOREACH(param_entry, &igvm->parameter_data, next)
@@ -90,7 +95,8 @@ qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index)
return param_entry;
}
}
warn_report("IGVM: No parameter area for index %u", parameter_area_index);
error_setg(errp, "IGVM: parameter area index %u not found",
parameter_area_index);
return NULL;
}
@@ -119,6 +125,10 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
static int qigvm_initialization_guest_policy(QIgvm *ctx,
const uint8_t *header_data,
Error **errp);
#ifdef CONFIG_FDT
static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
Error **errp);
#endif
struct QIGVMHandler {
IgvmVariableHeaderType type;
@@ -149,6 +159,10 @@ static struct QIGVMHandler handlers[] = {
qigvm_initialization_guest_policy },
{ IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE,
qigvm_directive_madt },
#ifdef CONFIG_FDT
{ IGVM_VHT_DEVICE_TREE, IGVM_HEADER_SECTION_DIRECTIVE,
qigvm_directive_device_tree },
#endif
};
static int qigvm_handler(QIgvm *ctx, IgvmVariableHeaderType raw_type,
@@ -528,9 +542,10 @@ static int qigvm_directive_parameter_insert(QIgvm *ctx,
return 0;
}
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
param_entry = qigvm_find_param_entry(ctx,
param->parameter_area_index, errp);
if (param_entry == NULL) {
return 0;
return -1;
}
region = qigvm_prepare_memory(ctx, param->gpa, param_entry->size,
@@ -601,9 +616,10 @@ static int qigvm_directive_memory_map(QIgvm *ctx, const uint8_t *header_data,
}
/* Find the parameter area that should hold the memory map */
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
param_entry = qigvm_find_param_entry(ctx,
param->parameter_area_index, errp);
if (param_entry == NULL) {
return 0;
return -1;
}
max_entry_count = param_entry->size / sizeof(IGVM_VHS_MEMORY_MAP_ENTRY);
@@ -660,9 +676,10 @@ static int qigvm_directive_vp_count(QIgvm *ctx, const uint8_t *header_data,
uint32_t *vp_count;
CPUState *cpu;
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
param_entry = qigvm_find_param_entry(ctx,
param->parameter_area_index, errp);
if (param_entry == NULL) {
return 0;
return -1;
}
vp_count = (uint32_t *)(param_entry->data + param->byte_offset);
@@ -683,9 +700,10 @@ static int qigvm_directive_environment_info(QIgvm *ctx,
QIgvmParameterData *param_entry;
IgvmEnvironmentInfo *environmental_state;
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
param_entry = qigvm_find_param_entry(ctx,
param->parameter_area_index, errp);
if (param_entry == NULL) {
return 0;
return -1;
}
environmental_state =
@@ -780,6 +798,48 @@ static int qigvm_directive_snp_id_block(QIgvm *ctx, const uint8_t *header_data,
return 0;
}
#ifdef CONFIG_FDT
static int qigvm_directive_device_tree(QIgvm *ctx, const uint8_t *header_data,
Error **errp)
{
const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data;
g_autofree void *fdt_packed = NULL;
QIgvmParameterData *param_entry;
uint32_t fdt_size;
param_entry = qigvm_find_param_entry(ctx,
param->parameter_area_index, errp);
if (param_entry == NULL) {
return -1;
}
if (ctx->machine_state->fdt == NULL) {
error_setg(errp, "IGVM: device tree not available");
return -1;
}
fdt_size = fdt_totalsize(ctx->machine_state->fdt);
fdt_packed = g_memdup2(ctx->machine_state->fdt, fdt_size);
if (fdt_pack(fdt_packed)) {
error_setg(errp, "IGVM: failed to pack device tree");
return -1;
}
fdt_size = fdt_totalsize(fdt_packed);
if (fdt_size > param_entry->size) {
error_setg(errp,
"IGVM: device tree size exceeds parameter area"
" defined in IGVM file");
return -1;
}
memcpy(param_entry->data, fdt_packed, fdt_size);
return 0;
}
#endif
static int qigvm_initialization_guest_policy(QIgvm *ctx,
const uint8_t *header_data, Error **errp)
{

View File

@@ -34,11 +34,8 @@ if have_vhost_user_crypto
endif
system_ss.add(when: gio, if_true: files('dbus-vmstate.c'))
system_ss.add(when: 'CONFIG_SGX', if_true: files('hostmem-epc.c'))
if igvm.found()
system_ss.add(igvm)
system_ss.add(files('igvm-cfg.c'), igvm)
system_ss.add(files('igvm.c'), igvm)
endif
system_ss.add(when: igvm, if_true: [files('igvm-cfg.c', 'igvm.c'), fdt])
system_ss.add(when: 'CONFIG_SPDM_SOCKET', if_true: files('spdm-socket.c'))

View File

@@ -72,6 +72,7 @@ struct QIgvm {
IgvmHandle qigvm_file_init(char *filename, Error **errp);
QIgvmParameterData*
qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index);
qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index,
Error **errp);
#endif

View File

@@ -191,9 +191,10 @@ int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp)
int result = 0;
/* Find the parameter area that should hold the MADT data */
param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
param_entry = qigvm_find_param_entry(ctx,
param->parameter_area_index, errp);
if (param_entry == NULL) {
return 0;
return -1;
}
GArray *madt = acpi_build_madt_standalone(ctx->machine_state);