diff --git a/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch b/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch index 03bbf21..224dd74 100644 --- a/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch +++ b/SOURCES/libvirt-Add-load-average-information-type-into-virDomainGetGuestInfo.patch @@ -1,5 +1,5 @@ -From 514588d016d1e105f987d821331a578a34ccdf49 Mon Sep 17 00:00:00 2001 -Message-ID: <514588d016d1e105f987d821331a578a34ccdf49.1745925135.git.jdenemar@redhat.com> +From 9874072fc9396d609f1a0213bb06fa7e9a2fa019 Mon Sep 17 00:00:00 2001 +Message-ID: <9874072fc9396d609f1a0213bb06fa7e9a2fa019.1747908717.git.jdenemar@redhat.com> From: Martin Kletzander Date: Tue, 25 Feb 2025 15:36:03 +0100 Subject: [PATCH] Add load average information type into virDomainGetGuestInfo @@ -10,7 +10,7 @@ Signed-off-by: Martin Kletzander Reviewed-by: Peter Krempa (cherry picked from commit c52c449fd40c7263896d5f17129207b815c3a09c) -https://issues.redhat.com/browse/RHEL-88449 +https://issues.redhat.com/browse/RHEL-88447 Signed-off-by: Martin Kletzander --- diff --git a/SOURCES/libvirt-conf-Add-Intel-TDX-Quote-Generation-Service-QGS-support.patch b/SOURCES/libvirt-conf-Add-Intel-TDX-Quote-Generation-Service-QGS-support.patch new file mode 100644 index 0000000..73ee651 --- /dev/null +++ b/SOURCES/libvirt-conf-Add-Intel-TDX-Quote-Generation-Service-QGS-support.patch @@ -0,0 +1,141 @@ +From e3233ee7847c0b51267b511038724a0ab8a54484 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:16 -0400 +Subject: [PATCH] conf: Add Intel TDX Quote Generation Service(QGS) support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add element "quoteGenerationService" to tdx launch security type. +It contains only an optional unix socket address attribute, +when omitted, libvirt will use default QGS server address +"/var/run/tdx-qgs/qgs.socket". + +UNIX sockets offer the required functionality with greater +security than vsock, so libvirt only provides support for unix +socket. + +XML example: + + + 0x10000001 + xxx + xxx + xxx + + + +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Zhenzhong Duan +(cherry picked from commit 8214980432191138f052c2e32d12ae284597c8b8) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + src/conf/domain_conf.c | 35 ++++++++++++++++++++++++++++++- + src/conf/domain_conf.h | 2 ++ + src/conf/schemas/domaincommon.rng | 9 ++++++++ + 3 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 92185080a9..38179a7e59 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -3895,6 +3895,7 @@ virDomainSecDefFree(virDomainSecDef *def) + g_free(def->data.tdx.mrconfigid); + g_free(def->data.tdx.mrowner); + g_free(def->data.tdx.mrownerconfig); ++ g_free(def->data.tdx.qgs_unix_path); + break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: +@@ -13911,6 +13912,33 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def, + } + + ++static int ++virDomainTDXQGSDefParseXML(virDomainTDXDef *def, xmlXPathContextPtr ctxt) ++{ ++ g_autofree xmlNodePtr *nodes = NULL; ++ xmlNodePtr node; ++ int n; ++ ++ if ((n = virXPathNodeSet("./quoteGenerationService", ctxt, &nodes)) < 0) ++ return -1; ++ ++ if (!n) ++ return 0; ++ ++ if (n > 1) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("only a single QGS element is supported")); ++ return -1; ++ } ++ node = nodes[0]; ++ ++ def->haveQGS = true; ++ def->qgs_unix_path = virXMLPropString(node, "path"); ++ ++ return 0; ++} ++ ++ + static int + virDomainTDXDefParseXML(virDomainTDXDef *def, + xmlXPathContextPtr ctxt) +@@ -13930,7 +13958,7 @@ virDomainTDXDefParseXML(virDomainTDXDef *def, + def->mrowner = virXPathString("string(./mrOwner)", ctxt); + def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt); + +- return 0; ++ return virDomainTDXQGSDefParseXML(def, ctxt); + } + + +@@ -27261,6 +27289,11 @@ virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def) + virBufferEscapeString(childBuf, "%s\n", def->mrconfigid); + virBufferEscapeString(childBuf, "%s\n", def->mrowner); + virBufferEscapeString(childBuf, "%s\n", def->mrownerconfig); ++ if (def->haveQGS) { ++ virBufferAddLit(childBuf, "qgs_unix_path); ++ virBufferAddLit(childBuf, "/>\n"); ++ } + } + + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 0ea88e013b..85ef6fbf2c 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2965,6 +2965,8 @@ struct _virDomainTDXDef { + char *mrconfigid; + char *mrowner; + char *mrownerconfig; ++ bool haveQGS; ++ char *qgs_unix_path; + }; + + +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index 552b2f4ced..93bc128dec 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -652,6 +652,15 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +2.51.0 diff --git a/SOURCES/libvirt-conf-Add-tdx-as-launch-security-type.patch b/SOURCES/libvirt-conf-Add-tdx-as-launch-security-type.patch new file mode 100644 index 0000000..6becfaa --- /dev/null +++ b/SOURCES/libvirt-conf-Add-tdx-as-launch-security-type.patch @@ -0,0 +1,379 @@ +From 3f4f38e2f1f05b0484035f96e61ee0de130d3050 Mon Sep 17 00:00:00 2001 +Message-ID: <3f4f38e2f1f05b0484035f96e61ee0de130d3050.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:09 -0400 +Subject: [PATCH] conf: Add tdx as launch security type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When 'tdx' is used, the VM will be launched with Intel TDX feature enabled. +TDX feature supports running encrypted VM (Trust Domain, TD) under the +control of KVM. A TD runs in a CPU model which protects the confidentiality +of its memory and its CPU state from other software. + +There are four optional child elements. Element policy is 64bit hex, bit 0 +is set to enable TDX debug, bit 28 is set to enable sept-ve-disable, other +bits are reserved currently. When policy isn't specified, QEMU will use its +own default value 0x10000000. mrConfigId, mrOwner and mrOwnerConfig are +base64 encoded SHA384 digest string. + +For example: + + + 0x10000001 + xxx + xxx + xxx + + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit e919a4dd374535511d962bee2cd64f22f1ac3fa1) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini + +RHEL: context +--- + src/conf/domain_conf.c | 49 +++++++++++++++++++++++++++++++ + src/conf/domain_conf.h | 11 +++++++ + src/conf/domain_validate.c | 1 + + src/conf/schemas/domaincommon.rng | 32 ++++++++++++++++++++ + src/conf/virconftypes.h | 2 ++ + src/qemu/qemu_cgroup.c | 1 + + src/qemu/qemu_command.c | 3 ++ + src/qemu/qemu_driver.c | 1 + + src/qemu/qemu_firmware.c | 1 + + src/qemu/qemu_namespace.c | 1 + + src/qemu/qemu_process.c | 2 ++ + src/qemu/qemu_validate.c | 1 + + src/security/security_dac.c | 2 ++ + 13 files changed, 107 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 286e59a4c7..92185080a9 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1538,6 +1538,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, + "sev", + "sev-snp", + "s390-pv", ++ "tdx", + ); + + VIR_ENUM_IMPL(virDomainPstoreBackend, +@@ -3890,6 +3891,11 @@ virDomainSecDefFree(virDomainSecDef *def) + g_free(def->data.sev_snp.id_auth); + g_free(def->data.sev_snp.host_data); + break; ++ case VIR_DOMAIN_LAUNCH_SECURITY_TDX: ++ g_free(def->data.tdx.mrconfigid); ++ g_free(def->data.tdx.mrowner); ++ g_free(def->data.tdx.mrownerconfig); ++ break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: +@@ -13905,6 +13911,29 @@ virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def, + } + + ++static int ++virDomainTDXDefParseXML(virDomainTDXDef *def, ++ xmlXPathContextPtr ctxt) ++{ ++ int rc; ++ ++ rc = virXPathULongLongBase("string(./policy)", ctxt, 16, &def->policy); ++ if (rc == 0) { ++ def->havePolicy = true; ++ } else if (rc == -2) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("failed to get launch security policy for launch security type TDX")); ++ return -1; ++ } ++ ++ def->mrconfigid = virXPathString("string(./mrConfigId)", ctxt); ++ def->mrowner = virXPathString("string(./mrOwner)", ctxt); ++ def->mrownerconfig = virXPathString("string(./mrOwnerConfig)", ctxt); ++ ++ return 0; ++} ++ ++ + static virDomainSecDef * + virDomainSecDefParseXML(xmlNodePtr lsecNode, + xmlXPathContextPtr ctxt) +@@ -13928,6 +13957,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode, + if (virDomainSEVSNPDefParseXML(&sec->data.sev_snp, ctxt) < 0) + return NULL; + break; ++ case VIR_DOMAIN_LAUNCH_SECURITY_TDX: ++ if (virDomainTDXDefParseXML(&sec->data.tdx, ctxt) < 0) ++ return NULL; ++ break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + break; + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: +@@ -27219,6 +27252,18 @@ virDomainSEVSNPDefFormat(virBuffer *attrBuf, + } + + ++static void ++virDomainTDXDefFormat(virBuffer *childBuf, virDomainTDXDef *def) ++{ ++ if (def->havePolicy) ++ virBufferAsprintf(childBuf, "0x%llx\n", def->policy); ++ ++ virBufferEscapeString(childBuf, "%s\n", def->mrconfigid); ++ virBufferEscapeString(childBuf, "%s\n", def->mrowner); ++ virBufferEscapeString(childBuf, "%s\n", def->mrownerconfig); ++} ++ ++ + static void + virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) + { +@@ -27240,6 +27285,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) + virDomainSEVSNPDefFormat(&attrBuf, &childBuf, &sec->data.sev_snp); + break; + ++ case VIR_DOMAIN_LAUNCH_SECURITY_TDX: ++ virDomainTDXDefFormat(&childBuf, &sec->data.tdx); ++ break; ++ + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + break; + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index e59d2e6c5f..1238f2001f 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2924,6 +2924,7 @@ typedef enum { + VIR_DOMAIN_LAUNCH_SECURITY_SEV, + VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP, + VIR_DOMAIN_LAUNCH_SECURITY_PV, ++ VIR_DOMAIN_LAUNCH_SECURITY_TDX, + + VIR_DOMAIN_LAUNCH_SECURITY_LAST, + } virDomainLaunchSecurity; +@@ -2958,11 +2959,21 @@ struct _virDomainSEVSNPDef { + }; + + ++struct _virDomainTDXDef { ++ bool havePolicy; ++ unsigned long long policy; ++ char *mrconfigid; ++ char *mrowner; ++ char *mrownerconfig; ++}; ++ ++ + struct _virDomainSecDef { + virDomainLaunchSecurity sectype; + union { + virDomainSEVDef sev; + virDomainSEVSNPDef sev_snp; ++ virDomainTDXDef tdx; + } data; + }; + +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index 522fd0174f..2d4b79032b 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -1860,6 +1860,7 @@ virDomainDefLaunchSecurityValidate(const virDomainDef *def) + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_PV: ++ case VIR_DOMAIN_LAUNCH_SECURITY_TDX: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: + break; + } +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index 1b153acc48..552b2f4ced 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -528,6 +528,9 @@ + s390-pv + + ++ ++ ++ + + + +@@ -623,6 +626,35 @@ + + + ++ ++ ++ ++ tdx ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + +@@ -541,6 +544,17 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +2.49.0 diff --git a/SOURCES/libvirt-cpu_map-Add-sha512-sm3-and-sm4-CPU-features.patch b/SOURCES/libvirt-cpu_map-Add-sha512-sm3-and-sm4-CPU-features.patch new file mode 100644 index 0000000..35a1057 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-sha512-sm3-and-sm4-CPU-features.patch @@ -0,0 +1,46 @@ +From a28c3abf6f5c7c1d8d45b3fc681f6768e2a3d7a9 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Jiri Denemark +Date: Wed, 18 Dec 2024 13:27:40 +0100 +Subject: [PATCH] cpu_map: Add sha512, sm3, and sm4 CPU features + +Introduced by Clearwater Forest platform. + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +(cherry picked from commit 212b7d8e280cabddef1f0996bd9553c6a55babd8) + +https://issues.redhat.com/browse/RHEL-71898 + +Signed-off-by: Jiri Denemark +(cherry picked from commit 153ee694e806ebf1ba684c1b7ddfa7a90c9d3adf) + +https://issues.redhat.com/browse/RHEL-87796 + +Signed-off-by: Jiri Denemark +--- + src/cpu_map/x86_features.xml | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 8be8fab42e..0e1fee6e98 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -416,6 +416,15 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +-- +2.49.0 diff --git a/SOURCES/libvirt-docs-domain-Add-documentation-for-Intel-TDX-guest.patch b/SOURCES/libvirt-docs-domain-Add-documentation-for-Intel-TDX-guest.patch new file mode 100644 index 0000000..701e486 --- /dev/null +++ b/SOURCES/libvirt-docs-domain-Add-documentation-for-Intel-TDX-guest.patch @@ -0,0 +1,94 @@ +From 81832cba9c026511ccf3fecbff894f9db48fbd33 Mon Sep 17 00:00:00 2001 +Message-ID: <81832cba9c026511ccf3fecbff894f9db48fbd33.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:25 -0400 +Subject: [PATCH] docs: domain: Add documentation for Intel TDX guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Zhenzhong Duan +(cherry picked from commit 5e5528ef14b600a43070c7efc3877e3840725dec) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + docs/formatdomain.rst | 63 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 63 insertions(+) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 847c9ebc6e..bfe28759e7 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -9294,6 +9294,69 @@ The ```` element then accepts the following child elements: + the SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI. + + ++The contents of the ```` element is used to provide ++the guest owners input used for creating an encrypted VM using the Intel TDX ++(Trusted Domain eXtensions). Intel TDX refers to an Intel technology that ++extends Virtual Machine Extensions (VMX) and Multi-Key Total Memory Encryption ++(MKTME) with a new kind of virtual machine guest called a Trust Domain (TD). ++A TD runs in a CPU mode that is designed to protect the confidentiality of its ++memory contents and its CPU state from any other software, including the hosting ++Virtual Machine Monitor (VMM), unless explicitly shared by the TD itself. ++Example configuration: ++ ++:: ++ ++ ++ ... ++ ++ 0x10000001 ++ xxx ++ xxx ++ xxx ++ ++ ++ ... ++ ++ ++``policy`` ++ The optional ``policy`` element provides the guest TD attributes which is ++ passed by the host VMM as a guest TD initialization parameter as part of ++ TD_PARAMS, it exactly matches the definition of TD_PARAMS.ATTRIBUTES in ++ (Intel TDX Module Spec Table 22.2: ATTRIBUTES Definition). It is reported ++ to the guest TD by TDG.VP.INFO and as part of TDREPORT_STRUCT returned by ++ TDG.MR.REPORT. The guest policy is 64bit unsigned with the fields shown ++ in Table: ++ ++ ====== ==================================================================================== ++ Bit(s) Description ++ ====== ==================================================================================== ++ 0 Guest TD runs in off-TD debug mode when set ++ 1:27 reserved ++ 28 Disable EPT violation conversion to #VE on guest TD access of PENDING pages when set ++ 29:63 reserved ++ ====== ==================================================================================== ++ ++``mrConfigId`` ++ The optional ``mrConfigId`` element provides ID for non-owner-defined ++ configuration of the guest TD, e.g., run-time or OS configuration ++ (base64 encoded SHA384 digest). ++ ++``@mrOwner`` ++ The optional ``@mrOwner`` element provides ID for the guest TD’s owner ++ (base64 encoded SHA384 digest). ++ ++``mrOwnerConfig`` ++ The optional ``mrOwnerConfig`` element provides ID for owner-defined ++ configuration of the guest TD, e.g., specific to the workload rather than ++ the run-time or OS (base64 encoded SHA384 digest). ++ ++``quoteGenerationService`` ++ The optional ``quoteGenerationService`` subelement provides Quote Generation ++ Service(QGS) daemon socket address configuration. It includes an optional ++ ``path`` attribute to determine the UNIX socket address, when omitted, ++ ``/var/run/tdx-qgs/qgs.socket`` is used as default. User in TD guest cannot ++ get TD quoting for attestation if this subelement is not provided. ++ + Example configs + =============== + +-- +2.51.0 diff --git a/SOURCES/libvirt-docs-formatdomain-document-intel-only-IOMMU-attributes.patch b/SOURCES/libvirt-docs-formatdomain-document-intel-only-IOMMU-attributes.patch new file mode 100644 index 0000000..e0038cf --- /dev/null +++ b/SOURCES/libvirt-docs-formatdomain-document-intel-only-IOMMU-attributes.patch @@ -0,0 +1,61 @@ +From 229d362a429fdcf64f91cf2422ab6a402d0af3fa Mon Sep 17 00:00:00 2001 +Message-ID: <229d362a429fdcf64f91cf2422ab6a402d0af3fa.1752749355.git.jdenemar@redhat.com> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 19 Mar 2025 01:55:02 +0100 +Subject: [PATCH] docs: formatdomain: document intel-only IOMMU attributes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit 6291b0af3dd6a34b5a0f5f56dafa881d9c262f57) + +https://issues.redhat.com/browse/RHEL-50560 + +Signed-off-by: Ján Tomko +--- + docs/formatdomain.rst | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 961d20a41d..a950ee1cb4 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -8857,14 +8857,15 @@ Example: + ``caching_mode`` + The ``caching_mode`` attribute with possible values ``on`` and ``off`` can + be used to turn on the VT-d caching mode (useful for assigned devices). +- :since:`Since 3.4.0` (QEMU/KVM only) ++ :since:`Since 3.4.0` (QEMU/KVM and ``intel`` model only) + + ``eim`` + The ``eim`` attribute (with possible values ``on`` and ``off``) can be + used to configure Extended Interrupt Mode. A q35 domain with split I/O + APIC (as described in `Hypervisor features`_), and + both interrupt remapping and EIM turned on for the IOMMU, will be able to +- use more than 255 vCPUs. :since:`Since 3.4.0` (QEMU/KVM only) ++ use more than 255 vCPUs. :since:`Since 3.4.0` (QEMU/KVM and ``intel`` model ++ only) + + ``iotlb`` + The ``iotlb`` attribute with possible values ``on`` and ``off`` can be +@@ -8874,14 +8875,14 @@ Example: + ``aw_bits`` + The ``aw_bits`` attribute can be used to set the address width to allow + mapping larger iova addresses in the guest. :since:`Since 6.5.0` (QEMU/KVM +- only) ++ and ``intel`` model only) + + ``dma_translation`` + The ``dma_translation`` attribute with possible values ``on`` and ``off`` can + be used to turn off the dma translation for IOMMU. It is useful when only + interrupt remapping is required but dma translation overhead is unwanted, for + example to efficiently enable more than 255 vCPUs. +- :since:`Since 10.7.0` (QEMU/KVM only) ++ :since:`Since 10.7.0` (QEMU/KVM and ``intel`` model only) + + The ``virtio`` IOMMU devices can further have ``address`` element as described + in `Device addresses`_ (address has to by type of ``pci``). +-- +2.50.1 diff --git a/SOURCES/libvirt-esx-Accept-empty-path-URI-component-same-way-as.patch b/SOURCES/libvirt-esx-Accept-empty-path-URI-component-same-way-as.patch new file mode 100644 index 0000000..93bf0a0 --- /dev/null +++ b/SOURCES/libvirt-esx-Accept-empty-path-URI-component-same-way-as.patch @@ -0,0 +1,49 @@ +From e9899b64816f8086038098b44690df076d93d8d8 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Tue, 8 Apr 2025 16:25:37 +0200 +Subject: [PATCH] esx: Accept empty "path" URI component same way as "/" + +When connecting to "esx://" URI there's code which prints a warning that +the path is not "empty". The check validates that "uri->path" is "/". + +In case when the user uses URI such as: + + esx://hostname + +the warning is printed as well. Since there is no effective difference +betweeen the two allow empty strings as well. + +Resolves: https://issues.redhat.com/browse/RHEL-86459 +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 59f40ba67cc7d0a3f8eeb601c2f3c84def24a361) +--- + src/esx/esx_driver.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c +index 6ae4ef9658..512ca6c028 100644 +--- a/src/esx/esx_driver.c ++++ b/src/esx/esx_driver.c +@@ -687,7 +687,9 @@ esxConnectToVCenter(esxPrivate *priv, + g_autofree char *url = NULL; + + if (!hostSystemIPAddress && +- (!priv->parsedUri->path || STREQ(priv->parsedUri->path, "/"))) { ++ (!priv->parsedUri->path || ++ STREQ(priv->parsedUri->path, "") || ++ STREQ(priv->parsedUri->path, "/"))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Path has to specify the datacenter and compute resource")); + return -1; +@@ -799,6 +801,7 @@ esxConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, + virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + + if (STRCASENEQ(conn->uri->scheme, "vpx") && ++ STRNEQ(conn->uri->path, "") && + STRNEQ(conn->uri->path, "/")) { + VIR_WARN("Ignoring unexpected path '%s' for non-vpx scheme '%s'", + conn->uri->path, conn->uri->scheme); +-- +2.49.0 diff --git a/SOURCES/libvirt-esx-Allow-specifying-different-CA-bundle-for-remote-connections.patch b/SOURCES/libvirt-esx-Allow-specifying-different-CA-bundle-for-remote-connections.patch index 468f8fd..5114e44 100644 --- a/SOURCES/libvirt-esx-Allow-specifying-different-CA-bundle-for-remote-connections.patch +++ b/SOURCES/libvirt-esx-Allow-specifying-different-CA-bundle-for-remote-connections.patch @@ -1,5 +1,5 @@ -From 018bb4a28e986278bb9a6e8d9bec93cb8047b7ce Mon Sep 17 00:00:00 2001 -Message-ID: <018bb4a28e986278bb9a6e8d9bec93cb8047b7ce.1752834529.git.jdenemar@redhat.com> +From b554cae09e7870484240b023865bd13fe56878d1 Mon Sep 17 00:00:00 2001 +Message-ID: From: Martin Kletzander Date: Mon, 9 Jun 2025 15:40:12 +0200 Subject: [PATCH] esx: Allow specifying different CA bundle for remote @@ -15,7 +15,7 @@ Signed-off-by: Martin Kletzander Reviewed-by: Ján Tomko (cherry picked from commit 6c9a0beeca1c6a54eda5d15ba27925c734d51279) -Resolves: https://issues.redhat.com/browse/RHEL-98292 +Resolves: https://issues.redhat.com/browse/RHEL-97440 Signed-off-by: Martin Kletzander --- diff --git a/SOURCES/libvirt-esxConnectListAllDomains-Don-t-propagate-failure-to-lookup-a-single-domain.patch b/SOURCES/libvirt-esxConnectListAllDomains-Don-t-propagate-failure-to-lookup-a-single-domain.patch new file mode 100644 index 0000000..0a685b2 --- /dev/null +++ b/SOURCES/libvirt-esxConnectListAllDomains-Don-t-propagate-failure-to-lookup-a-single-domain.patch @@ -0,0 +1,63 @@ +From 7caecd5f75f22d6bab74efcb3bc151f8bf441ec9 Mon Sep 17 00:00:00 2001 +Message-ID: <7caecd5f75f22d6bab74efcb3bc151f8bf441ec9.1744876587.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Tue, 25 Mar 2025 07:23:01 +0100 +Subject: [PATCH] esxConnectListAllDomains: Don't propagate failure to lookup a + single domain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In esxConnectListAllDomains if the lookup of the VM name and UUID fails +for a single VM (possible e.g. with broken storage) the whole API would +return failure even when there are working VMs. + +Rework the lookup so that if a subset fails we ignore the failure on +those. We report an error only if lookup of all of the objects failed. +Failure is reported from the last one. + +Resolves: https://issues.redhat.com/browse/RHEL-80606 +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 7d4de62cfa8c684b2d63a48c71f0ae009acddf62) +--- + src/esx/esx_driver.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c +index 554fb3e18f..6ae4ef9658 100644 +--- a/src/esx/esx_driver.c ++++ b/src/esx/esx_driver.c +@@ -4792,18 +4792,20 @@ esxConnectListAllDomains(virConnectPtr conn, + virtualMachine = virtualMachine->_next) { + g_autofree char *name = NULL; + +- if (needIdentity) { +- if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, +- &name, uuid) < 0) { +- goto cleanup; +- } +- } ++ /* If the lookup of the required properties fails for some of the machines ++ * in the list it's preferrable to return the valid objects instead of ++ * failing outright */ ++ if ((needIdentity && esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, uuid) < 0) || ++ (needPowerState && esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0)) { + +- if (needPowerState) { +- if (esxVI_GetVirtualMachinePowerState(virtualMachine, +- &powerState) < 0) { ++ /* Raise error only if we didn't successfuly fill any domain */ ++ if (count == 0 && !virtualMachine->_next) + goto cleanup; +- } ++ ++ /* failure to fetch information of a single VM must not interrupt ++ * the lookup of the rest */ ++ virResetLastError(); ++ continue; + } + + /* filter by active state */ +-- +2.49.0 diff --git a/SOURCES/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch b/SOURCES/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch index 7f21f5b..76dd0fb 100644 --- a/SOURCES/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch +++ b/SOURCES/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch @@ -1,5 +1,5 @@ -From ac453665a65559a7fb8b88d3f96cc275606ab51f Mon Sep 17 00:00:00 2001 -Message-ID: +From 0b2b30820c623e11aced21adb1692ed23430c064 Mon Sep 17 00:00:00 2001 +Message-ID: <0b2b30820c623e11aced21adb1692ed23430c064.1749039441.git.jdenemar@redhat.com> From: Collin Walling Date: Mon, 16 Dec 2024 18:03:55 -0500 Subject: [PATCH] libvirt-domain: introduce @@ -11,7 +11,7 @@ domain's CPU model. Signed-off-by: Collin Walling Reviewed-by: Jiri Denemark (cherry picked from commit 4e2c8de2047e21d98443944a2bfe94529b269efa) -JIRA: https://issues.redhat.com/browse/RHEL-89977 +JIRA: https://issues.redhat.com/browse/RHEL-89415 Signed-off-by: Thomas Huth --- include/libvirt/libvirt-domain.h | 12 ++++++++++++ diff --git a/SOURCES/libvirt-libvirt-host-Clarify-fix-description-of-the-CPU-frequency-field.patch b/SOURCES/libvirt-libvirt-host-Clarify-fix-description-of-the-CPU-frequency-field.patch new file mode 100644 index 0000000..81a06ec --- /dev/null +++ b/SOURCES/libvirt-libvirt-host-Clarify-fix-description-of-the-CPU-frequency-field.patch @@ -0,0 +1,51 @@ +From a96d1c90832b639c81f6cd893a79610d4379594d Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Mon, 7 Apr 2025 13:35:37 +0200 +Subject: [PATCH] libvirt-host: Clarify/fix description of the CPU frequency + field + +The 'virNodeInfo' field for CPU frequency is named 'mhz'. The docs were +mentioning 'mHZ', which is neither the field name nor proper spelling of +the unit. + +Reword the paragraph to mention "CPU frequency" instead and explicitly +name the field in virNodeInfo struct. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit e54cc1500ccfb36cd5b67eb4d886c491fdda5b2b) + +https://issues.redhat.com/browse/RHEL-86197 +--- + src/libvirt-host.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/libvirt-host.c b/src/libvirt-host.c +index b3a6421a7f..318a664d24 100644 +--- a/src/libvirt-host.c ++++ b/src/libvirt-host.c +@@ -410,9 +410,9 @@ virConnectGetMaxVcpus(virConnectPtr conn, + * Use of this API is strongly discouraged as the information provided + * is not guaranteed to be accurate on all hardware platforms. + * +- * The mHZ value merely reflects the speed that the first CPU in the +- * machine is currently running at. This speed may vary across CPUs +- * and changes continually as the host OS throttles. ++ * The CPU frequency value (field 'mhz' in virNodeInfo) merely reflects the ++ * speed that the first CPU in the machine is currently running at. This speed ++ * may vary across CPUs and changes continually as the host OS throttles. + * + * The nodes/sockets/cores/threads data is potentially inaccurate as + * it assumes a symmetric installation. If one NUMA node has more +@@ -420,7 +420,7 @@ virConnectGetMaxVcpus(virConnectPtr conn, + * wrong. It is also not able to report about CPU dies. + * + * Applications are recommended to use the virConnectGetCapabilities() +- * call instead, which provides all the information except CPU mHZ, ++ * call instead, which provides all the information except CPU frequency, + * in a more accurate representation. + * + * Returns 0 in case of success and -1 in case of failure. +-- +2.49.0 diff --git a/SOURCES/libvirt-libxl-support-rawset-ACPI-table-type.patch b/SOURCES/libvirt-libxl-support-rawset-ACPI-table-type.patch new file mode 100644 index 0000000..f1adca5 --- /dev/null +++ b/SOURCES/libvirt-libxl-support-rawset-ACPI-table-type.patch @@ -0,0 +1,85 @@ +From fb8c22b5606b2c3d0881df8df05ad1c909b247b2 Mon Sep 17 00:00:00 2001 +Message-ID: +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 26 Feb 2025 19:10:42 +0000 +Subject: [PATCH] libxl: support 'rawset' ACPI table type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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. + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit dac6ecba6f75bff11fbddb2bce8ca9b576ea6a74) +Resolves: https://issues.redhat.com/browse/RHEL-81041 +--- + docs/formatdomain.rst | 2 +- + src/libxl/libxl_domain.c | 5 +++-- + src/libxl/xen_xl.c | 2 +- + tests/xlconfigdata/test-fullvirt-acpi-slic.xml | 2 +- + 4 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index ff06efb69f..b03b5317aa 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -492,7 +492,7 @@ These options apply to any form of booting of the guest OS. + 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`). ++ (:since:`Since 11.2.0 (Xen)`). + * ``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)`, +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 @@ + hvm + /usr/lib/xen/boot/hvmloader + +- /sys/firmware/acpi/tables/SLIC
++ /sys/firmware/acpi/tables/SLIC
+
+ + +-- +2.49.0 diff --git a/SOURCES/libvirt-manpages-virsh-Use-disclaimer-from-virNodeGetInfo-for-virsh-nodeinfo.patch b/SOURCES/libvirt-manpages-virsh-Use-disclaimer-from-virNodeGetInfo-for-virsh-nodeinfo.patch new file mode 100644 index 0000000..ac94a0c --- /dev/null +++ b/SOURCES/libvirt-manpages-virsh-Use-disclaimer-from-virNodeGetInfo-for-virsh-nodeinfo.patch @@ -0,0 +1,55 @@ +From 90859b9c9cda1ab3daa34847ac4608cf451102ce Mon Sep 17 00:00:00 2001 +Message-ID: <90859b9c9cda1ab3daa34847ac4608cf451102ce.1744876588.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 7 Apr 2025 14:58:41 +0200 +Subject: [PATCH] manpages: virsh: Use disclaimer from 'virNodeGetInfo()' for + 'virsh nodeinfo' + +Adapt the disclarimer about the data not being accurate in many cases +from the API docs to the virsh command using the aforementioned API. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +(cherry picked from commit 617e2dc3194204a88309e3da55bec8743a5df2ea) + +https://issues.redhat.com/browse/RHEL-86197 +--- + docs/manpages/virsh.rst | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index 2e525d3fac..aea920b7a7 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -427,10 +427,25 @@ nodeinfo + nodeinfo + + Returns basic information about the node, like number and type of CPU, +-and size of the physical memory. The output corresponds to virNodeInfo +-structure. Specifically, the "CPU socket(s)" field means number of CPU +-sockets per NUMA cell. The information libvirt displays is dependent +-upon what each architecture may provide. ++and size of the physical memory. ++ ++Use of this command is strongly discouraged as the information provided ++is not guaranteed to be accurate on all hardware platforms. ++ ++The *CPU frequency* value merely reflects the speed that the first CPU in the ++machine is currently running at. This speed may vary across CPUs and changes ++continually as the host OS throttles. ++ ++The data structure used to fetch the data is not extensible thus only supports ++global nodes/sockets/cores/threads (sockets/cores/threads is per NUMA node) ++topology information. If the host CPU has any further groupings (e.g. ++dies, clusters, etc) or the NUMA topology is non-symmetrical the data structure ++can't faithfully represent the system. In such cases a fake topology ++(nodes = 1, sockets = 1, cores = number of host cpus, threads = 1) which ++only correctly represents the total host CPU count is reported. ++ ++Recommended replacement is to use the *capabilities* command which reports ++the data (except frequency) under ``/capabilities/host/topology`` XPath. + + + nodecpumap +-- +2.49.0 diff --git a/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch b/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch index 0a812a8..e6883dc 100644 --- a/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch +++ b/SOURCES/libvirt-network-Free-inhibitor-in-networkStateCleanup.patch @@ -1,5 +1,5 @@ -From 8e64dac6129cacd8f53813cbc7580209e96e7dc3 Mon Sep 17 00:00:00 2001 -Message-ID: <8e64dac6129cacd8f53813cbc7580209e96e7dc3.1744361503.git.jdenemar@redhat.com> +From 2ea12b6f6eed044dd7100ed19565319227f7384f Mon Sep 17 00:00:00 2001 +Message-ID: <2ea12b6f6eed044dd7100ed19565319227f7384f.1742990721.git.jdenemar@redhat.com> From: Michal Privoznik Date: Thu, 13 Mar 2025 13:01:19 +0100 Subject: [PATCH] network: Free inhibitor in networkStateCleanup() @@ -22,7 +22,7 @@ networkStateCleanup() leading to a memleak: Signed-off-by: Michal Privoznik Reviewed-by: Peter Krempa (cherry picked from commit 8701ba4feb528109da8b72fa48a8ada50a235807) -Resolves: https://issues.redhat.com/browse/RHEL-83076 +Resolves: https://issues.redhat.com/browse/RHEL-83064 --- src/network/bridge_driver.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SOURCES/libvirt-qemu-Add-FakeReboot-support-for-TDX-guest.patch b/SOURCES/libvirt-qemu-Add-FakeReboot-support-for-TDX-guest.patch new file mode 100644 index 0000000..2993619 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-FakeReboot-support-for-TDX-guest.patch @@ -0,0 +1,139 @@ +From 30e83bf71626ce8a180982feb974ac4592b0303c Mon Sep 17 00:00:00 2001 +Message-ID: <30e83bf71626ce8a180982feb974ac4592b0303c.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:18 -0400 +Subject: [PATCH] qemu: Add FakeReboot support for TDX guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Utilize the existing fake reboot mechanism to do reboot for TDX guest. + +Different from normal guest, TDX guest doesn't support system_reset, +so have to kill the old guest and start a new one to simulate the reboot. + +Co-developed-by: Chenyi Qiang +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 4f733348212b3bb4de491aeaab4ac32f0335673d) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini + +RHEL: fix arguments to qemuProcessStart, qemuProcessStop, qemuDomainRemoveInactive +--- + src/qemu/qemu_process.c | 80 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 77 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 7586248329..caf63b0ae3 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -446,6 +446,67 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED, + } + + ++/* ++ * Secure guest doesn't support fake reboot via machine CPU reset. ++ * We thus fake reboot via QEMU re-creation. ++ */ ++static void ++qemuProcessFakeRebootViaRecreate(virDomainObj *vm) ++{ ++ qemuDomainObjPrivate *priv = vm->privateData; ++ virQEMUDriver *driver = priv->driver; ++ int ret = -1; ++ ++ VIR_DEBUG("Handle secure guest reboot: destroy phase"); ++ ++ virObjectLock(vm); ++ if (qemuProcessBeginStopJob(vm, VIR_JOB_DESTROY, 0) < 0) ++ goto cleanup; ++ ++ if (virDomainObjCheckActive(vm) < 0) { ++ qemuProcessEndStopJob(vm); ++ goto cleanup; ++ } ++ ++ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED, VIR_ASYNC_JOB_NONE, 0); ++ virDomainAuditStop(vm, "destroyed"); ++ ++ /* skip remove inactive domain from active list */ ++ qemuProcessEndStopJob(vm); ++ ++ VIR_DEBUG("Handle secure guest reboot: boot phase"); ++ ++ if (qemuProcessBeginJob(vm, VIR_DOMAIN_JOB_OPERATION_START, 0) < 0) { ++ qemuDomainRemoveInactive(driver, vm, 0, false); ++ goto cleanup; ++ } ++ ++ if (qemuProcessStart(NULL, driver, vm, NULL, VIR_ASYNC_JOB_START, ++ NULL, -1, NULL, NULL, ++ VIR_NETDEV_VPORT_PROFILE_OP_CREATE, ++ 0) < 0) { ++ virDomainAuditStart(vm, "booted", false); ++ qemuDomainRemoveInactive(driver, vm, 0, false); ++ goto endjob; ++ } ++ ++ virDomainAuditStart(vm, "booted", true); ++ ++ qemuDomainSaveStatus(vm); ++ ret = 0; ++ ++ endjob: ++ qemuProcessEndJob(vm); ++ ++ cleanup: ++ priv->pausedShutdown = false; ++ qemuDomainSetFakeReboot(vm, false); ++ if (ret == -1) ++ ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE)); ++ virDomainObjEndAPI(&vm); ++} ++ ++ + /* + * Since we have the '-no-shutdown' flag set, the + * QEMU process will currently have guest OS shutdown +@@ -455,15 +516,13 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED, + * guest OS booting up again + */ + static void +-qemuProcessFakeReboot(void *opaque) ++qemuProcessFakeRebootViaReset(virDomainObj *vm) + { +- virDomainObj *vm = opaque; + qemuDomainObjPrivate *priv = vm->privateData; + virQEMUDriver *driver = priv->driver; + virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED; + int ret = -1, rc; + +- VIR_DEBUG("vm=%p", vm); + virObjectLock(vm); + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto cleanup; +@@ -509,6 +568,21 @@ qemuProcessFakeReboot(void *opaque) + } + + ++static void ++qemuProcessFakeReboot(void *opaque) ++{ ++ virDomainObj *vm = opaque; ++ ++ VIR_DEBUG("vm=%p", vm); ++ ++ if (vm->def->sec && ++ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) ++ qemuProcessFakeRebootViaRecreate(vm); ++ else ++ qemuProcessFakeRebootViaReset(vm); ++} ++ ++ + void + qemuProcessShutdownOrReboot(virDomainObj *vm) + { +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Add-QEMU_CAPS_TDX_GUEST-capability.patch b/SOURCES/libvirt-qemu-Add-QEMU_CAPS_TDX_GUEST-capability.patch new file mode 100644 index 0000000..db4c9a7 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-QEMU_CAPS_TDX_GUEST-capability.patch @@ -0,0 +1,72 @@ +From b4b30bd7eebc51bbc4b3de23db6cf3b494a8f60f Mon Sep 17 00:00:00 2001 +Message-ID: +From: Paolo Bonzini +Date: Wed, 24 Sep 2025 13:11:50 +0200 +Subject: [PATCH] qemu: Add QEMU_CAPS_TDX_GUEST capability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU_CAPS_TDX_GUEST set means TDX supported with this QEMU. + +Signed-off-by: Chenyi Qiang +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Peter Krempa +(cherry picked from commit 121fd199420e0f3f645177de78e285dfa3502935) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini + +RHEL: context +--- + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml | 1 + + 3 files changed, 4 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index ea0c42d624..f912b4cf9d 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -728,6 +728,7 @@ VIR_ENUM_IMPL(virQEMUCaps, + "blockdev-set-active", /* QEMU_CAPS_BLOCKDEV_SET_ACTIVE */ + "amd-iommu", /* QEMU_CAPS_AMD_IOMMU */ + "amd-iommu.pci-id", /* QEMU_CAPS_AMD_IOMMU_PCI_ID */ ++ "tdx-guest", /* QEMU_CAPS_TDX_GUEST */ + ); + + +@@ -1419,6 +1420,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { + { "acpi-erst", QEMU_CAPS_DEVICE_ACPI_ERST }, + { "virtio-mem-ccw", QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW }, + { "amd-iommu", QEMU_CAPS_AMD_IOMMU }, ++ { "tdx-guest", QEMU_CAPS_TDX_GUEST}, + }; + + +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 8918e8dfc4..1334a668f0 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -707,6 +707,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_BLOCKDEV_SET_ACTIVE, /* blockdev-set-active QMP command supported */ + QEMU_CAPS_AMD_IOMMU, /* -device amd-iommu */ + QEMU_CAPS_AMD_IOMMU_PCI_ID, /* amd-iommu.pci-id */ ++ QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml +index 584d515d8c..54b09813a8 100644 +--- a/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml ++++ b/tests/qemucapabilitiesdata/caps_10.1.0_x86_64+inteltdx.xml +@@ -194,6 +194,7 @@ + + + ++ + 10000050 + 43100286 + v10.0.0-1724-gf9a3def17b +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Add-command-line-and-validation-for-TDX-type.patch b/SOURCES/libvirt-qemu-Add-command-line-and-validation-for-TDX-type.patch new file mode 100644 index 0000000..a09fcde --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-command-line-and-validation-for-TDX-type.patch @@ -0,0 +1,118 @@ +From 2fa4ab6a8a776f41e64bcd7a3f1bf0f76e54f8db Mon Sep 17 00:00:00 2001 +Message-ID: <2fa4ab6a8a776f41e64bcd7a3f1bf0f76e54f8db.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:11 -0400 +Subject: [PATCH] qemu: Add command line and validation for TDX type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU will provides 'tdx-guest' object which is used to launch encrypted +VMs on Intel platform using TDX feature. + +Command line looks like: +$QEMU ... \ + -object '{"qom-type":"tdx-guest","id":"lsec0","mrconfigid":"xxx","mrowner":"xxx","mrownerconfig":"xxx","attributes":268435457}' \ + -machine pc-q35-6.0,confidential-guest-support=lsec0 + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 67b0720d2f2a16ab59a11aa8ecccfe11c73d8727) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini + +RHEL: pass priv->qemuCaps to qemuBuildObjectCommandlineFromJSON +--- + src/conf/domain_conf.h | 5 +++++ + src/qemu/qemu_command.c | 29 +++++++++++++++++++++++++++++ + src/qemu/qemu_validate.c | 12 ++++++++++++ + 3 files changed, 46 insertions(+) + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 1238f2001f..0ea88e013b 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2968,6 +2968,11 @@ struct _virDomainTDXDef { + }; + + ++#define VIR_DOMAIN_TDX_POLICY_DEBUG 0x1 ++#define VIR_DOMAIN_TDX_POLICY_SEPT_VE_DISABLE 0x10000000 ++#define VIR_DOMAIN_TDX_POLICY_ALLOWED_MASK (VIR_DOMAIN_TDX_POLICY_DEBUG | \ ++ VIR_DOMAIN_TDX_POLICY_SEPT_VE_DISABLE) ++ + struct _virDomainSecDef { + virDomainLaunchSecurity sectype; + union { +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 6c5e1926a5..c2183d332e 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -9750,6 +9750,34 @@ qemuBuildPVCommandLine(virDomainObj *vm, virCommand *cmd) + } + + ++static int ++qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd, ++ virDomainTDXDef *tdx) ++{ ++ g_autoptr(virJSONValue) props = NULL; ++ qemuDomainObjPrivate *priv = vm->privateData; ++ ++ if (tdx->havePolicy) ++ VIR_DEBUG("policy=0x%llx", tdx->policy); ++ ++ if (qemuMonitorCreateObjectProps(&props, "tdx-guest", "lsec0", ++ "S:mrconfigid", tdx->mrconfigid, ++ "S:mrowner", tdx->mrowner, ++ "S:mrownerconfig", tdx->mrownerconfig, ++ NULL) < 0) ++ return -1; ++ ++ if (tdx->havePolicy && ++ virJSONValueObjectAdd(&props, "U:attributes", tdx->policy, NULL) < 0) ++ return -1; ++ ++ if (qemuBuildObjectCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ + static int + qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd, + virDomainSecDef *sec) +@@ -9769,6 +9797,7 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd, + break; + + case VIR_DOMAIN_LAUNCH_SECURITY_TDX: ++ return qemuBuildTDXCommandLine(vm, cmd, &sec->data.tdx); + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: + virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype); +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 34bb7e45c7..80aa2529f2 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -1392,6 +1392,18 @@ qemuValidateDomainDef(const virDomainDef *def, + } + break; + case VIR_DOMAIN_LAUNCH_SECURITY_TDX: ++ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Intel TDX launch security is not supported with this QEMU binary")); ++ return -1; ++ } ++ if (def->sec->data.tdx.havePolicy && ++ def->sec->data.tdx.policy & ~VIR_DOMAIN_TDX_POLICY_ALLOWED_MASK) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Only bit0(debug) and bit28(sept-ve-disable) are supported intel TDX launch security policy")); ++ return -1; ++ } ++ break; + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: + virReportEnumRangeError(virDomainLaunchSecurity, def->sec->sectype); +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Add-command-line-for-TDX-Quote-Generation-Service-QGS.patch b/SOURCES/libvirt-qemu-Add-command-line-for-TDX-Quote-Generation-Service-QGS.patch new file mode 100644 index 0000000..ad0ce78 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-command-line-for-TDX-Quote-Generation-Service-QGS.patch @@ -0,0 +1,84 @@ +From ed45ed36365fd14833c74d6143678afdf8448dc7 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Paolo Bonzini +Date: Wed, 24 Sep 2025 12:41:09 +0200 +Subject: [PATCH] qemu: Add command line for TDX Quote Generation Service(QGS) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +'tdx-guest' object supports a "quote-generation-socket" property for +attestation purpose. When "quote-generation-socket" is configured in +guest xml, libvirt generates unix socket format cmdline for QEMU. + +'Path' element can be omitted, default path "/var/run/tdx-qgs/qgs.socket" +is used in this case. + +QEMU command line example: + qemu-system-x86_64 \ + -object '{"qom-type":"tdx-guest","id":"lsec0","mrconfigid":"xxx","mrowner":"xxx","mrownerconfig":"xxx","quote-generation-socket":{"type":"unix","path":"/var/run/tdx-qgs/qgs.socket"},"attributes":268435457}' \ + -machine pc-q35-6.0,confidential-guest-support=lsec0 + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 61c4c1b538eed608315c21126b4bd1d26f972512) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini + +RHEL: context +--- + src/conf/domain_conf.h | 3 +++ + src/qemu/qemu_command.c | 14 ++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 85ef6fbf2c..15aacc71c1 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2959,6 +2959,9 @@ struct _virDomainSEVSNPDef { + }; + + ++/* Copied from QGS source code */ ++#define QGS_UNIX_SOCKET_FILE "/var/run/tdx-qgs/qgs.socket" ++ + struct _virDomainTDXDef { + bool havePolicy; + unsigned long long policy; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index c2183d332e..c6b826a007 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -9754,16 +9754,30 @@ static int + qemuBuildTDXCommandLine(virDomainObj *vm, virCommand *cmd, + virDomainTDXDef *tdx) + { ++ g_autoptr(virJSONValue) addr = NULL; + g_autoptr(virJSONValue) props = NULL; + qemuDomainObjPrivate *priv = vm->privateData; ++ const char *path = QGS_UNIX_SOCKET_FILE; + + if (tdx->havePolicy) + VIR_DEBUG("policy=0x%llx", tdx->policy); + ++ if (tdx->haveQGS) { ++ if (tdx->qgs_unix_path) ++ path = tdx->qgs_unix_path; ++ ++ if (virJSONValueObjectAdd(&addr, ++ "s:type", "unix", ++ "s:path", path, ++ NULL) < 0) ++ return -1; ++ } ++ + if (qemuMonitorCreateObjectProps(&props, "tdx-guest", "lsec0", + "S:mrconfigid", tdx->mrconfigid, + "S:mrowner", tdx->mrowner, + "S:mrownerconfig", tdx->mrownerconfig, ++ "A:quote-generation-socket", &addr, + NULL) < 0) + return -1; + +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch b/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch index ccb387b..c78f850 100644 --- a/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch +++ b/SOURCES/libvirt-qemu-Add-support-for-VIR_DOMAIN_GUEST_INFO_LOAD.patch @@ -1,5 +1,5 @@ -From 816ce9100cbc410706fde26763158640f6d06f44 Mon Sep 17 00:00:00 2001 -Message-ID: <816ce9100cbc410706fde26763158640f6d06f44.1745925135.git.jdenemar@redhat.com> +From aeff1ebf96b595337f14ef6d1412d6c407bdc085 Mon Sep 17 00:00:00 2001 +Message-ID: From: Martin Kletzander Date: Tue, 25 Feb 2025 15:36:32 +0100 Subject: [PATCH] qemu: Add support for VIR_DOMAIN_GUEST_INFO_LOAD @@ -8,7 +8,7 @@ Signed-off-by: Martin Kletzander Reviewed-by: Peter Krempa (cherry picked from commit b4cf9c8cba45e65551aa9440dea2c3757a96aa0c) -https://issues.redhat.com/browse/RHEL-88449 +https://issues.redhat.com/browse/RHEL-88447 Signed-off-by: Martin Kletzander --- @@ -16,10 +16,10 @@ Signed-off-by: Martin Kletzander 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c -index d65fc542d1..3e194999fe 100644 +index 8a354a606a..11dbbc1aab 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c -@@ -19288,7 +19288,8 @@ static const unsigned int qemuDomainGetGuestInfoSupportedTypes = +@@ -19276,7 +19276,8 @@ static const unsigned int qemuDomainGetGuestInfoSupportedTypes = VIR_DOMAIN_GUEST_INFO_HOSTNAME | VIR_DOMAIN_GUEST_INFO_FILESYSTEM | VIR_DOMAIN_GUEST_INFO_DISKS | @@ -29,7 +29,7 @@ index d65fc542d1..3e194999fe 100644 static int qemuDomainGetGuestInfoCheckSupport(unsigned int types, -@@ -19575,6 +19576,10 @@ qemuDomainGetGuestInfo(virDomainPtr dom, +@@ -19563,6 +19564,10 @@ qemuDomainGetGuestInfo(virDomainPtr dom, qemuAgentDiskInfo **agentdiskinfo = NULL; virDomainInterfacePtr *ifaces = NULL; size_t nifaces = 0; @@ -40,7 +40,7 @@ index d65fc542d1..3e194999fe 100644 size_t i; virCheckFlags(0, -1); -@@ -19645,6 +19650,14 @@ qemuDomainGetGuestInfo(virDomainPtr dom, +@@ -19633,6 +19638,14 @@ qemuDomainGetGuestInfo(virDomainPtr dom, nifaces = rc; } @@ -55,7 +55,7 @@ index d65fc542d1..3e194999fe 100644 qemuDomainObjExitAgent(vm, agent); virDomainObjEndAgentJob(vm); -@@ -19671,6 +19684,12 @@ qemuDomainGetGuestInfo(virDomainPtr dom, +@@ -19659,6 +19672,12 @@ qemuDomainGetGuestInfo(virDomainPtr dom, virDomainInterfaceFormatParams(ifaces, nifaces, params, nparams, &maxparams); } diff --git a/SOURCES/libvirt-qemu-Allow-virtio-mem-on-CCW.patch b/SOURCES/libvirt-qemu-Allow-virtio-mem-on-CCW.patch new file mode 100644 index 0000000..6eda024 --- /dev/null +++ b/SOURCES/libvirt-qemu-Allow-virtio-mem-on-CCW.patch @@ -0,0 +1,36 @@ +From 5c4270439f99bd52f91613a6ee833aa4bcb131c4 Mon Sep 17 00:00:00 2001 +Message-ID: <5c4270439f99bd52f91613a6ee833aa4bcb131c4.1744876588.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Wed, 15 Jan 2025 13:00:36 +0100 +Subject: [PATCH] qemu: Allow virtio-mem on CCW + +After previous commits, we can allow virtio-mem to live on CCW +channel. + +Signed-off-by: Michal Privoznik +Reviewed-by: Boris Fiuczynski +(cherry picked from commit ee0320a7fccc8088bc2830fe949ae2339db208cb) +Resolves: https://issues.redhat.com/browse/RHEL-72976 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_domain.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index b6c36d85d7..4234e4605b 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -7673,9 +7673,10 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem, + + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && ++ mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && + mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +- _("only 'pci' addresses are supported for the %1$s device"), ++ _("only 'pci' and 'ccw' addresses are supported for the %1$s device"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch b/SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch new file mode 100644 index 0000000..7eb1537 --- /dev/null +++ b/SOURCES/libvirt-qemu-Avoid-crash-in-qemuDomainCheckCPU-with-unknown-host-CPU.patch @@ -0,0 +1,38 @@ +From d874530eaded03d0b90139c9bbd80902b9464e87 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Jiri Denemark +Date: Tue, 18 Feb 2025 11:24:32 +0100 +Subject: [PATCH] qemu: Avoid crash in qemuDomainCheckCPU with unknown host CPU + +When we don't have any information about host CPU (for example when +running on an aarch64 host), the virQEMUCapsGetHostModel would return +NULL. + +Fixes: f928eb5fc80ca0ed7277f2513b63aed36c09d275 +Fixes: https://gitlab.com/libvirt/libvirt/-/issues/747 +Signed-off-by: Jiri Denemark +Tested-by: Jaroslav Suchanek +Reviewed-by: Michal Privoznik +(cherry picked from commit 43eae1b7077104d4e2ed52447407a335c2d093e3) + +https://issues.redhat.com/browse/RHEL-81747 + +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 92035dd281..1ccaff90d9 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -11446,6 +11446,7 @@ qemuDomainCheckCPU(virArch arch, + /* Force compat check if the CPU model is not found in qemuCaps or + * we don't have host CPU data from QEMU */ + if (!cpu->model || ++ !hypervisorCPU || + hypervisorCPU->fallback != VIR_CPU_FALLBACK_FORBID || + virQEMUCapsGetCPUBlockers(qemuCaps, virtType, + cpu->model, &blockers) < 0) +-- +2.48.1 diff --git a/SOURCES/libvirt-qemu-Avoid-duplicate-FakeReboot-for-secure-guest.patch b/SOURCES/libvirt-qemu-Avoid-duplicate-FakeReboot-for-secure-guest.patch new file mode 100644 index 0000000..5b582cd --- /dev/null +++ b/SOURCES/libvirt-qemu-Avoid-duplicate-FakeReboot-for-secure-guest.patch @@ -0,0 +1,48 @@ +From 80e6f292a501cc9bc8b2d5197c339326ecff0323 Mon Sep 17 00:00:00 2001 +Message-ID: <80e6f292a501cc9bc8b2d5197c339326ecff0323.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:20 -0400 +Subject: [PATCH] qemu: Avoid duplicate FakeReboot for secure guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For secure guest, FakeReboot kills original QEMU instance and +create new one. During this process, QEMU send SHUTDOWN event +with "host-signal" reason which can trigger another FakeReboot. + +Check if a FakeReboot is ongoing and bypass "host-signal" +processing which originally comes from FakeReboot. + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 194a36f4fe14b489b4697396d908c2a2c578ca5c) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + src/qemu/qemu_monitor.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 40f15c88a8..6d19b675d5 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1076,6 +1076,16 @@ qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest, + * with it here. */ + if (vm->def->sec && + vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) { ++ qemuDomainObjPrivate *priv = vm->privateData; ++ ++ /* For secure guest, FakeReboot kills original QEMU instance and ++ * create new one. During this process, QEMU send SHUTDOWN event ++ * with "host-signal" reason which can trigger another FakeReboot. ++ * Check if a FakeReboot is ongoing and bypass "host-signal" ++ * processing which is originally come from FakeReboot. */ ++ if (priv->fakeReboot && STREQ_NULLABLE(reason, "host-signal")) ++ return; ++ + if ((STREQ_NULLABLE(reason, "guest-shutdown") && + vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) || + (STREQ_NULLABLE(reason, "guest-reset") && +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Check-if-INTEL-Trust-Domain-Extention-support-is-enabled.patch b/SOURCES/libvirt-qemu-Check-if-INTEL-Trust-Domain-Extention-support-is-enabled.patch new file mode 100644 index 0000000..464c2fd --- /dev/null +++ b/SOURCES/libvirt-qemu-Check-if-INTEL-Trust-Domain-Extention-support-is-enabled.patch @@ -0,0 +1,68 @@ +From 7eff4d32f92fa15ffa3705b977cf8e29d41f6d26 Mon Sep 17 00:00:00 2001 +Message-ID: <7eff4d32f92fa15ffa3705b977cf8e29d41f6d26.1759835599.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:04 -0400 +Subject: [PATCH] qemu: Check if INTEL Trust Domain Extention support is + enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Implement TDX check in order to generate domain feature capability +correctly in case the availability of the feature changed. + +For INTEL TDX the verification is: + - checking if "/sys/module/kvm_intel/parameters/tdx" contains the + value 'Y': meaning TDX is enabled in the host kernel. + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Xiaoyao Li +(cherry picked from commit d7c96e809d2c446830930790db5206168aedef81) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + src/qemu/qemu_capabilities.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index d60d2d95cc..ea0c42d624 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -5308,6 +5308,24 @@ virQEMUCapsKVMSupportsSecureGuestAMD(void) + } + + ++/* ++ * Check whether INTEL Trust Domain Extention (x86) is enabled ++ */ ++static bool ++virQEMUCapsKVMSupportsSecureGuestTDX(void) ++{ ++ g_autofree char *modValue = NULL; ++ ++ if (virFileReadValueString(&modValue, "/sys/module/kvm_intel/parameters/tdx") < 0) ++ return false; ++ ++ if (modValue[0] != 'Y') ++ return false; ++ ++ return true; ++} ++ ++ + /* + * Check whether the secure guest functionality is enabled. + * See the specific architecture function for details on the verifications made. +@@ -5321,7 +5339,8 @@ virQEMUCapsKVMSupportsSecureGuest(void) + return virQEMUCapsKVMSupportsSecureGuestS390(); + + if (ARCH_IS_X86(arch)) +- return virQEMUCapsKVMSupportsSecureGuestAMD(); ++ return virQEMUCapsKVMSupportsSecureGuestAMD() || ++ virQEMUCapsKVMSupportsSecureGuestTDX(); + + return false; + } +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Do-NOT-autoadd-NUMA-node-for-s390.patch b/SOURCES/libvirt-qemu-Do-NOT-autoadd-NUMA-node-for-s390.patch new file mode 100644 index 0000000..80f172f --- /dev/null +++ b/SOURCES/libvirt-qemu-Do-NOT-autoadd-NUMA-node-for-s390.patch @@ -0,0 +1,50 @@ +From b2e5469f35657b7d46842b39be04ecc34e5ff659 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Michal Privoznik +Date: Mon, 20 Jan 2025 17:10:24 +0100 +Subject: [PATCH] qemu: Do NOT autoadd NUMA node for s390 + +In some cases, we might automatically add a NUMA node. But this +doesn't work for s390 really, because in its commit +v2.12.0-rc0~41^2~6 QEMU forbade specifying NUMA nodes for s390. +Suppress automatic adding of NUMA node on our side. + +Signed-off-by: Michal Privoznik +Reviewed-by: David Hildenbrand +Reviewed-by: Boris Fiuczynski +(cherry picked from commit a8ed747b9a8c5cbd07557edc66962bc26205d7fb) +Resolves: https://issues.redhat.com/browse/RHEL-72976 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_domain.c | 3 ++- + src/qemu/qemu_postparse.c | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 89e1b50366..b6c36d85d7 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -7761,7 +7761,8 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, + return 0; + } + +- if (!ARCH_IS_PPC64(def->os.arch)) { ++ if (!ARCH_IS_PPC64(def->os.arch) && ++ !ARCH_IS_S390(def->os.arch)) { + /* due to guest support, qemu would silently enable NUMA with one node + * once the memory hotplug backend is enabled. To avoid possible + * confusion we will enforce user originated numa configuration along +diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c +index 892330646a..141847b0ef 100644 +--- a/src/qemu/qemu_postparse.c ++++ b/src/qemu/qemu_postparse.c +@@ -1806,6 +1806,7 @@ qemuDomainDefNumaAutoAdd(virDomainDef *def, + + if (!abiUpdate || + !virDomainDefHasMemoryHotplug(def) || ++ qemuDomainIsS390CCW(def) || + virDomainNumaGetNodeCount(def->numa) > 0) { + return 0; + } +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-Force-special-parameters-enabled-for-TDX-guest.patch b/SOURCES/libvirt-qemu-Force-special-parameters-enabled-for-TDX-guest.patch new file mode 100644 index 0000000..bdc8287 --- /dev/null +++ b/SOURCES/libvirt-qemu-Force-special-parameters-enabled-for-TDX-guest.patch @@ -0,0 +1,73 @@ +From 809c8b4ebb569d283e02b869580914a6c7d9edd5 Mon Sep 17 00:00:00 2001 +Message-ID: <809c8b4ebb569d283e02b869580914a6c7d9edd5.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:13 -0400 +Subject: [PATCH] qemu: Force special parameters enabled for TDX guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TDX guest requires some special parameters to boot, currently: + + "kernel_irqchip=split" + "pmu!=on" + "smm!=on" + "-bios" + +If not specified explicitly, QEMU should configure this option implicitly +when start a TDX guest. + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 626b9ca84650966de266ff41e9df59aba948f65e) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + src/qemu/qemu_validate.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 80aa2529f2..bbd838c7f0 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -1403,6 +1403,38 @@ qemuValidateDomainDef(const virDomainDef *def, + _("Only bit0(debug) and bit28(sept-ve-disable) are supported intel TDX launch security policy")); + return -1; + } ++ if (def->features[VIR_DOMAIN_FEATURE_IOAPIC] == VIR_DOMAIN_IOAPIC_KVM) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Intel TDX launch security needs split kernel irqchip")); ++ return -1; ++ } ++ /* Current KVM doesn't support PMU for TD guest. It returns ++ * error if TD is created with PMU bit being set in attributes. ++ * By default, QEMU disable PMU for TD guest. ++ */ ++ if (def->features[VIR_DOMAIN_FEATURE_PMU] == VIR_TRISTATE_SWITCH_ON) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Intel TDX launch security is not supported with PMU enabled")); ++ return -1; ++ } ++ /* TDX doesn't support SMM and VMM cannot emulate SMM for TDX VMs ++ * because VMM cannot manipulate TDX VM's memory. ++ * By default, QEMU disable SMM for TD guest. ++ */ ++ if (def->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Intel TDX launch security is not supported with SMM enabled")); ++ return -1; ++ } ++ /* TDVF(OVMF) needs to run at private memory for TD guest. TDX cannot ++ * support pflash device since it doesn't support read-only private memory. ++ * Thus load TDVF(OVMF) with -bios option for TDs. ++ */ ++ if (def->os.loader && def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Intel TDX launch security is not supported with pflash loader")); ++ return -1; ++ } + break; + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Properly-propagate-migration-state-to-TPM-cleanup-code.patch b/SOURCES/libvirt-qemu-Properly-propagate-migration-state-to-TPM-cleanup-code.patch new file mode 100644 index 0000000..1060783 --- /dev/null +++ b/SOURCES/libvirt-qemu-Properly-propagate-migration-state-to-TPM-cleanup-code.patch @@ -0,0 +1,135 @@ +From b6e803fc90bb9d49345adca4f38856ce97fde9f8 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Jiri Denemark +Date: Wed, 9 Apr 2025 15:35:20 +0200 +Subject: [PATCH] qemu: Properly propagate migration state to TPM cleanup code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When migrating a domain with TPM state on a shared disk, we need to skip +TPM cleanup on both ends. So far the code only handled successful +migration and skipped the cleanup on the source host. But if the +migration failed for some reason, the cleanup would be incorrectly +called on the destination host removing the TPM files even though the +domain was still running on the source host. + +https://issues.redhat.com/browse/RHEL-82411 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit 97ed7f22b089c5fdd9ee02cffc6854f6e021ab2b) + +https://issues.redhat.com/browse/RHEL-86800 +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_driver.c | 7 +++++-- + src/qemu/qemu_migration.c | 6 +++--- + src/qemu/qemu_process.c | 8 ++------ + 3 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index f8f3d2c725..4c6eff9286 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -3853,6 +3853,7 @@ processMonitorEOFEvent(virQEMUDriver *driver, + const char *auditReason = "shutdown"; + unsigned int stopFlags = 0; + virObjectEvent *event = NULL; ++ bool migration; + + if (vm->def->id != domid) { + VIR_DEBUG("Domain %s was restarted, ignoring EOF", +@@ -3863,6 +3864,8 @@ processMonitorEOFEvent(virQEMUDriver *driver, + if (qemuProcessBeginStopJob(vm, VIR_JOB_DESTROY, true) < 0) + return; + ++ migration = vm->job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN; ++ + if (!virDomainObjIsActive(vm)) { + VIR_DEBUG("Domain %p '%s' is not active, ignoring EOF", + vm, vm->def->name); +@@ -3877,7 +3880,7 @@ processMonitorEOFEvent(virQEMUDriver *driver, + auditReason = "failed"; + } + +- if (vm->job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN) { ++ if (migration) { + stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED; + qemuMigrationDstErrorSave(driver, vm->def->name, + qemuMonitorLastError(priv->mon)); +@@ -3890,7 +3893,7 @@ processMonitorEOFEvent(virQEMUDriver *driver, + virObjectEventStateQueue(driver->domainEventState, event); + + endjob: +- qemuDomainRemoveInactive(driver, vm, 0, false); ++ qemuDomainRemoveInactive(driver, vm, 0, migration); + qemuProcessEndStopJob(vm); + } + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 62da892254..5cb7642315 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -3592,7 +3592,7 @@ qemuMigrationDstPrepareFresh(virQEMUDriver *driver, + * and there is no 'goto cleanup;' in the middle of those */ + VIR_FREE(priv->origname); + virDomainObjRemoveTransientDef(vm); +- qemuDomainRemoveInactive(driver, vm, 0, false); ++ qemuDomainRemoveInactive(driver, vm, 0, true); + } + virDomainObjEndAPI(&vm); + virErrorRestore(&origErr); +@@ -6963,7 +6963,7 @@ qemuMigrationDstFinishActive(virQEMUDriver *driver, + } + + if (!qemuDomainObjIsActive(vm)) +- qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, false); ++ qemuDomainRemoveInactive(driver, vm, VIR_DOMAIN_UNDEFINE_TPM, true); + + virErrorRestore(&orig_err); + return NULL; +@@ -7099,7 +7099,7 @@ qemuMigrationProcessUnattended(virQEMUDriver *driver, + qemuMigrationJobFinish(vm); + + if (!virDomainObjIsActive(vm)) +- qemuDomainRemoveInactive(driver, vm, 0, false); ++ qemuDomainRemoveInactive(driver, vm, 0, true); + } + + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index fac5678439..ad7e99750f 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -8731,7 +8731,6 @@ void qemuProcessStop(virQEMUDriver *driver, + size_t i; + g_autofree char *timestamp = NULL; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); +- bool outgoingMigration; + + VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%lld, " + "reason=%s, asyncJob=%s, flags=0x%x", +@@ -8807,10 +8806,7 @@ void qemuProcessStop(virQEMUDriver *driver, + + qemuDomainCleanupRun(driver, vm); + +- outgoingMigration = (flags & VIR_QEMU_PROCESS_STOP_MIGRATED) && +- (asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT); +- +- qemuExtDevicesStop(driver, vm, outgoingMigration); ++ qemuExtDevicesStop(driver, vm, !!(flags & VIR_QEMU_PROCESS_STOP_MIGRATED)); + + qemuDBusStop(driver, vm); + +@@ -9070,7 +9066,7 @@ qemuProcessAutoDestroy(virDomainObj *dom, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_DESTROYED); + +- qemuDomainRemoveInactive(driver, dom, 0, false); ++ qemuDomainRemoveInactive(driver, dom, 0, !!(stopFlags & VIR_QEMU_PROCESS_STOP_MIGRATED)); + + qemuProcessEndStopJob(dom); + +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-Rename-outgoingMigration-parameter-in-various-TPM-functions.patch b/SOURCES/libvirt-qemu-Rename-outgoingMigration-parameter-in-various-TPM-functions.patch new file mode 100644 index 0000000..ed7eb10 --- /dev/null +++ b/SOURCES/libvirt-qemu-Rename-outgoingMigration-parameter-in-various-TPM-functions.patch @@ -0,0 +1,230 @@ +From c28859cbaeac298adbe957956cf8442c9a6b7264 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Jiri Denemark +Date: Tue, 11 Mar 2025 10:05:28 +0100 +Subject: [PATCH] qemu: Rename outgoingMigration parameter in various TPM + functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The parameter is used to skip TPM state cleanup on outgoing migration +with shared storage. But we also need to skip the cleanup after a failed +incoming migration. Let's call the parameter "migration" to reflect its +usage on both sides of migration. + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +(cherry picked from commit a5e4ca6f02dc8250f84163a0d19b69300affde43) + +https://issues.redhat.com/browse/RHEL-86800 +Signed-off-by: Jiri Denemark +--- + src/qemu/qemu_domain.c | 8 ++++---- + src/qemu/qemu_domain.h | 2 +- + src/qemu/qemu_extdevice.c | 8 ++++---- + src/qemu/qemu_extdevice.h | 4 ++-- + src/qemu/qemu_tpm.c | 19 +++++++++---------- + src/qemu/qemu_tpm.h | 4 ++-- + 6 files changed, 22 insertions(+), 23 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 1ccaff90d9..89e1b50366 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5749,7 +5749,7 @@ static void + qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, + virDomainObj *vm, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autofree char *snapDir = NULL; +@@ -5775,7 +5775,7 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver, + if (rmdir(chkDir) < 0 && errno != ENOENT) + VIR_WARN("unable to remove checkpoint directory %s", chkDir); + } +- qemuExtDevicesCleanupHost(driver, vm->def, flags, outgoingMigration); ++ qemuExtDevicesCleanupHost(driver, vm->def, flags, migration); + } + + +@@ -5788,14 +5788,14 @@ void + qemuDomainRemoveInactive(virQEMUDriver *driver, + virDomainObj *vm, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + { + if (vm->persistent) { + /* Short-circuit, we don't want to remove a persistent domain */ + return; + } + +- qemuDomainRemoveInactiveCommon(driver, vm, flags, outgoingMigration); ++ qemuDomainRemoveInactiveCommon(driver, vm, flags, migration); + + virDomainObjListRemove(driver->domains, vm); + } +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index e810f79599..6246988491 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -689,7 +689,7 @@ int qemuDomainMomentDiscardAll(void *payload, + void qemuDomainRemoveInactive(virQEMUDriver *driver, + virDomainObj *vm, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration); ++ bool migration); + + void + qemuDomainRemoveInactiveLocked(virQEMUDriver *driver, +diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c +index 2384bab7a6..7451e0fa03 100644 +--- a/src/qemu/qemu_extdevice.c ++++ b/src/qemu/qemu_extdevice.c +@@ -154,7 +154,7 @@ void + qemuExtDevicesCleanupHost(virQEMUDriver *driver, + virDomainDef *def, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + { + size_t i; + +@@ -165,7 +165,7 @@ qemuExtDevicesCleanupHost(virQEMUDriver *driver, + virDomainTPMDef *tpm = def->tpms[i]; + + if (tpm->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) +- qemuExtTPMCleanupHost(driver, tpm, flags, outgoingMigration); ++ qemuExtTPMCleanupHost(driver, tpm, flags, migration); + } + } + +@@ -266,7 +266,7 @@ qemuExtDevicesStart(virQEMUDriver *driver, + void + qemuExtDevicesStop(virQEMUDriver *driver, + virDomainObj *vm, +- bool outgoingMigration) ++ bool migration) + { + virDomainDef *def = vm->def; + size_t i; +@@ -283,7 +283,7 @@ qemuExtDevicesStop(virQEMUDriver *driver, + + for (i = 0; i < def->ntpms; i++) { + if (def->tpms[i]->type == VIR_DOMAIN_TPM_TYPE_EMULATOR) +- qemuExtTPMStop(driver, vm, outgoingMigration); ++ qemuExtTPMStop(driver, vm, migration); + } + + for (i = 0; i < def->nnets; i++) { +diff --git a/src/qemu/qemu_extdevice.h b/src/qemu/qemu_extdevice.h +index d4ac9f395c..36f7fb77a8 100644 +--- a/src/qemu/qemu_extdevice.h ++++ b/src/qemu/qemu_extdevice.h +@@ -48,7 +48,7 @@ int qemuExtDevicesPrepareHost(virQEMUDriver *driver, + void qemuExtDevicesCleanupHost(virQEMUDriver *driver, + virDomainDef *def, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + int qemuExtDevicesStart(virQEMUDriver *driver, +@@ -59,7 +59,7 @@ int qemuExtDevicesStart(virQEMUDriver *driver, + + void qemuExtDevicesStop(virQEMUDriver *driver, + virDomainObj *vm, +- bool outgoingMigration) ++ bool migration) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + bool qemuExtDevicesHasDevice(virDomainDef *def); +diff --git a/src/qemu/qemu_tpm.c b/src/qemu/qemu_tpm.c +index f5e0184e54..f910a26286 100644 +--- a/src/qemu/qemu_tpm.c ++++ b/src/qemu/qemu_tpm.c +@@ -907,7 +907,8 @@ qemuTPMEmulatorInitPaths(virDomainTPMDef *tpm, + * @driver: QEMU driver + * @tpm: TPM definition + * @flags: flags indicating whether to keep or remove TPM persistent state +- * @outgoingMigration: whether cleanup is due to an outgoing migration ++ * @migration: whether cleanup is due to a successful outgoing or failed ++ * incoming migration + * + * Clean up persistent storage for the swtpm. + */ +@@ -915,14 +916,12 @@ static void + qemuTPMEmulatorCleanupHost(virQEMUDriver *driver, + virDomainTPMDef *tpm, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + +- /* Never remove the state in case of outgoing migration with shared +- * storage. +- */ +- if (outgoingMigration && ++ /* Never remove the state in case of migration with shared storage. */ ++ if (migration && + virFileIsSharedFS(tpm->data.emulator.source_path, cfg->sharedFilesystems) == 1) + return; + +@@ -1293,9 +1292,9 @@ void + qemuExtTPMCleanupHost(virQEMUDriver *driver, + virDomainTPMDef *tpm, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + { +- qemuTPMEmulatorCleanupHost(driver, tpm, flags, outgoingMigration); ++ qemuTPMEmulatorCleanupHost(driver, tpm, flags, migration); + } + + +@@ -1319,7 +1318,7 @@ qemuExtTPMStart(virQEMUDriver *driver, + void + qemuExtTPMStop(virQEMUDriver *driver, + virDomainObj *vm, +- bool outgoingMigration) ++ bool migration) + { + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + g_autofree char *shortName = virDomainDefGetShortName(vm->def); +@@ -1329,7 +1328,7 @@ qemuExtTPMStop(virQEMUDriver *driver, + return; + + qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName); +- if (outgoingMigration && qemuTPMHasSharedStorage(driver, vm->def)) ++ if (migration && qemuTPMHasSharedStorage(driver, vm->def)) + restoreTPMStateLabel = false; + + if (qemuSecurityRestoreTPMLabels(driver, vm, restoreTPMStateLabel, false) < 0) +diff --git a/src/qemu/qemu_tpm.h b/src/qemu/qemu_tpm.h +index 7096060a2a..37813087cf 100644 +--- a/src/qemu/qemu_tpm.h ++++ b/src/qemu/qemu_tpm.h +@@ -38,7 +38,7 @@ int qemuExtTPMPrepareHost(virQEMUDriver *driver, + void qemuExtTPMCleanupHost(virQEMUDriver *driver, + virDomainTPMDef *tpm, + virDomainUndefineFlagsValues flags, +- bool outgoingMigration) ++ bool migration) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + int qemuExtTPMStart(virQEMUDriver *driver, +@@ -52,7 +52,7 @@ int qemuExtTPMStart(virQEMUDriver *driver, + + void qemuExtTPMStop(virQEMUDriver *driver, + virDomainObj *vm, +- bool outgoingMigration) ++ bool migration) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + int qemuExtTPMSetupCgroup(virQEMUDriver *driver, +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-Send-event-VIR_DOMAIN_EVENT_-STOPPED-STARTED-during-recreation.patch b/SOURCES/libvirt-qemu-Send-event-VIR_DOMAIN_EVENT_-STOPPED-STARTED-during-recreation.patch new file mode 100644 index 0000000..f1936c2 --- /dev/null +++ b/SOURCES/libvirt-qemu-Send-event-VIR_DOMAIN_EVENT_-STOPPED-STARTED-during-recreation.patch @@ -0,0 +1,138 @@ +From dbeae7c9d470143a0c23195d1880ad302bce78ab Mon Sep 17 00:00:00 2001 +Message-ID: +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:21 -0400 +Subject: [PATCH] qemu: Send event VIR_DOMAIN_EVENT_[STOPPED|STARTED] during + recreation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For secure guest, FakeReboot kills original QEMU instance and +create new one which is quite different from normal guest. + +To reflect this fact, VIR_DOMAIN_EVENT_[STOPPED|STARTED] +are sent to control plane with new introduced reasons +VIR_DOMAIN_EVENT_[STOPPED|STARTED]_RECREATION. + +That would let control plane software understand that these +events are from a fake reboot. + +Suggested-by: Daniel P. Berrangé +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Zhenzhong Duan +(cherry picked from commit 1af740c5012bb45dfe96c77bcd6b20c28b6bb45d) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + examples/c/misc/event-test.c | 6 ++++++ + include/libvirt/libvirt-domain.h | 2 ++ + src/qemu/qemu_process.c | 10 ++++++++++ + tools/virsh-domain-event.c | 6 ++++-- + 4 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/examples/c/misc/event-test.c b/examples/c/misc/event-test.c +index 88d99dff56..04d74670e7 100644 +--- a/examples/c/misc/event-test.c ++++ b/examples/c/misc/event-test.c +@@ -143,6 +143,9 @@ eventDetailToString(int event, + case VIR_DOMAIN_EVENT_STARTED_WAKEUP: + return "Event wakeup"; + ++ case VIR_DOMAIN_EVENT_STARTED_RECREATION: ++ return "Recreation"; ++ + case VIR_DOMAIN_EVENT_STARTED_LAST: + break; + } +@@ -227,6 +230,9 @@ eventDetailToString(int event, + case VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT: + return "Snapshot"; + ++ case VIR_DOMAIN_EVENT_STOPPED_RECREATION: ++ return "Recreation"; ++ + case VIR_DOMAIN_EVENT_STOPPED_LAST: + break; + } +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index df13b72f7b..7759ddeaad 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -3873,6 +3873,7 @@ typedef enum { + VIR_DOMAIN_EVENT_STARTED_RESTORED = 2, /* Restored from a state file (Since: 0.5.0) */ + VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT = 3, /* Restored from snapshot (Since: 0.8.0) */ + VIR_DOMAIN_EVENT_STARTED_WAKEUP = 4, /* Started due to wakeup event (Since: 0.9.11) */ ++ VIR_DOMAIN_EVENT_STARTED_RECREATION = 5, /* Secure guest recreation (Since: 10.1.0) */ + + # ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_EVENT_STARTED_LAST /* (Since: 0.9.10) */ +@@ -3937,6 +3938,7 @@ typedef enum { + VIR_DOMAIN_EVENT_STOPPED_SAVED = 4, /* Saved to a state file (Since: 0.5.0) */ + VIR_DOMAIN_EVENT_STOPPED_FAILED = 5, /* Host emulator/mgmt failed (Since: 0.5.0) */ + VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT = 6, /* offline snapshot loaded (Since: 0.8.0) */ ++ VIR_DOMAIN_EVENT_STOPPED_RECREATION = 7, /* Secure guest recreation (Since: 10.1.0) */ + + # ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_EVENT_STOPPED_LAST /* (Since: 0.9.10) */ +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index caf63b0ae3..0d4fdf6960 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -455,6 +455,7 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm) + { + qemuDomainObjPrivate *priv = vm->privateData; + virQEMUDriver *driver = priv->driver; ++ virObjectEvent *event = NULL; + int ret = -1; + + VIR_DEBUG("Handle secure guest reboot: destroy phase"); +@@ -471,6 +472,11 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm) + qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED, VIR_ASYNC_JOB_NONE, 0); + virDomainAuditStop(vm, "destroyed"); + ++ event = virDomainEventLifecycleNewFromObj(vm, ++ VIR_DOMAIN_EVENT_STOPPED, ++ VIR_DOMAIN_EVENT_STOPPED_RECREATION); ++ virObjectEventStateQueue(driver->domainEventState, event); ++ + /* skip remove inactive domain from active list */ + qemuProcessEndStopJob(vm); + +@@ -491,6 +497,10 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm) + } + + virDomainAuditStart(vm, "booted", true); ++ event = virDomainEventLifecycleNewFromObj(vm, ++ VIR_DOMAIN_EVENT_STARTED, ++ VIR_DOMAIN_EVENT_STARTED_RECREATION); ++ virObjectEventStateQueue(driver->domainEventState, event); + + qemuDomainSaveStatus(vm); + ret = 0; +diff --git a/tools/virsh-domain-event.c b/tools/virsh-domain-event.c +index cd33d4d938..1b42ed706d 100644 +--- a/tools/virsh-domain-event.c ++++ b/tools/virsh-domain-event.c +@@ -70,7 +70,8 @@ VIR_ENUM_IMPL(virshDomainEventStarted, + N_("Migrated"), + N_("Restored"), + N_("Snapshot"), +- N_("Event wakeup")); ++ N_("Event wakeup"), ++ N_("Recreation")); + + VIR_ENUM_DECL(virshDomainEventSuspended); + VIR_ENUM_IMPL(virshDomainEventSuspended, +@@ -103,7 +104,8 @@ VIR_ENUM_IMPL(virshDomainEventStopped, + N_("Migrated"), + N_("Saved"), + N_("Failed"), +- N_("Snapshot")); ++ N_("Snapshot"), ++ N_("Recreation")); + + VIR_ENUM_DECL(virshDomainEventShutdown); + VIR_ENUM_IMPL(virshDomainEventShutdown, +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Support-domain-reset-command-for-TDX-guest.patch b/SOURCES/libvirt-qemu-Support-domain-reset-command-for-TDX-guest.patch new file mode 100644 index 0000000..7b5585b --- /dev/null +++ b/SOURCES/libvirt-qemu-Support-domain-reset-command-for-TDX-guest.patch @@ -0,0 +1,150 @@ +From 9a47f88f06ca6c1274c2bb5ca723057faf33e86e Mon Sep 17 00:00:00 2001 +Message-ID: <9a47f88f06ca6c1274c2bb5ca723057faf33e86e.1759835600.git.jdenemar@redhat.com> +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:23 -0400 +Subject: [PATCH] qemu: Support domain reset command for TDX guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +TDX guest doesn't support system_reset, so have to kill the old QEMU and +start a new one to simulate the reset. This can be achieved by calling +qemuProcessFakeRebootViaRecreate(). + +Simiar as FakeReboot, QEMU sends SHUTDOWN event with "host-signal" reason +which can trigger another FakeReset. Check if a FakeReset is ongoing and +bypass "host-signal" processing which originally comes from FakeReset. + +Domain lock is already hold in qemuDomainReset() before calling +qemuProcessFakeRebootViaRecreate(), so bypass locking in it. + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit fcc12f217e7a45ec6049642c2707917bb290d58c) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_driver.c | 10 +++++++++- + src/qemu/qemu_monitor.c | 6 ++++++ + src/qemu/qemu_process.c | 14 +++++++++----- + src/qemu/qemu_process.h | 2 ++ + 5 files changed, 27 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 3f16f86da8..d787d2a065 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -128,6 +128,7 @@ struct _qemuDomainObjPrivate { + char *lockState; + + bool fakeReboot; ++ bool fakeReset; + bool pausedShutdown; + /* allowReboot: + * +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 7d0c39c89f..98bfe8124d 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -2008,13 +2008,21 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags) + if (virDomainResetEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + ++ priv = vm->privateData; ++ ++ if (vm->def->sec && ++ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) { ++ priv->fakeReset = true; ++ ret = qemuProcessFakeRebootViaRecreate(vm, true); ++ goto cleanup; ++ } ++ + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + +- priv = vm->privateData; + qemuDomainObjEnterMonitor(vm); + ret = qemuMonitorSystemReset(priv->mon); + qemuDomainObjExitMonitor(vm); +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 6d19b675d5..a9fe4f2f6b 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1086,6 +1086,12 @@ qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest, + if (priv->fakeReboot && STREQ_NULLABLE(reason, "host-signal")) + return; + ++ /* Similar as FakeReboot for FakeReset. */ ++ if (priv->fakeReset && STREQ_NULLABLE(reason, "host-signal")) { ++ priv->fakeReset = false; ++ return; ++ } ++ + if ((STREQ_NULLABLE(reason, "guest-shutdown") && + vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) || + (STREQ_NULLABLE(reason, "guest-reset") && +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 0d4fdf6960..7b6c02bc27 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -450,8 +450,8 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED, + * Secure guest doesn't support fake reboot via machine CPU reset. + * We thus fake reboot via QEMU re-creation. + */ +-static void +-qemuProcessFakeRebootViaRecreate(virDomainObj *vm) ++int ++qemuProcessFakeRebootViaRecreate(virDomainObj *vm, bool locked) + { + qemuDomainObjPrivate *priv = vm->privateData; + virQEMUDriver *driver = priv->driver; +@@ -460,7 +460,9 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm) + + VIR_DEBUG("Handle secure guest reboot: destroy phase"); + +- virObjectLock(vm); ++ if (!locked) ++ virObjectLock(vm); ++ + if (qemuProcessBeginStopJob(vm, VIR_JOB_DESTROY, 0) < 0) + goto cleanup; + +@@ -513,7 +515,9 @@ qemuProcessFakeRebootViaRecreate(virDomainObj *vm) + qemuDomainSetFakeReboot(vm, false); + if (ret == -1) + ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE)); +- virDomainObjEndAPI(&vm); ++ if (!locked) ++ virDomainObjEndAPI(&vm); ++ return ret; + } + + +@@ -587,7 +591,7 @@ qemuProcessFakeReboot(void *opaque) + + if (vm->def->sec && + vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) +- qemuProcessFakeRebootViaRecreate(vm); ++ ignore_value(qemuProcessFakeRebootViaRecreate(vm, false)); + else + qemuProcessFakeRebootViaReset(vm); + } +diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h +index fee00ce53b..3074f27b64 100644 +--- a/src/qemu/qemu_process.h ++++ b/src/qemu/qemu_process.h +@@ -184,6 +184,8 @@ typedef enum { + + int qemuProcessKill(virDomainObj *vm, unsigned int flags); + ++int qemuProcessFakeRebootViaRecreate(virDomainObj *vm, bool locked); ++ + void qemuProcessShutdownOrReboot(virDomainObj *vm); + + void qemuProcessAutoDestroy(virDomainObj *dom, +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Support-reboot-command-in-guest.patch b/SOURCES/libvirt-qemu-Support-reboot-command-in-guest.patch new file mode 100644 index 0000000..f7cdf0a --- /dev/null +++ b/SOURCES/libvirt-qemu-Support-reboot-command-in-guest.patch @@ -0,0 +1,96 @@ +From ae1ff9ae8b699e4be8b482d7dee32b3fe27767c7 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Zhenzhong Duan +Date: Thu, 10 Jul 2025 03:21:19 -0400 +Subject: [PATCH] qemu: Support reboot command in guest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We can reboot a TDX guest with 'virsh reboot' or 'virsh shutdown' if action +for onPoweroff is 'restart'. But running reboot command in guest shell will +always lead to shutdown. + +This behavior is not consistent with normal guest, fix it by checking +shutdown reason and action configuration to trigger FakeReboot. + +Signed-off-by: Zhenzhong Duan +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit 312c3afa48936c7a9676408abdd5a44cb9ad2baa) +Resolves: https://issues.redhat.com/browse/RHEL-111840 +Signed-off-by: Paolo Bonzini +--- + src/qemu/qemu_monitor.c | 18 +++++++++++++++++- + src/qemu/qemu_monitor.h | 2 +- + src/qemu/qemu_monitor_json.c | 6 +++++- + 3 files changed, 23 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 18b877ce29..40f15c88a8 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1063,10 +1063,26 @@ qemuMonitorEmitEvent(qemuMonitor *mon, const char *event, + + + void +-qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest) ++qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest, ++ const char *reason) + { ++ virDomainObj *vm = mon->vm; ++ + VIR_DEBUG("mon=%p guest=%u", mon, guest); + ++ /* This isn't best place to set FakeReboot but we need to access ++ * mon->vm which is defined in this file. Reboot command in guest ++ * will trigger SHUTDOWN event for TDX guest, so we has to deal ++ * with it here. */ ++ if (vm->def->sec && ++ vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_TDX) { ++ if ((STREQ_NULLABLE(reason, "guest-shutdown") && ++ vm->def->onPoweroff == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART) || ++ (STREQ_NULLABLE(reason, "guest-reset") && ++ vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_RESTART)) ++ qemuDomainSetFakeReboot(vm, true); ++ } ++ + QEMU_MONITOR_CALLBACK(mon, domainShutdown, mon->vm, guest); + } + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index bf44c96057..d4730162ca 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -460,7 +460,7 @@ int qemuMonitorUpdateVideoVram64Size(qemuMonitor *mon, + void qemuMonitorEmitEvent(qemuMonitor *mon, const char *event, + long long seconds, unsigned int micros, + const char *details); +-void qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest); ++void qemuMonitorEmitShutdown(qemuMonitor *mon, virTristateBool guest, const char *reason); + void qemuMonitorEmitReset(qemuMonitor *mon); + void qemuMonitorEmitStop(qemuMonitor *mon); + void qemuMonitorEmitResume(qemuMonitor *mon); +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index db46bcc741..cbe10ad907 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -548,12 +548,16 @@ qemuMonitorJSONMakeCommand(const char *cmdname, + static void qemuMonitorJSONHandleShutdown(qemuMonitor *mon, virJSONValue *data) + { + bool guest = false; ++ const char *reason = NULL; + virTristateBool guest_initiated = VIR_TRISTATE_BOOL_ABSENT; + + if (data && virJSONValueObjectGetBoolean(data, "guest", &guest) == 0) + guest_initiated = virTristateBoolFromBool(guest); + +- qemuMonitorEmitShutdown(mon, guest_initiated); ++ if (data) ++ reason = virJSONValueObjectGetString(data, "reason"); ++ ++ qemuMonitorEmitShutdown(mon, guest_initiated, reason); + } + + static void qemuMonitorJSONHandleReset(qemuMonitor *mon, virJSONValue *data G_GNUC_UNUSED) +-- +2.51.0 diff --git a/SOURCES/libvirt-qemu-Validate-virtio-mem-ccw.patch b/SOURCES/libvirt-qemu-Validate-virtio-mem-ccw.patch new file mode 100644 index 0000000..d79173f --- /dev/null +++ b/SOURCES/libvirt-qemu-Validate-virtio-mem-ccw.patch @@ -0,0 +1,86 @@ +From 6fa979b9735e988971203bca10903ba587a27f79 Mon Sep 17 00:00:00 2001 +Message-ID: <6fa979b9735e988971203bca10903ba587a27f79.1744876588.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Wed, 15 Jan 2025 15:48:41 +0100 +Subject: [PATCH] qemu: Validate virtio-mem-ccw + +There are basically two differences between virtio-mem-ccw and +virtio-mem-pci. s390 doesn't allow mixing different page sizes +and there's no NUMA support in QEMU. + +Signed-off-by: Michal Privoznik +Reviewed-by: Boris Fiuczynski +(cherry picked from commit 541dfe40bc9b3fe90d488ab85df8ea3ea31b8249) +Resolves: https://issues.redhat.com/browse/RHEL-72976 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_validate.c | 35 ++++++++++++++++++++++++++++++++--- + 1 file changed, 32 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 1c61038f93..97f8f58ffd 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -5259,7 +5259,8 @@ qemuValidateDomainDeviceDefHub(virDomainHubDef *hub, + + + static int +-qemuValidateDomainDeviceDefMemory(virDomainMemoryDef *mem, ++qemuValidateDomainDeviceDefMemory(const virDomainMemoryDef *mem, ++ const virDomainDef *def, + virQEMUCaps *qemuCaps) + { + virSGXCapability *sgxCaps; +@@ -5298,12 +5299,40 @@ qemuValidateDomainDeviceDefMemory(virDomainMemoryDef *mem, + break; + + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: +- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI)) { ++ if ((mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI)) || ++ (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtio-mem isn't supported by this QEMU binary")); + return -1; + } + ++ if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { ++ /* virtio-mem-ccw has a few differences compared to virtio-mem-pci: ++ * ++ * 1) corresponding memory-backing-* object can't have a different ++ * page size than the boot memory (see s390_machine_device_plug() ++ * in qemu sources). ++ * 2) Since its commit v2.12.0-rc0~41^2~6 QEMU doesn't allow NUMA ++ * for s390. ++ */ ++ ++ if (mem->source.virtio_mem.pagesize != 0 && ++ def->mem.nhugepages && ++ mem->source.virtio_mem.pagesize != def->mem.hugepages[0].size) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("virtio-mem-ccw can't use different page size than the boot memory")); ++ return -1; ++ } ++ ++ if (mem->targetNode != 0 && mem->targetNode != -1) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("NUMA nodes are not supported for virtio-mem-ccw")); ++ return -1; ++ } ++ } ++ + if (mem->target.virtio_mem.dynamicMemslots == VIR_TRISTATE_BOOL_YES && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_DYNAMIC_MEMSLOTS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +@@ -5490,7 +5519,7 @@ qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev, + return qemuValidateDomainDeviceDefSound(dev->data.sound, qemuCaps); + + case VIR_DOMAIN_DEVICE_MEMORY: +- return qemuValidateDomainDeviceDefMemory(dev->data.memory, qemuCaps); ++ return qemuValidateDomainDeviceDefMemory(dev->data.memory, def, qemuCaps); + + case VIR_DOMAIN_DEVICE_SHMEM: + return qemuValidateDomainDeviceDefShmem(dev->data.shmem, qemuCaps); +-- +2.49.0 diff --git a/SOURCES/libvirt-qemu-add-IOMMU-model-amd.patch b/SOURCES/libvirt-qemu-add-IOMMU-model-amd.patch new file mode 100644 index 0000000..ba02509 --- /dev/null +++ b/SOURCES/libvirt-qemu-add-IOMMU-model-amd.patch @@ -0,0 +1,337 @@ +From 62862c4c7302758d304dd876f26712a75df26e08 Mon Sep 17 00:00:00 2001 +Message-ID: <62862c4c7302758d304dd876f26712a75df26e08.1752749355.git.jdenemar@redhat.com> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Fri, 14 Mar 2025 17:13:09 +0100 +Subject: [PATCH] qemu: add IOMMU model amd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce a new IOMMU device model 'amd', both the parser +and the formatter for QEMU because of our enum warnings. + +https://issues.redhat.com/browse/RHEL-50560 + +Signed-off-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit 14760600914ea6b5da778dd470823e734becf630) + +Signed-off-by: Ján Tomko +--- + docs/formatdomain.rst | 5 ++- + src/conf/domain_conf.c | 1 + + src/conf/domain_conf.h | 1 + + src/conf/domain_validate.c | 13 +++++++ + src/conf/schemas/domaincommon.rng | 1 + + src/qemu/qemu_command.c | 28 +++++++++++++ + src/qemu/qemu_domain_address.c | 4 ++ + src/qemu/qemu_validate.c | 22 +++++++++++ + .../amd-iommu.x86_64-latest.args | 35 +++++++++++++++++ + .../amd-iommu.x86_64-latest.xml | 1 + + tests/qemuxmlconfdata/amd-iommu.xml | 39 +++++++++++++++++++ + tests/qemuxmlconftest.c | 2 + + 12 files changed, 150 insertions(+), 2 deletions(-) + create mode 100644 tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args + create mode 120000 tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml + create mode 100644 tests/qemuxmlconfdata/amd-iommu.xml + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index a950ee1cb4..ec7bdb07d0 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -8841,8 +8841,9 @@ Example: + + ``model`` + Supported values are ``intel`` (for Q35 guests) ``smmuv3`` +- (:since:`since 5.5.0`, for ARM virt guests), and ``virtio`` +- (:since:`since 8.3.0`, for Q35 and ARM virt guests). ++ (:since:`since 5.5.0`, for ARM virt guests), ``virtio`` ++ (:since:`since 8.3.0`, for Q35 and ARM virt guests) and ++ ``amd`` (:since:`since 11.5.0`). + + ``driver`` + The ``driver`` subelement can be used to configure additional options, some +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 726c3095ed..7c8591e509 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1349,6 +1349,7 @@ VIR_ENUM_IMPL(virDomainIOMMUModel, + "intel", + "smmuv3", + "virtio", ++ "amd", + ); + + VIR_ENUM_IMPL(virDomainVsockModel, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 20be6f7c05..343bb9bae0 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2973,6 +2973,7 @@ typedef enum { + VIR_DOMAIN_IOMMU_MODEL_INTEL, + VIR_DOMAIN_IOMMU_MODEL_SMMUV3, + VIR_DOMAIN_IOMMU_MODEL_VIRTIO, ++ VIR_DOMAIN_IOMMU_MODEL_AMD, + + VIR_DOMAIN_IOMMU_MODEL_LAST + } virDomainIOMMUModel; +diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c +index 9cedc8d6d2..483cfbbe08 100644 +--- a/src/conf/domain_validate.c ++++ b/src/conf/domain_validate.c +@@ -2986,6 +2986,18 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + } + break; + ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: ++ if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->eim != VIR_TRISTATE_SWITCH_ABSENT || ++ iommu->aw_bits != 0 || ++ iommu->dma_translation != VIR_TRISTATE_SWITCH_ABSENT) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("iommu model '%1$s' doesn't support some additional attributes"), ++ virDomainIOMMUModelTypeToString(iommu->model)); ++ return -1; ++ } ++ break; ++ + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_LAST: + break; +@@ -3003,6 +3015,7 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *iommu) + break; + + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: + case VIR_DOMAIN_IOMMU_MODEL_LAST: + break; + } +diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng +index d46eb44588..38a0586f40 100644 +--- a/src/conf/schemas/domaincommon.rng ++++ b/src/conf/schemas/domaincommon.rng +@@ -6174,6 +6174,7 @@ + intel + smmuv3 + virtio ++ amd + + + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index fb70c79a94..de535029a8 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6051,6 +6051,7 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, + virQEMUCaps *qemuCaps) + { + g_autoptr(virJSONValue) props = NULL; ++ g_autoptr(virJSONValue) wrapperProps = NULL; + const virDomainIOMMUDef *iommu = def->iommu; + + if (!iommu) +@@ -6095,6 +6096,32 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, + /* There is no -device for SMMUv3, so nothing to be done here */ + return 0; + ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: ++ if (virJSONValueObjectAdd(&wrapperProps, ++ "s:driver", "AMDVI-PCI", ++ "s:id", iommu->info.alias, ++ NULL) < 0) ++ return -1; ++ ++ if (qemuBuildDeviceAddressProps(wrapperProps, def, &iommu->info) < 0) ++ return -1; ++ ++ if (qemuBuildDeviceCommandlineFromJSON(cmd, wrapperProps, def, qemuCaps) < 0) ++ return -1; ++ ++ if (virJSONValueObjectAdd(&props, ++ "s:driver", "amd-iommu", ++ "s:pci-id", iommu->info.alias, ++ "S:intremap", qemuOnOffAuto(iommu->intremap), ++ "T:device-iotlb", iommu->iotlb, ++ NULL) < 0) ++ return -1; ++ ++ if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, qemuCaps) < 0) ++ return -1; ++ ++ return 0; ++ + case VIR_DOMAIN_IOMMU_MODEL_LAST: + default: + virReportEnumRangeError(virDomainIOMMUModel, iommu->model); +@@ -6921,6 +6948,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, + + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: + /* These IOMMUs are formatted in qemuBuildIOMMUCommandLine */ + break; + +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index b73ac9ebf1..d8ab5a03f7 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -941,6 +941,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: + return virtioFlags | VIR_PCI_CONNECT_INTEGRATED; + ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: ++ return pciFlags | VIR_PCI_CONNECT_INTEGRATED; ++ + case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + case VIR_DOMAIN_IOMMU_MODEL_LAST: +@@ -2359,6 +2362,7 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, + + switch (iommu->model) { + case VIR_DOMAIN_IOMMU_MODEL_VIRTIO: ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: + if (virDeviceInfoPCIAddressIsWanted(&iommu->info) && + qemuDomainPCIAddressReserveNextAddr(addrs, &iommu->info) < 0) { + return -1; +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 97f8f58ffd..ddfb14399a 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -5153,6 +5153,28 @@ qemuValidateDomainDeviceDefIOMMU(const virDomainIOMMUDef *iommu, + } + break; + ++ case VIR_DOMAIN_IOMMU_MODEL_AMD: ++ if (!qemuDomainIsQ35(def)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("IOMMU device: '%1$s' is only supported with Q35 machines"), ++ virDomainIOMMUModelTypeToString(iommu->model)); ++ return -1; ++ } ++ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_AMD_IOMMU_PCI_ID)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("IOMMU device: '%1$s' is not supported with this QEMU binary"), ++ virDomainIOMMUModelTypeToString(iommu->model)); ++ return -1; ++ } ++ if (iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && ++ iommu->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("IOMMU device: '%1$s' needs a PCI address"), ++ virDomainIOMMUModelTypeToString(iommu->model)); ++ return -1; ++ } ++ break; ++ + case VIR_DOMAIN_IOMMU_MODEL_LAST: + default: + virReportEnumRangeError(virDomainIOMMUModel, iommu->model); +diff --git a/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args +new file mode 100644 +index 0000000000..36244edb3a +--- /dev/null ++++ b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.args +@@ -0,0 +1,35 @@ ++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 q35,usb=off,kernel_irqchip=split,dump-guest-core=off,memory-backend=pc.ram,acpi=on \ ++-accel kvm \ ++-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 \ ++-device '{"driver":"AMDVI-PCI","id":"iommu0","bus":"pcie.0","addr":"0x1"}' \ ++-device '{"driver":"amd-iommu","pci-id":"iommu0","intremap":"on","device-iotlb":true}' \ ++-audiodev '{"id":"audio1","driver":"none"}' \ ++-global ICH9-LPC.noreboot=off \ ++-watchdog-action reset \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml +new file mode 120000 +index 0000000000..5ba3d4b91b +--- /dev/null ++++ b/tests/qemuxmlconfdata/amd-iommu.x86_64-latest.xml +@@ -0,0 +1 @@ ++amd-iommu.xml +\ No newline at end of file +diff --git a/tests/qemuxmlconfdata/amd-iommu.xml b/tests/qemuxmlconfdata/amd-iommu.xml +new file mode 100644 +index 0000000000..0668ed4237 +--- /dev/null ++++ b/tests/qemuxmlconfdata/amd-iommu.xml +@@ -0,0 +1,39 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219100 ++ 219100 ++ 1 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++
++ ++ ++ ++