mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
qemu: Add check for whether KVM nesting is enabled
Support for nested KVM is handled via a kernel module configuration parameters values for kvm_intel, kvm_amd, kvm_hv (PPC), or kvm (s390). While it's possible to fetch the kmod config values via virKModConfig, unfortunately that is the static value and we need to get the current/dynamic value from the kernel file system. So this patch adds a new API virHostKVMSupportsNesting that will search the 3 kernel modules to get the nesting value and check if it is 'Y' (or 'y' just in case) to return a true/false whether the KVM kernel supports nesting. We need to do this in order to handle cases where adjustments to the value are made after libvirtd is started to force a refetch of the latest QEMU capabilities since the correct CPU settings need to be made for a guest to add the "vmx=on" to/for the guest config. Signed-off-by: John Ferlan <jferlan@redhat.com> ACKed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
e0eb8a8a69
commit
b183a75319
@ -559,6 +559,7 @@ struct _virQEMUCaps {
|
||||
virObject parent;
|
||||
|
||||
bool usedQMP;
|
||||
bool kvmSupportsNesting;
|
||||
|
||||
char *binary;
|
||||
time_t ctime;
|
||||
@ -1532,6 +1533,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
|
||||
return NULL;
|
||||
|
||||
ret->usedQMP = qemuCaps->usedQMP;
|
||||
ret->kvmSupportsNesting = qemuCaps->kvmSupportsNesting;
|
||||
|
||||
if (VIR_STRDUP(ret->binary, qemuCaps->binary) < 0)
|
||||
goto error;
|
||||
@ -3591,6 +3593,9 @@ virQEMUCapsLoadCache(virArch hostArch,
|
||||
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
|
||||
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
|
||||
|
||||
if (virXPathBoolean("boolean(./kvmSupportsNesting)", ctxt) > 0)
|
||||
qemuCaps->kvmSupportsNesting = true;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(str);
|
||||
@ -3810,6 +3815,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
|
||||
if (qemuCaps->sevCapabilities)
|
||||
virQEMUCapsFormatSEVInfo(qemuCaps, &buf);
|
||||
|
||||
if (qemuCaps->kvmSupportsNesting)
|
||||
virBufferAddLit(&buf, "<kvmSupportsNesting/>\n");
|
||||
|
||||
virBufferAdjustIndent(&buf, -2);
|
||||
virBufferAddLit(&buf, "</qemuCaps>\n");
|
||||
|
||||
@ -3850,6 +3858,41 @@ virQEMUCapsSaveFile(void *data,
|
||||
}
|
||||
|
||||
|
||||
/* Check the kernel module parameters 'nested' file to determine if enabled
|
||||
*
|
||||
* Intel: 'kvm_intel' uses 'Y'
|
||||
* AMD: 'kvm_amd' uses '1'
|
||||
* PPC64: 'kvm_hv' uses 'Y'
|
||||
* S390: 'kvm' uses '1'
|
||||
*/
|
||||
static bool
|
||||
virQEMUCapsKVMSupportsNesting(void)
|
||||
{
|
||||
static char const * const kmod[] = {"kvm_intel", "kvm_amd",
|
||||
"kvm_hv", "kvm"};
|
||||
VIR_AUTOFREE(char *) value = NULL;
|
||||
int rc;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_CARDINALITY(kmod); i++) {
|
||||
VIR_FREE(value);
|
||||
rc = virFileReadValueString(&value, "/sys/module/%s/parameters/nested",
|
||||
kmod[i]);
|
||||
if (rc == -2)
|
||||
continue;
|
||||
if (rc < 0) {
|
||||
virResetLastError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value[0] == 'Y' || value[0] == 'y' || value[0] == '1')
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
virQEMUCapsIsValid(void *data,
|
||||
void *privData)
|
||||
@ -3858,6 +3901,7 @@ virQEMUCapsIsValid(void *data,
|
||||
virQEMUCapsCachePrivPtr priv = privData;
|
||||
bool kvmUsable;
|
||||
struct stat sb;
|
||||
bool kvmSupportsNesting;
|
||||
|
||||
if (!qemuCaps->binary)
|
||||
return true;
|
||||
@ -3935,6 +3979,14 @@ virQEMUCapsIsValid(void *data,
|
||||
qemuCaps->kernelVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
kvmSupportsNesting = virQEMUCapsKVMSupportsNesting();
|
||||
if (kvmSupportsNesting != qemuCaps->kvmSupportsNesting) {
|
||||
VIR_DEBUG("Outdated capabilities for '%s': kvm kernel nested "
|
||||
"value changed from %d",
|
||||
qemuCaps->binary, qemuCaps->kvmSupportsNesting);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -4579,6 +4631,8 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
|
||||
|
||||
if (VIR_STRDUP(qemuCaps->kernelVersion, kernelVersion) < 0)
|
||||
goto error;
|
||||
|
||||
qemuCaps->kvmSupportsNesting = virQEMUCapsKVMSupportsNesting();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
Loading…
x
Reference in New Issue
Block a user