If I create a machine with more CPUs than KVM supports, but specify
multiple accelerator options, QEMU will fall back to the next
accelerator.  This is great, because if I've explicitly specified
multiple accelerators, I've told QEMU I'm fine with any of them being
used to provide the machine I want.

When I create a machine with nested virtualization enabled, though,
this doesn't happen.  KVM often doesn't support it, but TCG always
does.  The nice thing to do would be for QEMU to fall back to TCG if
KVM can't provide, like it does when too many CPUs are requested.
This patch adjusts the behaviour to do that.

This is very helpful for OS development scripts that run an OS in QEMU
— I want everybody to be able to run the script, always with
virtualization enabled because the OS requires it, but for it to take
advantage of KVM acceleration when available.

Signed-off-by: Alyssa Ross <[email protected]>
---
 hw/arm/virt.c    | 6 ------
 target/arm/kvm.c | 8 ++++++++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7456614d05..0b63b2eac3 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -2372,12 +2372,6 @@ static void machvirt_init(MachineState *machine)
         exit(1);
     }
 
-    if (vms->virt && kvm_enabled() && !kvm_arm_el2_supported()) {
-        error_report("mach-virt: host kernel KVM does not support providing "
-                     "Virtualization extensions to the guest CPU");
-        exit(1);
-    }
-
     if (vms->virt && !kvm_enabled() && !tcg_enabled() && !qtest_enabled()) {
         error_report("mach-virt: %s does not support providing "
                      "Virtualization extensions to the guest CPU",
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index d4a68874b8..20dcc6a820 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -615,6 +615,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
         ret = -EINVAL;
     }
 
+    if (object_property_find(OBJECT(ms), "virtualization") &&
+        object_property_get_bool(OBJECT(ms), "virtualization", NULL) &&
+        !kvm_arm_el2_supported()) {
+        error_report("Using ARM nested virtualization with KVM requires "
+                     "a host kernel with KVM_CAP_ARM_EL2");
+        ret = -EINVAL;
+    }
+
     if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) {
         if (kvm_vm_enable_cap(s, KVM_CAP_ARM_NISV_TO_USER, 0)) {
             error_report("Failed to enable KVM_CAP_ARM_NISV_TO_USER cap");

base-commit: ae56950eac7b61b1abf42003329ee0f3ce111711
-- 
2.53.0


Reply via email to