render / rpms / libvirt

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