[libvirt] [PATCH RFC 1/3] qemu: Add check for whether nesting was enabled
Marc Hartmayer
mhartmay at linux.ibm.com
Wed Nov 14 10:05:12 UTC 2018
On Tue, Nov 13, 2018 at 09:21 PM +0100, John Ferlan <jferlan at redhat.com> wrote:
> Support for nested kvm is handled via a kernel module configuration
> adjustment which if done after libvirtd is started and/or the last
> QEMU capabilities adjustment can result in the inability to start a
> guest and use nested kvm until the capabilities cache is invalidated.
>
> Thus, let's fetch and save the setting during initialization and then
> when the capabilities are checked for various host related adjustments
> that could affect whether the capabilities cache is updated add a check
> whether the nested value was set for either kvm_intel or kvm_amd to
> force a refetch of the capabilities.
>
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
> src/qemu/qemu_capabilities.c | 43 ++++++++++++++++++++++++++++++++++++
> src/qemu/qemu_capspriv.h | 2 ++
> tests/qemucapabilitiestest.c | 3 +++
> 3 files changed, 48 insertions(+)
>
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 2ca5af3297..ebe0c0c7df 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -40,6 +40,7 @@
> #include "virnodesuspend.h"
> #include "virnuma.h"
> #include "virhostcpu.h"
> +#include "virkmod.h"
> #include "qemu_monitor.h"
> #include "virstring.h"
> #include "qemu_hostdev.h"
> @@ -551,6 +552,7 @@ struct _virQEMUCaps {
> virObject parent;
>
> bool usedQMP;
> + bool isNested;
>
> char *binary;
> time_t ctime;
> @@ -1512,6 +1514,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
> return NULL;
>
> ret->usedQMP = qemuCaps->usedQMP;
> + ret->isNested = qemuCaps->isNested;
>
> if (VIR_STRDUP(ret->binary, qemuCaps->binary) < 0)
> goto error;
> @@ -3567,6 +3570,9 @@ virQEMUCapsLoadCache(virArch hostArch,
> virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
> virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
>
> + qemuCaps->isNested = virXPathBoolean("count(./isNested) > 0",
> + ctxt) > 0;
> +
> ret = 0;
> cleanup:
> VIR_FREE(str);
> @@ -3786,6 +3792,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
> if (qemuCaps->sevCapabilities)
> virQEMUCapsFormatSEVInfo(qemuCaps, &buf);
>
> + if (qemuCaps->isNested)
> + virBufferAddLit(&buf, "<isNested/>\n");
> +
> virBufferAdjustIndent(&buf, -2);
> virBufferAddLit(&buf, "</qemuCaps>\n");
>
> @@ -3826,6 +3835,28 @@ virQEMUCapsSaveFile(void *data,
> }
>
>
> +static bool
> +virQEMUCapsIsNested(void)
Not sure if “isNested” is the best wording… Since we’re talking about
nested KVM support here.
> +{
> + VIR_AUTOFREE(char *) kConfig = NULL;
> +
> + if ((kConfig = virKModConfig()) &&
> + (strstr(kConfig, "kvm_intel nested=1") ||
> + strstr(kConfig, "kvm_amd nested=1")))
Please add a check for "kvm nested=1" here since this is used by s390x :)
> + return true;
> + return false;
> +}
> +
> +
> +void
> +virQEMUCapsClearIsNested(virQEMUCapsPtr qemuCaps)
> +{
> + /* For qemucapabilitiestest to avoid printing the </isNested> on
> + * hosts with nested set in the kernel */
> + qemuCaps->isNested = false;
> +}
> +
> +
> static bool
> virQEMUCapsIsValid(void *data,
> void *privData)
> @@ -3834,6 +3865,7 @@ virQEMUCapsIsValid(void *data,
> virQEMUCapsCachePrivPtr priv = privData;
> bool kvmUsable;
> struct stat sb;
> + bool isNested;
>
> if (!qemuCaps->binary)
> return true;
> @@ -3866,6 +3898,15 @@ virQEMUCapsIsValid(void *data,
> return false;
> }
>
> + /* Check if someone changed the nested={0|1} value for the kernel from
> + * the previous time we checked. If so, then refresh the capabilities. */
> + isNested = virQEMUCapsIsNested();
> + if (isNested != qemuCaps->isNested) {
> + VIR_WARN("changed kernel nested kvm value was %d", qemuCaps->isNested);
> + qemuCaps->isNested = isNested;
> + return false;
> + }
> +
> if (!virQEMUCapsGuestIsNative(priv->hostArch, qemuCaps->arch)) {
> VIR_DEBUG("Guest arch (%s) is not native to host arch (%s), "
> "skipping KVM-related checks",
> @@ -4452,6 +4493,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
> if (virQEMUCapsInitQMPMonitor(qemuCaps, cmd->mon) < 0)
> goto cleanup;
>
> + qemuCaps->isNested = virQEMUCapsIsNested();
> +
> if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
> virQEMUCapsInitQMPCommandAbort(cmd);
> if ((rc = virQEMUCapsInitQMPCommandRun(cmd, true)) != 0) {
> diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
> index 8d1a40fe74..b5d6aae2e5 100644
> --- a/src/qemu/qemu_capspriv.h
> +++ b/src/qemu/qemu_capspriv.h
> @@ -48,6 +48,8 @@ int
> virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
> qemuMonitorPtr mon);
>
> +void virQEMUCapsClearIsNested(virQEMUCapsPtr qemuCaps);
> +
> int
> virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps,
> qemuMonitorPtr mon);
> diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
> index 8fe5a55e1d..703fb6a125 100644
> --- a/tests/qemucapabilitiestest.c
> +++ b/tests/qemucapabilitiestest.c
> @@ -63,6 +63,9 @@ testQemuCaps(const void *opaque)
> qemuMonitorTestGetMonitor(mon)) < 0)
> goto cleanup;
>
> + /* Don't apply what the host has... force clear for testing purposes */
> + virQEMUCapsClearIsNested(capsActual);
> +
> if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM)) {
> qemuMonitorResetCommandID(qemuMonitorTestGetMonitor(mon));
> if (virQEMUCapsInitQMPMonitorTCG(capsActual,
> --
> 2.17.2
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>
--
Kind regards / Beste Grüße
Marc Hartmayer
IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
More information about the libvir-list
mailing list