render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
a41c76
From 00ca6e3be3959169559c5bc44dd929d0f313b014 Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <00ca6e3be3959169559c5bc44dd929d0f313b014@dist-git>
a41c76
From: Paulo de Rezende Pinatti <ppinatti@linux.ibm.com>
a41c76
Date: Wed, 24 Jun 2020 13:16:18 +0200
a41c76
Subject: [PATCH] qemu: Check if s390 secure guest support is enabled
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
This patch introduces a common function to verify if the
a41c76
availability of the so-called Secure Guest feature on the host
a41c76
has changed in order to invalidate the qemu capabilities cache.
a41c76
It can be used as an entry point for verification on different
a41c76
architectures.
a41c76
a41c76
For s390 the verification consists of:
a41c76
- checking if /sys/firmware/uv is available: meaning the HW
a41c76
facility is available and the host OS supports it;
a41c76
- checking if the kernel cmdline contains 'prot_virt=1': meaning
a41c76
the host OS wants to use the feature.
a41c76
a41c76
Whenever the availability of the feature does not match the secure
a41c76
guest flag in the cache then libvirt will re-build it in order to
a41c76
pick up the new set of capabilities available.
a41c76
a41c76
Signed-off-by: Paulo de Rezende Pinatti <ppinatti@linux.ibm.com>
a41c76
Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
a41c76
Tested-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
a41c76
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
a41c76
Reviewed-by: Erik Skultety <eskultet@redhat.com>
a41c76
(cherry picked from commit b611b620ceaf940017ba4d0b8b0638869c751509)
a41c76
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1848997
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1850351
a41c76
a41c76
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
a41c76
Message-Id: <3b91df0693526810b255db4ddc9af3484d655cbf.1592996194.git.jdenemar@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_capabilities.c | 61 ++++++++++++++++++++++++++++++++++++
a41c76
 1 file changed, 61 insertions(+)
a41c76
a41c76
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
a41c76
index 7609f44efb..8a4b43c269 100644
a41c76
--- a/src/qemu/qemu_capabilities.c
a41c76
+++ b/src/qemu/qemu_capabilities.c
a41c76
@@ -23,6 +23,7 @@
a41c76
 
a41c76
 #include "qemu_capabilities.h"
a41c76
 #include "viralloc.h"
a41c76
+#include "virarch.h"
a41c76
 #include "vircrypto.h"
a41c76
 #include "virlog.h"
a41c76
 #include "virerror.h"
