|
|
51d9a2 |
From 05b6b6d0d034e0a2ecb9b826bf5052a3bada218d Mon Sep 17 00:00:00 2001
|
|
|
51d9a2 |
Message-Id: <05b6b6d0d034e0a2ecb9b826bf5052a3bada218d@dist-git>
|
|
|
51d9a2 |
From: Erik Skultety <eskultet@redhat.com>
|
|
|
51d9a2 |
Date: Mon, 20 Aug 2018 17:18:53 +0200
|
|
|
51d9a2 |
Subject: [PATCH] qemu: caps: Format SEV platform data into qemuCaps cache
|
|
|
51d9a2 |
MIME-Version: 1.0
|
|
|
51d9a2 |
Content-Type: text/plain; charset=UTF-8
|
|
|
51d9a2 |
Content-Transfer-Encoding: 8bit
|
|
|
51d9a2 |
|
|
|
51d9a2 |
Since we're not saving the platform-specific data into a cache, we're
|
|
|
51d9a2 |
not going to populate the structure, which in turn will cause a crash
|
|
|
51d9a2 |
upon calling virNodeGetSEVInfo because of a NULL pointer dereference.
|
|
|
51d9a2 |
Ultimately, we should start caching this data along with host-specific
|
|
|
51d9a2 |
capabilities like NUMA and SELinux stuff into a separate cache, but for
|
|
|
51d9a2 |
the time being, this is a semi-proper fix for a potential crash.
|
|
|
51d9a2 |
|
|
|
51d9a2 |
Backtrace (requires libvirtd restart to load qemu caps from cache):
|
|
|
51d9a2 |
#0 qemuGetSEVInfoToParams
|
|
|
51d9a2 |
#1 qemuNodeGetSEVInfo
|
|
|
51d9a2 |
#2 virNodeGetSEVInfo
|
|
|
51d9a2 |
#3 remoteDispatchNodeGetSevInfo
|
|
|
51d9a2 |
#4 remoteDispatchNodeGetSevInfoHelper
|
|
|
51d9a2 |
#5 virNetServerProgramDispatchCall
|
|
|
51d9a2 |
#6 virNetServerProgramDispatch
|
|
|
51d9a2 |
#7 virNetServerProcessMsg
|
|
|
51d9a2 |
#8 virNetServerHandleJob
|
|
|
51d9a2 |
#9 virThreadPoolWorker
|
|
|
51d9a2 |
#10 virThreadHelper
|
|
|
51d9a2 |
|
|
|
51d9a2 |
https: //bugzilla.redhat.com/show_bug.cgi?id=1612009
|
|
|
51d9a2 |
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
|
51d9a2 |
Acked-by: Peter Krempa <pkrempa@redhat.com>
|
|
|
51d9a2 |
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
|
|
|
51d9a2 |
(cherry picked from commit 77f51ab52049734d80a8ccb79b80189c7fb95c41)
|
|
|
51d9a2 |
|
|
|
51d9a2 |
https://bugzilla.redhat.com/show_bug.cgi?id=1612009
|
|
|
51d9a2 |
https://bugzilla.redhat.com/show_bug.cgi?id=1619150
|
|
|
51d9a2 |
|
|
|
51d9a2 |
Amend:
|
|
|
51d9a2 |
- fixed the VIR_AUTOPTR bits which downstream doesn't support
|
|
|
51d9a2 |
and wouldn't compile
|
|
|
51d9a2 |
|
|
|
51d9a2 |
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
|
51d9a2 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
51d9a2 |
---
|
|
|
51d9a2 |
src/qemu/qemu_capabilities.c | 109 ++++++++++++++++++
|
|
|
51d9a2 |
.../qemu_2.12.0.x86_64.xml | 5 +-
|
|
|
51d9a2 |
.../caps_2.12.0.x86_64.xml | 6 +
|
|
|
51d9a2 |
3 files changed, 119 insertions(+), 1 deletion(-)
|
|
|
51d9a2 |
|
|
|
51d9a2 |
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|
|
51d9a2 |
index 470f25a5a6..4f2051a2bb 100644
|
|
|
51d9a2 |
--- a/src/qemu/qemu_capabilities.c
|
|
|
51d9a2 |
+++ b/src/qemu/qemu_capabilities.c
|
|
|
51d9a2 |
@@ -1573,6 +1573,30 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
|
|
|
51d9a2 |
}
|
|
|
51d9a2 |
|
|
|
51d9a2 |
|
|
|
51d9a2 |
+static int
|
|
|
51d9a2 |
+virQEMUCapsSEVInfoCopy(virSEVCapabilityPtr *dst,
|
|
|
51d9a2 |
+ virSEVCapabilityPtr src)
|
|
|
51d9a2 |
+{
|
|
|
51d9a2 |
+ int ret = -1;
|
|
|
51d9a2 |
+ virSEVCapabilityPtr tmp = NULL;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (VIR_ALLOC(tmp) < 0 ||
|
|
|
51d9a2 |
+ VIR_STRDUP(tmp->pdh, src->pdh) < 0 ||
|
|
|
51d9a2 |
+ VIR_STRDUP(tmp->cert_chain, src->cert_chain) < 0)
|
|
|
51d9a2 |
+ goto cleanup;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ tmp->cbitpos = src->cbitpos;
|
|
|
51d9a2 |
+ tmp->reduced_phys_bits = src->reduced_phys_bits;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ VIR_STEAL_PTR(*dst, tmp);
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ ret = 0;
|
|
|
51d9a2 |
+ cleanup:
|
|
|
51d9a2 |
+ virSEVCapabilitiesFree(tmp);
|
|
|
51d9a2 |
+ return ret;
|
|
|
51d9a2 |
+}
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
|
|
|
51d9a2 |
{
|
|
|
51d9a2 |
virQEMUCapsPtr ret = virQEMUCapsNew();
|
|
|
51d9a2 |
@@ -1635,6 +1659,11 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
|
|
|
51d9a2 |
for (i = 0; i < qemuCaps->ngicCapabilities; i++)
|
|
|
51d9a2 |
ret->gicCapabilities[i] = qemuCaps->gicCapabilities[i];
|
|
|
51d9a2 |
|
|
|
51d9a2 |
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST) &&
|
|
|
51d9a2 |
+ virQEMUCapsSEVInfoCopy(&ret->sevCapabilities,
|
|
|
51d9a2 |
+ qemuCaps->sevCapabilities) < 0)
|
|
|
51d9a2 |
+ goto error;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
return ret;
|
|
|
51d9a2 |
|
|
|
51d9a2 |
error:
|
|
|
51d9a2 |
@@ -3273,6 +3302,62 @@ virQEMUCapsCachePrivFree(void *privData)
|
|
|
51d9a2 |
}
|
|
|
51d9a2 |
|
|
|
51d9a2 |
|
|
|
51d9a2 |
+static int
|
|
|
51d9a2 |
+virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt)
|
|
|
51d9a2 |
+{
|
|
|
51d9a2 |
+ int ret = -1;
|
|
|
51d9a2 |
+ virSEVCapabilityPtr sev = NULL;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST))
|
|
|
51d9a2 |
+ return 0;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (virXPathBoolean("boolean(./sev)", ctxt) == 0) {
|
|
|
51d9a2 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
51d9a2 |
+ _("missing SEV platform data in QEMU "
|
|
|
51d9a2 |
+ "capabilities cache"));
|
|
|
51d9a2 |
+ return -1;
|
|
|
51d9a2 |
+ }
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (VIR_ALLOC(sev) < 0)
|
|
|
51d9a2 |
+ return -1;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (virXPathUInt("string(./sev/cbitpos)", ctxt, &sev->cbitpos) < 0) {
|
|
|
51d9a2 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
51d9a2 |
+ _("missing or malformed SEV cbitpos information "
|
|
|
51d9a2 |
+ "in QEMU capabilities cache"));
|
|
|
51d9a2 |
+ goto cleanup;
|
|
|
51d9a2 |
+ }
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (virXPathUInt("string(./sev/reducedPhysBits)", ctxt,
|
|
|
51d9a2 |
+ &sev->reduced_phys_bits) < 0) {
|
|
|
51d9a2 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
51d9a2 |
+ _("missing or malformed SEV reducedPhysBits information "
|
|
|
51d9a2 |
+ "in QEMU capabilities cache"));
|
|
|
51d9a2 |
+ goto cleanup;
|
|
|
51d9a2 |
+ }
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (!(sev->pdh = virXPathString("string(./sev/pdh)", ctxt))) {
|
|
|
51d9a2 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
51d9a2 |
+ _("missing SEV pdh information "
|
|
|
51d9a2 |
+ "in QEMU capabilities cache"));
|
|
|
51d9a2 |
+ goto cleanup;
|
|
|
51d9a2 |
+ }
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ if (!(sev->cert_chain = virXPathString("string(./sev/certChain)", ctxt))) {
|
|
|
51d9a2 |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
51d9a2 |
+ _("missing SEV certChain information "
|
|
|
51d9a2 |
+ "in QEMU capabilities cache"));
|
|
|
51d9a2 |
+ goto cleanup;
|
|
|
51d9a2 |
+ }
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ VIR_STEAL_PTR(qemuCaps->sevCapabilities, sev);
|
|
|
51d9a2 |
+ ret = 0;
|
|
|
51d9a2 |
+ cleanup:
|
|
|
51d9a2 |
+ virSEVCapabilitiesFree(sev);
|
|
|
51d9a2 |
+ return ret;
|
|
|
51d9a2 |
+}
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
/*
|
|
|
51d9a2 |
* Parsing a doc that looks like
|
|
|
51d9a2 |
*
|
|
|
51d9a2 |
@@ -3521,6 +3606,9 @@ virQEMUCapsLoadCache(virArch hostArch,
|
|
|
51d9a2 |
}
|
|
|
51d9a2 |
VIR_FREE(nodes);
|
|
|
51d9a2 |
|
|
|
51d9a2 |
+ if (virQEMUCapsParseSEVInfo(qemuCaps, ctxt) < 0)
|
|
|
51d9a2 |
+ goto cleanup;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
|
|
|
51d9a2 |
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
|
|
|
51d9a2 |
|
|
|
51d9a2 |
@@ -3638,6 +3726,24 @@ virQEMUCapsFormatCPUModels(virQEMUCapsPtr qemuCaps,
|
|
|
51d9a2 |
}
|
|
|
51d9a2 |
|
|
|
51d9a2 |
|
|
|
51d9a2 |
+static void
|
|
|
51d9a2 |
+virQEMUCapsFormatSEVInfo(virQEMUCapsPtr qemuCaps, virBufferPtr buf)
|
|
|
51d9a2 |
+{
|
|
|
51d9a2 |
+ virSEVCapabilityPtr sev = virQEMUCapsGetSEVCapabilities(qemuCaps);
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+ virBufferAddLit(buf, "<sev>\n");
|
|
|
51d9a2 |
+ virBufferAdjustIndent(buf, 2);
|
|
|
51d9a2 |
+ virBufferAsprintf(buf, "<cbitpos>%u</cbitpos>\n", sev->cbitpos);
|
|
|
51d9a2 |
+ virBufferAsprintf(buf, "<reducedPhysBits>%u</reducedPhysBits>\n",
|
|
|
51d9a2 |
+ sev->reduced_phys_bits);
|
|
|
51d9a2 |
+ virBufferEscapeString(buf, "<pdh>%s</pdh>\n", sev->pdh);
|
|
|
51d9a2 |
+ virBufferEscapeString(buf, "<certChain>%s</certChain>\n",
|
|
|
51d9a2 |
+ sev->cert_chain);
|
|
|
51d9a2 |
+ virBufferAdjustIndent(buf, -2);
|
|
|
51d9a2 |
+ virBufferAddLit(buf, "</sev>\n");
|
|
|
51d9a2 |
+}
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
char *
|
|
|
51d9a2 |
virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
|
|
|
51d9a2 |
{
|
|
|
51d9a2 |
@@ -3719,6 +3825,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
|
|
|
51d9a2 |
emulated ? "yes" : "no");
|
|
|
51d9a2 |
}
|
|
|
51d9a2 |
|
|
|
51d9a2 |
+ if (qemuCaps->sevCapabilities)
|
|
|
51d9a2 |
+ virQEMUCapsFormatSEVInfo(qemuCaps, &buf;;
|
|
|
51d9a2 |
+
|
|
|
51d9a2 |
virBufferAdjustIndent(&buf, -2);
|
|
|
51d9a2 |
virBufferAddLit(&buf, "</qemuCaps>\n");
|
|
|
51d9a2 |
|
|
|
51d9a2 |
diff --git a/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml b/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml
|
|
|
51d9a2 |
index 7a1be4c093..a8d6a4d629 100644
|
|
|
51d9a2 |
--- a/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml
|
|
|
51d9a2 |
+++ b/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml
|
|
|
51d9a2 |
@@ -142,6 +142,9 @@
|
|
|
51d9a2 |
<gic supported='no'/>
|
|
|
51d9a2 |
<vmcoreinfo supported='yes'/>
|
|
|
51d9a2 |
<genid supported='yes'/>
|
|
|
51d9a2 |
- <sev supported='no'/>
|
|
|
51d9a2 |
+ <sev supported='yes'>
|
|
|
51d9a2 |
+ <cbitpos>47</cbitpos>
|
|
|
51d9a2 |
+ <reducedPhysBits>1</reducedPhysBits>
|
|
|
51d9a2 |
+ </sev>
|
|
|
51d9a2 |
</features>
|
|
|
51d9a2 |
</domainCapabilities>
|
|
|
51d9a2 |
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
|
|
|
51d9a2 |
index 78889facce..f0dc082640 100644
|
|
|
51d9a2 |
--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
|
|
|
51d9a2 |
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
|
|
|
51d9a2 |
@@ -1254,4 +1254,10 @@
|
|
|
51d9a2 |
<machine name='pc-0.11' hotplugCpus='yes' maxCpus='255'/>
|
|
|
51d9a2 |
<machine name='pc-0.12' hotplugCpus='yes' maxCpus='255'/>
|
|
|
51d9a2 |
<machine name='pc-0.10' hotplugCpus='yes' maxCpus='255'/>
|
|
|
51d9a2 |
+ <sev>
|
|
|
51d9a2 |
+ <cbitpos>47</cbitpos>
|
|
|
51d9a2 |
+ <reducedPhysBits>1</reducedPhysBits>
|
|
|
51d9a2 |
+ <pdh>AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA</pdh>
|
|
|
51d9a2 |
+ <certChain>AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA</certChain>
|
|
|
51d9a2 |
+ </sev>
|
|
|
51d9a2 |
</qemuCaps>
|
|
|
51d9a2 |
--
|
|
|
51d9a2 |
2.18.0
|
|
|
51d9a2 |
|