- util: introduce object for holding a system inhibitor lock (RHEL-83064) - src: convert drivers over to new virInhibitor APIs (RHEL-83064) - rpc: remove logind support for virNetDaemon (RHEL-83064) - util: fix off-by-1 in inhibitor constants (RHEL-83064) - util: don't attempt to acquire logind inhibitor if not requested (RHEL-83064) - network: Free inhibitor in networkStateCleanup() (RHEL-83064) - conf: introduce support for multiple ACPI tables (RHEL-81041) - src: validate permitted ACPI table types in libxl/qemu drivers (RHEL-81041) - src: introduce 'raw' and 'rawset' ACPI table types (RHEL-81041) - qemu: support 'raw' ACPI table type (RHEL-81041) - libxl: support 'rawset' ACPI table type (RHEL-81041) - conf: support MSDM ACPI table type (RHEL-81041) - qemu: support MSDM ACPI table type (RHEL-81041) - qemuxmlconftest: Include shared memory 'net-vhostuser' test cases (RHEL-84133) - qemuValidateDomainDeviceDefNetwork: Require shared memory for all vhost-user interfaces (RHEL-84133) - qemu: process: Remove un-updated 'qemuProcessStartWarnShmem' (RHEL-84133) Resolves: RHEL-81041, RHEL-83064, RHEL-84133
423 lines
15 KiB
Diff
423 lines
15 KiB
Diff
From f4dffda866c49db8cd905d7fb4d35a70c996fa89 Mon Sep 17 00:00:00 2001
|
|
Message-ID: <f4dffda866c49db8cd905d7fb4d35a70c996fa89.1742990721.git.jdenemar@redhat.com>
|
|
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
|
Date: Mon, 17 Feb 2025 16:30:07 +0000
|
|
Subject: [PATCH] conf: introduce support for multiple ACPI tables
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
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.
|
|
|
|
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
(cherry picked from commit 55f48d38522a4657815668dae9ed9184c8870766)
|
|
Resolves: https://issues.redhat.com/browse/RHEL-81041
|
|
---
|
|
src/conf/domain_conf.c | 92 +++++++++++++++++++++++----------
|
|
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, 134 insertions(+), 53 deletions(-)
|
|
|
|
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
index 095b9bbaa2..b0628da279 100644
|
|
--- a/src/conf/domain_conf.c
|
|
+++ b/src/conf/domain_conf.c
|
|
@@ -1456,6 +1456,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",
|
|
@@ -3890,6 +3895,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)
|
|
{
|
|
@@ -3915,7 +3929,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);
|
|
@@ -17849,40 +17865,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 (virXMLPropEnum(nodes[i], "type",
|
|
+ virDomainOsACPITableTypeFromString,
|
|
+ VIR_XML_PROP_REQUIRED,
|
|
+ &type) < 0)
|
|
+ goto error;
|
|
+
|
|
+ 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;
|
|
+ }
|
|
}
|
|
|
|
- if (STREQ_NULLABLE(tmp, "slic")) {
|
|
- VIR_FREE(tmp);
|
|
- if (!(tmp = virXMLNodeContentString(nodes[0])))
|
|
- return -1;
|
|
-
|
|
- def->os.slic_table = virFileSanitizePath(tmp);
|
|
- } else {
|
|
- virReportError(VIR_ERR_XML_ERROR,
|
|
- _("Unknown acpi table type: %1$s"),
|
|
- tmp);
|
|
- return -1;
|
|
- }
|
|
+ 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;
|
|
}
|
|
|
|
|
|
@@ -28447,11 +28480,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 2d38e8fa51..f52b80caec 100644
|
|
--- a/src/conf/domain_conf.h
|
|
+++ b/src/conf/domain_conf.h
|
|
@@ -2462,6 +2462,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;
|
|
@@ -2484,7 +2502,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 727ab52cfe..be313ad67b 100644
|
|
--- a/src/libvirt_private.syms
|
|
+++ b/src/libvirt_private.syms
|
|
@@ -609,6 +609,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 24dac0ce0f..756dd2168b 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)
|
|
@@ -5968,6 +5973,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)
|
|
@@ -6001,11 +6007,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 e82b5de2b4..e68e908994 100644
|
|
--- a/src/security/virt-aa-helper.c
|
|
+++ b/src/security/virt-aa-helper.c
|
|
@@ -1002,9 +1002,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.49.0
|