render / rpms / libvirt

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