a41c76
@@ -642,6 +643,7 @@ struct _virQEMUCaps {
a41c76
 
a41c76
     bool usedQMP;
a41c76
     bool kvmSupportsNesting;
a41c76
+    bool kvmSupportsSecureGuest;
a41c76
 
a41c76
     char *binary;
a41c76
     time_t ctime;
a41c76
@@ -1837,6 +1839,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
a41c76
     ret->invalidation = qemuCaps->invalidation;
a41c76
     ret->usedQMP = qemuCaps->usedQMP;
a41c76
     ret->kvmSupportsNesting = qemuCaps->kvmSupportsNesting;
a41c76
+    ret->kvmSupportsSecureGuest = qemuCaps->kvmSupportsSecureGuest;
a41c76
 
a41c76
     ret->ctime = qemuCaps->ctime;
a41c76
 
a41c76
@@ -4233,6 +4236,9 @@ virQEMUCapsLoadCache(virArch hostArch,
a41c76
     if (virXPathBoolean("boolean(./kvmSupportsNesting)", ctxt) > 0)
a41c76
         qemuCaps->kvmSupportsNesting = true;
a41c76
 
a41c76
+    if (virXPathBoolean("boolean(./kvmSupportsSecureGuest)", ctxt) > 0)
a41c76
+        qemuCaps->kvmSupportsSecureGuest = true;
a41c76
+
a41c76
     ret = 0;
a41c76
  cleanup:
a41c76
     VIR_FREE(str);
a41c76
@@ -4467,6 +4473,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
a41c76
     if (qemuCaps->kvmSupportsNesting)
a41c76
         virBufferAddLit(&buf, "<kvmSupportsNesting/>\n");
a41c76
 
a41c76
+    if (qemuCaps->kvmSupportsSecureGuest)
a41c76
+        virBufferAddLit(&buf, "<kvmSupportsSecureGuest/>\n");
a41c76
+
a41c76
     virBufferAdjustIndent(&buf, -2);
a41c76
     virBufferAddLit(&buf, "</qemuCaps>\n");
a41c76
 
a41c76
@@ -4506,6 +4515,49 @@ virQEMUCapsSaveFile(void *data,
a41c76
 }
a41c76
 
a41c76
 
a41c76
+/*
a41c76
+ * Check whether IBM Secure Execution (S390) is enabled
a41c76
+ */
a41c76
+static bool
a41c76
+virQEMUCapsKVMSupportsSecureGuestS390(void)
a41c76
+{
a41c76
+
a41c76
+    g_autofree char *cmdline = NULL;
a41c76
+    static const char *kValues[] = {"y", "Y", "on", "ON", "oN", "On", "1"};
a41c76
+
a41c76
+    if (!virFileIsDir("/sys/firmware/uv"))
a41c76
+        return false;
a41c76
+
a41c76
+    if (virFileReadValueString(&cmdline, "/proc/cmdline") < 0)
a41c76
+        return false;
a41c76
+
a41c76
+    /* we're prefix matching rather than equality matching here, because kernel
a41c76
+     * would treat even something like prot_virt='yFOO' as enabled */
a41c76
+    if (virKernelCmdlineMatchParam(cmdline, "prot_virt", kValues,
a41c76
+                                   G_N_ELEMENTS(kValues),
a41c76
+                                   VIR_KERNEL_CMDLINE_FLAGS_SEARCH_FIRST |
a41c76
+                                   VIR_KERNEL_CMDLINE_FLAGS_CMP_PREFIX))
a41c76
+        return true;
a41c76
+
a41c76
+    return false;
a41c76
+}
a41c76
+
a41c76
+
a41c76
+/*
a41c76
+ * Check whether the secure guest functionality is enabled.
a41c76
+ * See the specific architecture function for details on the verifications made.
a41c76
+ */
a41c76
+static bool
a41c76
+virQEMUCapsKVMSupportsSecureGuest(void)
a41c76
+{
a41c76
+    virArch arch = virArchFromHost();
a41c76
+
a41c76
+    if (ARCH_IS_S390(arch))
a41c76
+        return virQEMUCapsKVMSupportsSecureGuestS390();
a41c76
+    return false;
a41c76
+}
a41c76
+
a41c76
+
a41c76
 /* Check the kernel module parameters 'nested' file to determine if enabled
a41c76
  *
a41c76
  *   Intel: 'kvm_intel' uses 'Y'
a41c76
@@ -4685,6 +4737,13 @@ virQEMUCapsIsValid(void *data,
a41c76
                      qemuCaps->binary, qemuCaps->kvmSupportsNesting);
a41c76
             return false;
a41c76
         }
a41c76
+
a41c76
+        if (virQEMUCapsKVMSupportsSecureGuest() != qemuCaps->kvmSupportsSecureGuest) {
a41c76
+            VIR_DEBUG("Outdated capabilities for '%s': kvm kernel secure guest "
a41c76
+                      "value changed from %d",
a41c76
+                      qemuCaps->binary, qemuCaps->kvmSupportsSecureGuest);
a41c76
+            return false;
a41c76
+        }
a41c76
     }
a41c76
 
a41c76
     return true;
a41c76
@@ -5166,6 +5225,8 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
a41c76
         qemuCaps->kernelVersion = g_strdup(kernelVersion);
a41c76
 
a41c76
         qemuCaps->kvmSupportsNesting = virQEMUCapsKVMSupportsNesting();
a41c76
+
a41c76
+        qemuCaps->kvmSupportsSecureGuest = virQEMUCapsKVMSupportsSecureGuest();
a41c76
     }
a41c76
 
a41c76
     return qemuCaps;
a41c76
-- 
a41c76
2.27.0
a41c76