[PATCH v2 0/7] Add support for more ACPI table types

This was triggered by a request by KubeVirt in https://gitlab.com/libvirt/libvirt/-/issues/748 I've not functionally tested this, since I lack any suitable guest windows environment this is looking for MSDM tables, nor does my machine have MSDM ACPI tables to pass to a guest. I'm blindly assuming that the QEMU CLI code is identical except for s/SLIC/MSDM/. In this 2nd version I've addressed two further issues * the xen driver was incorrectly mapping its 'acpi_firmware' option to type=slic. Xen's setting accepts a concatenation of tables of any type. This is different from type=slic which represents a single table, whose type will be forced to 'SLIC' if not already set. To address this we introduce a new 'rawset' type * The QEMU driver does not require a type to be set in the first place; if set it merely overrides what is in the data file. Supporting this would let us handle any ACPI table type without further XML changes. To address this we introduce a new 'raw' type, which can occur many times. Daniel P. Berrangé (7): conf: introduce support for multiple ACPI tables src: validate permitted ACPI table types in libxl/qemu drivers src: introduce 'raw' and 'rawset' ACPI table types qemu: support 'raw' ACPI table type libxl: support 'rawset' ACPI table type conf: support MSDM ACPI table type qemu: support MSDM ACPI table type docs/formatdomain.rst | 23 ++++- src/conf/domain_conf.c | 94 ++++++++++++++----- src/conf/domain_conf.h | 24 ++++- src/conf/schemas/domaincommon.rng | 7 +- src/libvirt_private.syms | 2 + src/libxl/libxl_conf.c | 5 +- src/libxl/libxl_domain.c | 28 ++++++ src/libxl/xen_xl.c | 15 ++- src/qemu/qemu_command.c | 18 +++- src/qemu/qemu_validate.c | 23 +++++ src/security/security_dac.c | 18 ++-- src/security/security_selinux.c | 16 ++-- src/security/virt-aa-helper.c | 5 +- .../acpi-table-many.x86_64-latest.args | 37 ++++++++ .../acpi-table-many.x86_64-latest.xml | 42 +++++++++ tests/qemuxmlconfdata/acpi-table-many.xml | 34 +++++++ tests/qemuxmlconftest.c | 1 + .../xlconfigdata/test-fullvirt-acpi-slic.xml | 2 +- 18 files changed, 337 insertions(+), 57 deletions(-) create mode 100644 tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/acpi-table-many.xml -- 2.47.1

Currently we parse <os> <acpi> <table type="slic">...path...</table> </acpi> </os> into a flat 'char *slic_table' field which is rather an anti-pattern as it has special cased a single attribute type. This rewrites the internal design to permit multiple table types to be parsed, should we add more in future. Each type is currently permitted to only appear once. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/conf/domain_conf.c | 90 +++++++++++++++++++++++---------- src/conf/domain_conf.h | 21 +++++++- src/libvirt_private.syms | 2 + src/libxl/libxl_conf.c | 5 +- src/libxl/xen_xl.c | 15 ++++-- src/qemu/qemu_command.c | 13 +++-- src/security/security_dac.c | 18 ++++--- src/security/security_selinux.c | 16 +++--- src/security/virt-aa-helper.c | 5 +- 9 files changed, 133 insertions(+), 52 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5630a469be..fc8ed9fc54 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1457,6 +1457,11 @@ VIR_ENUM_IMPL(virDomainOsDefFirmwareFeature, "secure-boot", ); +VIR_ENUM_IMPL(virDomainOsACPITable, + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, + "slic", +); + VIR_ENUM_IMPL(virDomainCFPC, VIR_DOMAIN_CFPC_LAST, "none", @@ -3899,6 +3904,15 @@ virDomainSecDefFree(virDomainSecDef *def) g_free(def); } +void virDomainOSACPITableDefFree(virDomainOSACPITableDef *def) +{ + if (!def) + return; + g_free(def->path); + g_free(def); +} + + static void virDomainOSDefClear(virDomainOSDef *os) { @@ -3924,7 +3938,9 @@ virDomainOSDefClear(virDomainOSDef *os) g_free(os->cmdline); g_free(os->dtb); g_free(os->root); - g_free(os->slic_table); + for (i = 0; i < os->nacpiTables; i++) + virDomainOSACPITableDefFree(os->acpiTables[i]); + g_free(os->acpiTables); virDomainLoaderDefFree(os->loader); g_free(os->bootloader); g_free(os->bootloaderArgs); @@ -17883,40 +17899,57 @@ virDomainDefParseBootAcpiOptions(virDomainDef *def, int n; g_autofree xmlNodePtr *nodes = NULL; g_autofree char *tmp = NULL; + size_t ntables = 0; + virDomainOSACPITableDef **tables = NULL; + size_t i; if ((n = virXPathNodeSet("./os/acpi/table", ctxt, &nodes)) < 0) return -1; - if (n > 1) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Only one acpi table is supported")); - return -1; - } + if (n == 0) + return 0; - if (n == 1) { - tmp = virXMLPropString(nodes[0], "type"); + tables = g_new0(virDomainOSACPITableDef *, n); + for (i = 0; i < n; i++) { + g_autofree char *path = virXMLNodeContentString(nodes[i]); + virDomainOsACPITable type; + size_t j; - if (!tmp) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing acpi table type")); - return -1; - } + if (!path) + goto error; - if (STREQ_NULLABLE(tmp, "slic")) { - VIR_FREE(tmp); - if (!(tmp = virXMLNodeContentString(nodes[0]))) - return -1; + if (virXMLPropEnum(nodes[i], "type", + virDomainOsACPITableTypeFromString, + VIR_XML_PROP_REQUIRED, + &type) < 0) + goto error; - def->os.slic_table = virFileSanitizePath(tmp); - } else { - virReportError(VIR_ERR_XML_ERROR, - _("Unknown acpi table type: %1$s"), - tmp); - return -1; + for (j = 0; j < i; j++) { + if (tables[j]->type == type) { + virReportError(VIR_ERR_XML_ERROR, + _("ACPI table type '%1$s' may only appear once"), + virDomainOsACPITableTypeToString(type)); + goto error; + } } + + tables[ntables] = g_new0(virDomainOSACPITableDef, 1); + tables[ntables]->type = type; + tables[ntables]->path = virFileSanitizePath(path); + ntables++; } + def->os.nacpiTables = ntables; + def->os.acpiTables = tables; + return 0; + + error: + for (i = 0; i < ntables; i++) { + virDomainOSACPITableDefFree(tables[i]); + } + g_free(tables); + return -1; } @@ -28478,11 +28511,16 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def, def->os.dtb); virBufferEscapeString(buf, "<root>%s</root>\n", def->os.root); - if (def->os.slic_table) { + + if (def->os.nacpiTables) { virBufferAddLit(buf, "<acpi>\n"); virBufferAdjustIndent(buf, 2); - virBufferEscapeString(buf, "<table type='slic'>%s</table>\n", - def->os.slic_table); + for (i = 0; i < def->os.nacpiTables; i++) { + virBufferAsprintf(buf, "<table type='%s'>", + virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); + virBufferEscapeString(buf, "%s</table>\n", + def->os.acpiTables[i]->path); + } virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</acpi>\n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d4fa79cb84..cc9fd503fa 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2474,6 +2474,24 @@ typedef enum { VIR_ENUM_DECL(virDomainOsDefFirmwareFeature); +typedef enum { + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC, + + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST +} virDomainOsACPITable; + +VIR_ENUM_DECL(virDomainOsACPITable); + +struct _virDomainOSACPITableDef { + virDomainOsACPITable type; + char *path; +}; + +typedef struct _virDomainOSACPITableDef virDomainOSACPITableDef; +void virDomainOSACPITableDefFree(virDomainOSACPITableDef *def); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainOSACPITableDef, virDomainOSACPITableDefFree); + + struct _virDomainOSDef { int type; virDomainOsDefFirmware firmware; @@ -2496,7 +2514,8 @@ struct _virDomainOSDef { char *cmdline; char *dtb; char *root; - char *slic_table; + size_t nacpiTables; + virDomainOSACPITableDef **acpiTables; virDomainLoaderDef *loader; char *bootloader; char *bootloaderArgs; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 30a9f806f0..db8c29ec1d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -611,6 +611,8 @@ virDomainObjTaint; virDomainObjUpdateModificationImpact; virDomainObjWait; virDomainObjWaitUntil; +virDomainOsACPITableTypeFromString; +virDomainOsACPITableTypeToString; virDomainOsDefFirmwareTypeFromString; virDomainOsDefFirmwareTypeToString; virDomainOSTypeFromString; diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index c404226e43..7d845b97ec 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -582,8 +582,9 @@ libxlMakeDomBuildInfo(virDomainDef *def, VIR_TRISTATE_SWITCH_ON); #endif - /* copy SLIC table path to acpi_firmware */ - b_info->u.hvm.acpi_firmware = g_strdup(def->os.slic_table); + /* copy the table path to acpi_firmware */ + if (def->os.nacpiTables) + b_info->u.hvm.acpi_firmware = g_strdup(def->os.acpiTables[0]->path); if (def->nsounds > 0) { /* diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c index 53f6871efc..062b753cea 100644 --- a/src/libxl/xen_xl.c +++ b/src/libxl/xen_xl.c @@ -106,6 +106,7 @@ xenParseXLOS(virConf *conf, virDomainDef *def, virCaps *caps) g_autofree char *bios = NULL; g_autofree char *bios_path = NULL; g_autofree char *boot = NULL; + g_autofree char *slic = NULL; int val = 0; if (xenConfigGetString(conf, "bios", &bios, NULL) < 0) @@ -133,8 +134,15 @@ xenParseXLOS(virConf *conf, virDomainDef *def, virCaps *caps) } } - if (xenConfigCopyStringOpt(conf, "acpi_firmware", &def->os.slic_table) < 0) + if (xenConfigCopyStringOpt(conf, "acpi_firmware", &slic) < 0) return -1; + if (slic != NULL) { + def->os.nacpiTables = 1; + def->os.acpiTables = g_new0(virDomainOSACPITableDef *, 1); + def->os.acpiTables[0] = g_new0(virDomainOSACPITableDef, 1); + def->os.acpiTables[0]->type = VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC; + def->os.acpiTables[0]->path = g_steal_pointer(&slic); + } if (xenConfigCopyStringOpt(conf, "kernel", &def->os.kernel) < 0) return -1; @@ -1134,8 +1142,9 @@ xenFormatXLOS(virConf *conf, virDomainDef *def) return -1; } - if (def->os.slic_table && - xenConfigSetString(conf, "acpi_firmware", def->os.slic_table) < 0) + if (def->os.nacpiTables && + xenConfigSetString(conf, "acpi_firmware", + def->os.acpiTables[0]->path) < 0) return -1; if (def->os.kernel && diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0ad73af335..6048c755fc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -127,6 +127,11 @@ VIR_ENUM_IMPL(qemuNumaPolicy, "restrictive", ); +VIR_ENUM_DECL(qemuACPITableSIG); +VIR_ENUM_IMPL(qemuACPITableSIG, + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, + "SLIC"); + const char * qemuAudioDriverTypeToString(virDomainAudioType type) @@ -5995,6 +6000,7 @@ qemuBuildBootCommandLine(virCommand *cmd, { g_auto(virBuffer) boot_buf = VIR_BUFFER_INITIALIZER; g_autofree char *boot_opts_str = NULL; + size_t i; if (def->os.bootmenu) { if (def->os.bootmenu == VIR_TRISTATE_BOOL_YES) @@ -6028,11 +6034,12 @@ qemuBuildBootCommandLine(virCommand *cmd, virCommandAddArgList(cmd, "-append", def->os.cmdline, NULL); if (def->os.dtb) virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL); - if (def->os.slic_table) { + for (i = 0; i < def->os.nacpiTables; i++) { g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; virCommandAddArg(cmd, "-acpitable"); - virBufferAddLit(&buf, "sig=SLIC,file="); - virQEMUBuildBufferEscapeComma(&buf, def->os.slic_table); + virBufferAsprintf(&buf, "sig=%s,file=", + qemuACPITableSIGTypeToString(def->os.acpiTables[i]->type)); + virQEMUBuildBufferEscapeComma(&buf, def->os.acpiTables[i]->path); virCommandAddArgBuffer(cmd, &buf); } diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 0505f4e4a3..b4d61bc576 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -2050,9 +2050,10 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr, virSecurityDACRestoreFileLabel(mgr, def->os.dtb) < 0) rc = -1; - if (def->os.slic_table && - virSecurityDACRestoreFileLabel(mgr, def->os.slic_table) < 0) - rc = -1; + for (i = 0; i < def->os.nacpiTables; i++) { + if (virSecurityDACRestoreFileLabel(mgr, def->os.acpiTables[i]->path) < 0) + rc = -1; + } if (def->pstore && virSecurityDACRestoreFileLabel(mgr, def->pstore->path) < 0) @@ -2300,11 +2301,12 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr, user, group, true) < 0) return -1; - if (def->os.slic_table && - virSecurityDACSetOwnership(mgr, NULL, - def->os.slic_table, - user, group, true) < 0) - return -1; + for (i = 0; i < def->os.nacpiTables; i++) { + if (virSecurityDACSetOwnership(mgr, NULL, + def->os.acpiTables[i]->path, + user, group, true) < 0) + return -1; + } if (def->pstore && virSecurityDACSetOwnership(mgr, NULL, diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index cdc32d9b34..b8659e33d6 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -3013,9 +3013,10 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager *mgr, virSecuritySELinuxRestoreFileLabel(mgr, def->os.dtb, true) < 0) rc = -1; - if (def->os.slic_table && - virSecuritySELinuxRestoreFileLabel(mgr, def->os.slic_table, true) < 0) - rc = -1; + for (i = 0; i < def->os.nacpiTables; i++) { + if (virSecuritySELinuxRestoreFileLabel(mgr, def->os.acpiTables[i]->path, true) < 0) + rc = -1; + } if (def->pstore && virSecuritySELinuxRestoreFileLabel(mgr, def->pstore->path, true) < 0) @@ -3443,10 +3444,11 @@ virSecuritySELinuxSetAllLabel(virSecurityManager *mgr, data->content_context, true) < 0) return -1; - if (def->os.slic_table && - virSecuritySELinuxSetFilecon(mgr, def->os.slic_table, - data->content_context, true) < 0) - return -1; + for (i = 0; i < def->os.nacpiTables; i++) { + if (virSecuritySELinuxSetFilecon(mgr, def->os.acpiTables[i]->path, + data->content_context, true) < 0) + return -1; + } if (def->pstore && virSecuritySELinuxSetFilecon(mgr, def->pstore->path, diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index 1626d5a89c..23de0be9db 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -974,9 +974,10 @@ get_files(vahControl * ctl) if (vah_add_file(&buf, ctl->def->os.dtb, "r") != 0) goto cleanup; - if (ctl->def->os.slic_table) - if (vah_add_file(&buf, ctl->def->os.slic_table, "r") != 0) + for (i = 0; i < ctl->def->os.nacpiTables; i++) { + if (vah_add_file(&buf, ctl->def->os.acpiTables[i]->path, "r") != 0) goto cleanup; + } if (ctl->def->pstore) if (vah_add_file(&buf, ctl->def->pstore->path, "rw") != 0) -- 2.47.1

This forces us to update the drivers when defining new table types to avoid incorrectly accepting them by default. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/libxl/libxl_domain.c | 19 +++++++++++++++++++ src/qemu/qemu_validate.c | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 6805160923..efd01840de 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -306,6 +306,7 @@ libxlDomainDefValidate(const virDomainDef *def, libxlDriverPrivate *driver = opaque; g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver); bool reqSecureBoot = false; + size_t i; if (!virCapabilitiesDomainSupported(cfg->caps, def->os.type, def->os.arch, @@ -330,6 +331,24 @@ libxlDomainDefValidate(const virDomainDef *def, return -1; } + for (i = 0; i < def->os.nacpiTables; i++) { + switch (def->os.acpiTables[i]->type) { + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: + break; + + default: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST: + virReportEnumRangeError(virDomainOsACPITable, + def->os.acpiTables[i]->type); + return -1; + } + } + if (def->os.nacpiTables > 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only a single ACPI table is supported")); + return -1; + } + if (def->nsounds > 0) { virDomainSoundDef *snd = def->sounds[0]; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index f3ef1be660..1759ab4e6e 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -701,6 +701,8 @@ static int qemuValidateDomainDefBoot(const virDomainDef *def, virQEMUCaps *qemuCaps) { + size_t i; + if (def->os.bootloader || def->os.bootloaderArgs) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("bootloader is not supported by QEMU")); @@ -740,6 +742,19 @@ qemuValidateDomainDefBoot(const virDomainDef *def, return -1; } + for (i = 0; i < def->os.nacpiTables; i++) { + switch (def->os.acpiTables[i]->type) { + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: + break; + + default: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST: + virReportEnumRangeError(virDomainOsACPITable, + def->os.acpiTables[i]->type); + return -1; + } + } + return 0; } -- 2.47.1

The QEMU driver has only accepted type=slic even though QEMU is able to accept individual tables of any type, without needing to specify a signature. Introduce type=raw to address this usage scenario. Contrary to other types, this one may appear multiple times. The Xen driver has mistakenly accepted type=slic and use it to set the Xen acpi_firmware setting, which performs a simple passthrough of multiple concatenated data table. Introduce type=rawset to address this usage scenario. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 19 ++++++++++++++++--- src/conf/domain_conf.c | 5 ++++- src/conf/domain_conf.h | 2 ++ src/conf/schemas/domaincommon.rng | 6 +++++- src/libxl/libxl_domain.c | 7 +++++++ src/qemu/qemu_command.c | 2 ++ src/qemu/qemu_validate.c | 7 +++++++ 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index fdb3c2459e..d3add663e2 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -490,9 +490,22 @@ These options apply to any form of booting of the guest OS. ... ``acpi`` - The ``table`` element contains a fully-qualified path to the ACPI table. The - ``type`` attribute contains the ACPI table type (currently only ``slic`` is - supported) :since:`Since 1.3.5 (QEMU)` :since:`Since 5.9.0 (Xen)` + The ``table`` element contains a fully-qualified path to the ACPI table, + with the ``type`` attribute dictating what data must be present in the + file: + + * ``raw``: a single ACPI table with header and data, with ACPI + signature auto-detected from header (:since:`Since 11.2.0`). + * ``rawset``: concatenation of multiple ACPI tables with header + and data, each with any ACPI signature, auto-detected from header + (:since:`Since 11.2.0`). + * ``slic``: a single ACPI table with header and data, providing + software licensing information. The ACPI table signature in the + header will be forced to ``SLIC`` (:since:`Since 1.3.5 (QEMU)`, + mis-interpreted as ``rawset`` :since:`Since 5.9.0 (Xen)`). + + Each type may be used only once, except for ``raw`` which can + appear multiple times. SMBIOS System Information diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fc8ed9fc54..530473e200 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1459,6 +1459,8 @@ VIR_ENUM_IMPL(virDomainOsDefFirmwareFeature, VIR_ENUM_IMPL(virDomainOsACPITable, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, + "raw", + "rawset", "slic", ); @@ -17925,7 +17927,8 @@ virDomainDefParseBootAcpiOptions(virDomainDef *def, goto error; for (j = 0; j < i; j++) { - if (tables[j]->type == type) { + if (tables[j]->type == type && + type != VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW) { virReportError(VIR_ERR_XML_ERROR, _("ACPI table type '%1$s' may only appear once"), virDomainOsACPITableTypeToString(type)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cc9fd503fa..299e2cbd5b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2475,6 +2475,8 @@ typedef enum { VIR_ENUM_DECL(virDomainOsDefFirmwareFeature); typedef enum { + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW, + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 824da9d066..b5eaf7c233 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -7180,7 +7180,11 @@ <zeroOrMore> <element name="table"> <attribute name="type"> - <value>slic</value> + <choice> + <value>raw</value> + <value>rawset</value> + <value>slic</value> + </choice> </attribute> <ref name="absFilePath"/> </element> diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index efd01840de..e564d9e5fe 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -336,6 +336,13 @@ libxlDomainDefValidate(const virDomainDef *def, case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: break; + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("ACPI table type '%1$s' is not supported"), + virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); + return -1; + default: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST: virReportEnumRangeError(virDomainOsACPITable, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6048c755fc..bef06049ec 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -130,6 +130,8 @@ VIR_ENUM_IMPL(qemuNumaPolicy, VIR_ENUM_DECL(qemuACPITableSIG); VIR_ENUM_IMPL(qemuACPITableSIG, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, + "", /* raw */ + "", /* rawset */ "SLIC"); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 1759ab4e6e..de36bfc7ea 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -747,6 +747,13 @@ qemuValidateDomainDefBoot(const virDomainDef *def, case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: break; + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("ACPI table type '%1$s' is not supported"), + virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); + return -1; + default: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST: virReportEnumRangeError(virDomainOsACPITable, -- 2.47.1

CC Marek who did the original libxl integration of 'type=slic' mapping to Xen's 'acpi_firmware' property. Marek, this introduces a new 'rawset' ACPI type for direct passthrough of ACPI table lists, which is intended to match Xen's semantics exactly. The later patch in this series changes the libxl driver to accept both the old (slic) and new (rawset) types, but when emitting XML libvirt will use the new type. There's a possible risk this could upset apps if they're consuming XML from libvirt and validating the type. On Wed, Feb 26, 2025 at 08:16:15PM +0000, Daniel P. Berrangé wrote:
The QEMU driver has only accepted type=slic even though QEMU is able to accept individual tables of any type, without needing to specify a signature. Introduce type=raw to address this usage scenario. Contrary to other types, this one may appear multiple times.
The Xen driver has mistakenly accepted type=slic and use it to set the Xen acpi_firmware setting, which performs a simple passthrough of multiple concatenated data table. Introduce type=rawset to address this usage scenario.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 19 ++++++++++++++++--- src/conf/domain_conf.c | 5 ++++- src/conf/domain_conf.h | 2 ++ src/conf/schemas/domaincommon.rng | 6 +++++- src/libxl/libxl_domain.c | 7 +++++++ src/qemu/qemu_command.c | 2 ++ src/qemu/qemu_validate.c | 7 +++++++ 7 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index fdb3c2459e..d3add663e2 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -490,9 +490,22 @@ These options apply to any form of booting of the guest OS. ...
``acpi`` - The ``table`` element contains a fully-qualified path to the ACPI table. The - ``type`` attribute contains the ACPI table type (currently only ``slic`` is - supported) :since:`Since 1.3.5 (QEMU)` :since:`Since 5.9.0 (Xen)` + The ``table`` element contains a fully-qualified path to the ACPI table, + with the ``type`` attribute dictating what data must be present in the + file: + + * ``raw``: a single ACPI table with header and data, with ACPI + signature auto-detected from header (:since:`Since 11.2.0`). + * ``rawset``: concatenation of multiple ACPI tables with header + and data, each with any ACPI signature, auto-detected from header + (:since:`Since 11.2.0`). + * ``slic``: a single ACPI table with header and data, providing + software licensing information. The ACPI table signature in the + header will be forced to ``SLIC`` (:since:`Since 1.3.5 (QEMU)`, + mis-interpreted as ``rawset`` :since:`Since 5.9.0 (Xen)`). + + Each type may be used only once, except for ``raw`` which can + appear multiple times.
SMBIOS System Information diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fc8ed9fc54..530473e200 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1459,6 +1459,8 @@ VIR_ENUM_IMPL(virDomainOsDefFirmwareFeature,
VIR_ENUM_IMPL(virDomainOsACPITable, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, + "raw", + "rawset", "slic", );
@@ -17925,7 +17927,8 @@ virDomainDefParseBootAcpiOptions(virDomainDef *def, goto error;
for (j = 0; j < i; j++) { - if (tables[j]->type == type) { + if (tables[j]->type == type && + type != VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW) { virReportError(VIR_ERR_XML_ERROR, _("ACPI table type '%1$s' may only appear once"), virDomainOsACPITableTypeToString(type)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cc9fd503fa..299e2cbd5b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2475,6 +2475,8 @@ typedef enum { VIR_ENUM_DECL(virDomainOsDefFirmwareFeature);
typedef enum { + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW, + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC,
VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 824da9d066..b5eaf7c233 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -7180,7 +7180,11 @@ <zeroOrMore> <element name="table"> <attribute name="type"> - <value>slic</value> + <choice> + <value>raw</value> + <value>rawset</value> + <value>slic</value> + </choice> </attribute> <ref name="absFilePath"/> </element> diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index efd01840de..e564d9e5fe 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -336,6 +336,13 @@ libxlDomainDefValidate(const virDomainDef *def, case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: break;
+ case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("ACPI table type '%1$s' is not supported"), + virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); + return -1; + default: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST: virReportEnumRangeError(virDomainOsACPITable, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6048c755fc..bef06049ec 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -130,6 +130,8 @@ VIR_ENUM_IMPL(qemuNumaPolicy, VIR_ENUM_DECL(qemuACPITableSIG); VIR_ENUM_IMPL(qemuACPITableSIG, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, + "", /* raw */ + "", /* rawset */ "SLIC");
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 1759ab4e6e..de36bfc7ea 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -747,6 +747,13 @@ qemuValidateDomainDefBoot(const virDomainDef *def, case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: break;
+ case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("ACPI table type '%1$s' is not supported"), + virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); + return -1; + default: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST: virReportEnumRangeError(virDomainOsACPITable, -- 2.47.1
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 :|

This allows passing a single ACPI table of any type through to QEMU with the signture autodetected from the header. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 2 +- src/qemu/qemu_command.c | 6 ++- src/qemu/qemu_validate.c | 2 +- .../acpi-table-many.x86_64-latest.args | 36 ++++++++++++++++ .../acpi-table-many.x86_64-latest.xml | 41 +++++++++++++++++++ tests/qemuxmlconfdata/acpi-table-many.xml | 33 +++++++++++++++ tests/qemuxmlconftest.c | 1 + 7 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/acpi-table-many.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index d3add663e2..895f74a42a 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -495,7 +495,7 @@ These options apply to any form of booting of the guest OS. file: * ``raw``: a single ACPI table with header and data, with ACPI - signature auto-detected from header (:since:`Since 11.2.0`). + signature auto-detected from header (:since:`Since 11.2.0` (QEMU)). * ``rawset``: concatenation of multiple ACPI tables with header and data, each with any ACPI signature, auto-detected from header (:since:`Since 11.2.0`). diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bef06049ec..5ecc50d838 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6038,9 +6038,11 @@ qemuBuildBootCommandLine(virCommand *cmd, virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL); for (i = 0; i < def->os.nacpiTables; i++) { g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + const char *sig = qemuACPITableSIGTypeToString(def->os.acpiTables[i]->type); virCommandAddArg(cmd, "-acpitable"); - virBufferAsprintf(&buf, "sig=%s,file=", - qemuACPITableSIGTypeToString(def->os.acpiTables[i]->type)); + if (*sig != '\0') + virBufferAsprintf(&buf, "sig=%s,", sig); + virBufferAddLit(&buf, "file="); virQEMUBuildBufferEscapeComma(&buf, def->os.acpiTables[i]->path); virCommandAddArgBuffer(cmd, &buf); } diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index de36bfc7ea..397e2073ef 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -744,10 +744,10 @@ qemuValidateDomainDefBoot(const virDomainDef *def, for (i = 0; i < def->os.nacpiTables; i++) { switch (def->os.acpiTables[i]->type) { + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: break; - case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("ACPI table type '%1$s' is not supported"), diff --git a/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args new file mode 100644 index 0000000000..4d5d02cb3c --- /dev/null +++ b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args @@ -0,0 +1,36 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \ +-accel tcg \ +-cpu qemu64 \ +-m size=219136k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-acpitable file=/var/lib/libvirt/acpi/exm1.dat \ +-acpitable file=/var/lib/libvirt/acpi/exm2.dat \ +-acpitable file=/var/lib/libvirt/acpi/exm3.dat \ +-acpitable sig=SLIC,file=/var/lib/libvirt/acpi/slic.dat \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml new file mode 100644 index 0000000000..b7f7e18d28 --- /dev/null +++ b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml @@ -0,0 +1,41 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <acpi> + <table type='raw'>/var/lib/libvirt/acpi/exm1.dat</table> + <table type='raw'>/var/lib/libvirt/acpi/exm2.dat</table> + <table type='raw'>/var/lib/libvirt/acpi/exm3.dat</table> + <table type='slic'>/var/lib/libvirt/acpi/slic.dat</table> + </acpi> + <boot dev='hd'/> + </os> + <features> + <acpi/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/acpi-table-many.xml b/tests/qemuxmlconfdata/acpi-table-many.xml new file mode 100644 index 0000000000..cc75011990 --- /dev/null +++ b/tests/qemuxmlconfdata/acpi-table-many.xml @@ -0,0 +1,33 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + <acpi> + <table type='raw'>/var/lib/libvirt/acpi/exm1.dat</table> + <table type='raw'>/var/lib/libvirt/acpi/exm2.dat</table> + <table type='raw'>/var/lib/libvirt/acpi/exm3.dat</table> + <table type='slic'>/var/lib/libvirt/acpi/slic.dat</table> + </acpi> + </os> + <features> + <acpi/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 8632434760..2013b9be2f 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2774,6 +2774,7 @@ mymain(void) DO_TEST_CAPS_LATEST_PARSE_ERROR("usb-too-long-port-path-invalid"); DO_TEST_CAPS_LATEST("acpi-table"); + DO_TEST_CAPS_LATEST("acpi-table-many"); DO_TEST_CAPS_LATEST("intel-iommu"); DO_TEST_CAPS_LATEST("intel-iommu-caching-mode"); -- 2.47.1

This fixes representation of the 'acpi_firmware' config in the Xen driver, which repesents a concatenation of tables of any type. Use of 'type=slic' is accepted on input for backwards compatibility. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/libxl/libxl_domain.c | 5 +++-- src/libxl/xen_xl.c | 2 +- tests/xlconfigdata/test-fullvirt-acpi-slic.xml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index e564d9e5fe..e31d92d903 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -333,11 +333,12 @@ libxlDomainDefValidate(const virDomainDef *def, for (i = 0; i < def->os.nacpiTables; i++) { switch (def->os.acpiTables[i]->type) { - case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: /* Back compat for historical mistake, + * functionally the same as 'rawset' */ + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: break; case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: - case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("ACPI table type '%1$s' is not supported"), virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c index 062b753cea..9d06315661 100644 --- a/src/libxl/xen_xl.c +++ b/src/libxl/xen_xl.c @@ -140,7 +140,7 @@ xenParseXLOS(virConf *conf, virDomainDef *def, virCaps *caps) def->os.nacpiTables = 1; def->os.acpiTables = g_new0(virDomainOSACPITableDef *, 1); def->os.acpiTables[0] = g_new0(virDomainOSACPITableDef, 1); - def->os.acpiTables[0]->type = VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC; + def->os.acpiTables[0]->type = VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET; def->os.acpiTables[0]->path = g_steal_pointer(&slic); } diff --git a/tests/xlconfigdata/test-fullvirt-acpi-slic.xml b/tests/xlconfigdata/test-fullvirt-acpi-slic.xml index 366d877624..bf617e5e05 100644 --- a/tests/xlconfigdata/test-fullvirt-acpi-slic.xml +++ b/tests/xlconfigdata/test-fullvirt-acpi-slic.xml @@ -8,7 +8,7 @@ <type arch='x86_64' machine='xenfv'>hvm</type> <loader type='rom' format='raw'>/usr/lib/xen/boot/hvmloader</loader> <acpi> - <table type='slic'>/sys/firmware/acpi/tables/SLIC</table> + <table type='rawset'>/sys/firmware/acpi/tables/SLIC</table> </acpi> <boot dev='cdrom'/> </os> -- 2.47.1

The MSDM ACPI table is an alternative for the SLIC table type, sometimes used by Microsoft for Windows Licensing checks: https://learn.microsoft.com/en-us/previous-versions/windows/hardware/design/...) Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 4 ++++ src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/conf/schemas/domaincommon.rng | 1 + src/libxl/libxl_domain.c | 1 + src/qemu/qemu_command.c | 3 ++- src/qemu/qemu_validate.c | 1 + 7 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 895f74a42a..3bf1ff7714 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -503,6 +503,10 @@ These options apply to any form of booting of the guest OS. software licensing information. The ACPI table signature in the header will be forced to ``SLIC`` (:since:`Since 1.3.5 (QEMU)`, mis-interpreted as ``rawset`` :since:`Since 5.9.0 (Xen)`). + * ``msdm``: a single ACPI table with header and data, providing + Microsoft Data Management information. The ACPI table signature + in the header will be forced to ``MSDM`` + (:since:`Since 11.2.0`). Each type may be used only once, except for ``raw`` which can appear multiple times. diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 530473e200..7bdfe21bff 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1462,6 +1462,7 @@ VIR_ENUM_IMPL(virDomainOsACPITable, "raw", "rawset", "slic", + "msdm", ); VIR_ENUM_IMPL(virDomainCFPC, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 299e2cbd5b..7880cbedff 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2478,6 +2478,7 @@ typedef enum { VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC, + VIR_DOMAIN_OS_ACPI_TABLE_TYPE_MSDM, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST } virDomainOsACPITable; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index b5eaf7c233..39d5604454 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -7184,6 +7184,7 @@ <value>raw</value> <value>rawset</value> <value>slic</value> + <value>msdm</value> </choice> </attribute> <ref name="absFilePath"/> diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index e31d92d903..c5a556ec78 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -339,6 +339,7 @@ libxlDomainDefValidate(const virDomainDef *def, break; case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_MSDM: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("ACPI table type '%1$s' is not supported"), virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5ecc50d838..67797a8af8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -132,7 +132,8 @@ VIR_ENUM_IMPL(qemuACPITableSIG, VIR_DOMAIN_OS_ACPI_TABLE_TYPE_LAST, "", /* raw */ "", /* rawset */ - "SLIC"); + "SLIC", + ""); const char * diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 397e2073ef..295be2de5a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -749,6 +749,7 @@ qemuValidateDomainDefBoot(const virDomainDef *def, break; case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_MSDM: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("ACPI table type '%1$s' is not supported"), virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); -- 2.47.1

The MSDM ACPI table is a replacement for the SLIC table type, now preferred by Microsoft for Windows Licensing checks: https://learn.microsoft.com/en-us/previous-versions/windows/hardware/design/...) Resolves: https://gitlab.com/libvirt/libvirt/-/issues/748 Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatdomain.rst | 2 +- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_validate.c | 2 +- tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args | 1 + tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml | 1 + tests/qemuxmlconfdata/acpi-table-many.xml | 1 + 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 3bf1ff7714..999192791b 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -506,7 +506,7 @@ These options apply to any form of booting of the guest OS. * ``msdm``: a single ACPI table with header and data, providing Microsoft Data Management information. The ACPI table signature in the header will be forced to ``MSDM`` - (:since:`Since 11.2.0`). + (:since:`Since 11.2.0 (QEMU)`). Each type may be used only once, except for ``raw`` which can appear multiple times. diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 67797a8af8..92a634948e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -133,7 +133,7 @@ VIR_ENUM_IMPL(qemuACPITableSIG, "", /* raw */ "", /* rawset */ "SLIC", - ""); + "MSDM"); const char * diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 295be2de5a..4ab7af36f3 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -746,10 +746,10 @@ qemuValidateDomainDefBoot(const virDomainDef *def, switch (def->os.acpiTables[i]->type) { case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAW: case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_SLIC: + case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_MSDM: break; case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_RAWSET: - case VIR_DOMAIN_OS_ACPI_TABLE_TYPE_MSDM: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("ACPI table type '%1$s' is not supported"), virDomainOsACPITableTypeToString(def->os.acpiTables[i]->type)); diff --git a/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args index 4d5d02cb3c..2b0b433258 100644 --- a/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args +++ b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args @@ -30,6 +30,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -acpitable file=/var/lib/libvirt/acpi/exm2.dat \ -acpitable file=/var/lib/libvirt/acpi/exm3.dat \ -acpitable sig=SLIC,file=/var/lib/libvirt/acpi/slic.dat \ +-acpitable sig=MSDM,file=/var/lib/libvirt/acpi/msdm.dat \ -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ diff --git a/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml index b7f7e18d28..084bb4cda3 100644 --- a/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml @@ -11,6 +11,7 @@ <table type='raw'>/var/lib/libvirt/acpi/exm2.dat</table> <table type='raw'>/var/lib/libvirt/acpi/exm3.dat</table> <table type='slic'>/var/lib/libvirt/acpi/slic.dat</table> + <table type='msdm'>/var/lib/libvirt/acpi/msdm.dat</table> </acpi> <boot dev='hd'/> </os> diff --git a/tests/qemuxmlconfdata/acpi-table-many.xml b/tests/qemuxmlconfdata/acpi-table-many.xml index cc75011990..890078d4c3 100644 --- a/tests/qemuxmlconfdata/acpi-table-many.xml +++ b/tests/qemuxmlconfdata/acpi-table-many.xml @@ -12,6 +12,7 @@ <table type='raw'>/var/lib/libvirt/acpi/exm2.dat</table> <table type='raw'>/var/lib/libvirt/acpi/exm3.dat</table> <table type='slic'>/var/lib/libvirt/acpi/slic.dat</table> + <table type='msdm'>/var/lib/libvirt/acpi/msdm.dat</table> </acpi> </os> <features> -- 2.47.1

On 2/26/25 21:16, Daniel P. Berrangé wrote:
This was triggered by a request by KubeVirt in
https://gitlab.com/libvirt/libvirt/-/issues/748
I've not functionally tested this, since I lack any suitable guest windows environment this is looking for MSDM tables, nor does my machine have MSDM ACPI tables to pass to a guest.
I'm blindly assuming that the QEMU CLI code is identical except for s/SLIC/MSDM/.
In this 2nd version I've addressed two further issues
* the xen driver was incorrectly mapping its 'acpi_firmware' option to type=slic. Xen's setting accepts a concatenation of tables of any type. This is different from type=slic which represents a single table, whose type will be forced to 'SLIC' if not already set. To address this we introduce a new 'rawset' type
* The QEMU driver does not require a type to be set in the first place; if set it merely overrides what is in the data file. Supporting this would let us handle any ACPI table type without further XML changes. To address this we introduce a new 'raw' type, which can occur many times.
Daniel P. Berrangé (7): conf: introduce support for multiple ACPI tables src: validate permitted ACPI table types in libxl/qemu drivers src: introduce 'raw' and 'rawset' ACPI table types qemu: support 'raw' ACPI table type libxl: support 'rawset' ACPI table type conf: support MSDM ACPI table type qemu: support MSDM ACPI table type
docs/formatdomain.rst | 23 ++++- src/conf/domain_conf.c | 94 ++++++++++++++----- src/conf/domain_conf.h | 24 ++++- src/conf/schemas/domaincommon.rng | 7 +- src/libvirt_private.syms | 2 + src/libxl/libxl_conf.c | 5 +- src/libxl/libxl_domain.c | 28 ++++++ src/libxl/xen_xl.c | 15 ++- src/qemu/qemu_command.c | 18 +++- src/qemu/qemu_validate.c | 23 +++++ src/security/security_dac.c | 18 ++-- src/security/security_selinux.c | 16 ++-- src/security/virt-aa-helper.c | 5 +- .../acpi-table-many.x86_64-latest.args | 37 ++++++++ .../acpi-table-many.x86_64-latest.xml | 42 +++++++++ tests/qemuxmlconfdata/acpi-table-many.xml | 34 +++++++ tests/qemuxmlconftest.c | 1 + .../xlconfigdata/test-fullvirt-acpi-slic.xml | 2 +- 18 files changed, 337 insertions(+), 57 deletions(-) create mode 100644 tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.args create mode 100644 tests/qemuxmlconfdata/acpi-table-many.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/acpi-table-many.xml
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Daniel P. Berrangé
-
Michal Prívozník