123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- .. SPDX-License-Identifier: GPL-2.0
- ==============================
- Running nested guests with KVM
- ==============================
- A nested guest is the ability to run a guest inside another guest (it
- can be KVM-based or a different hypervisor). The straightforward
- example is a KVM guest that in turn runs on a KVM guest (the rest of
- this document is built on this example)::
- .----------------. .----------------.
- | | | |
- | L2 | | L2 |
- | (Nested Guest) | | (Nested Guest) |
- | | | |
- |----------------'--'----------------|
- | |
- | L1 (Guest Hypervisor) |
- | KVM (/dev/kvm) |
- | |
- .------------------------------------------------------.
- | L0 (Host Hypervisor) |
- | KVM (/dev/kvm) |
- |------------------------------------------------------|
- | Hardware (with virtualization extensions) |
- '------------------------------------------------------'
- Terminology:
- - L0 – level-0; the bare metal host, running KVM
- - L1 – level-1 guest; a VM running on L0; also called the "guest
- hypervisor", as it itself is capable of running KVM.
- - L2 – level-2 guest; a VM running on L1, this is the "nested guest"
- .. note:: The above diagram is modelled after the x86 architecture;
- s390x, ppc64 and other architectures are likely to have
- a different design for nesting.
- For example, s390x always has an LPAR (LogicalPARtition)
- hypervisor running on bare metal, adding another layer and
- resulting in at least four levels in a nested setup — L0 (bare
- metal, running the LPAR hypervisor), L1 (host hypervisor), L2
- (guest hypervisor), L3 (nested guest).
- This document will stick with the three-level terminology (L0,
- L1, and L2) for all architectures; and will largely focus on
- x86.
- Use Cases
- ---------
- There are several scenarios where nested KVM can be useful, to name a
- few:
- - As a developer, you want to test your software on different operating
- systems (OSes). Instead of renting multiple VMs from a Cloud
- Provider, using nested KVM lets you rent a large enough "guest
- hypervisor" (level-1 guest). This in turn allows you to create
- multiple nested guests (level-2 guests), running different OSes, on
- which you can develop and test your software.
- - Live migration of "guest hypervisors" and their nested guests, for
- load balancing, disaster recovery, etc.
- - VM image creation tools (e.g. ``virt-install``, etc) often run
- their own VM, and users expect these to work inside a VM.
- - Some OSes use virtualization internally for security (e.g. to let
- applications run safely in isolation).
- Enabling "nested" (x86)
- -----------------------
- From Linux kernel v4.20 onwards, the ``nested`` KVM parameter is enabled
- by default for Intel and AMD. (Though your Linux distribution might
- override this default.)
- In case you are running a Linux kernel older than v4.19, to enable
- nesting, set the ``nested`` KVM module parameter to ``Y`` or ``1``. To
- persist this setting across reboots, you can add it in a config file, as
- shown below:
- 1. On the bare metal host (L0), list the kernel modules and ensure that
- the KVM modules::
- $ lsmod | grep -i kvm
- kvm_intel 133627 0
- kvm 435079 1 kvm_intel
- 2. Show information for ``kvm_intel`` module::
- $ modinfo kvm_intel | grep -i nested
- parm: nested:bool
- 3. For the nested KVM configuration to persist across reboots, place the
- below in ``/etc/modprobed/kvm_intel.conf`` (create the file if it
- doesn't exist)::
- $ cat /etc/modprobe.d/kvm_intel.conf
- options kvm-intel nested=y
- 4. Unload and re-load the KVM Intel module::
- $ sudo rmmod kvm-intel
- $ sudo modprobe kvm-intel
- 5. Verify if the ``nested`` parameter for KVM is enabled::
- $ cat /sys/module/kvm_intel/parameters/nested
- Y
- For AMD hosts, the process is the same as above, except that the module
- name is ``kvm-amd``.
- Additional nested-related kernel parameters (x86)
- -------------------------------------------------
- If your hardware is sufficiently advanced (Intel Haswell processor or
- higher, which has newer hardware virt extensions), the following
- additional features will also be enabled by default: "Shadow VMCS
- (Virtual Machine Control Structure)", APIC Virtualization on your bare
- metal host (L0). Parameters for Intel hosts::
- $ cat /sys/module/kvm_intel/parameters/enable_shadow_vmcs
- Y
- $ cat /sys/module/kvm_intel/parameters/enable_apicv
- Y
- $ cat /sys/module/kvm_intel/parameters/ept
- Y
- .. note:: If you suspect your L2 (i.e. nested guest) is running slower,
- ensure the above are enabled (particularly
- ``enable_shadow_vmcs`` and ``ept``).
- Starting a nested guest (x86)
- -----------------------------
- Once your bare metal host (L0) is configured for nesting, you should be
- able to start an L1 guest with::
- $ qemu-kvm -cpu host [...]
- The above will pass through the host CPU's capabilities as-is to the
- gues); or for better live migration compatibility, use a named CPU
- model supported by QEMU. e.g.::
- $ qemu-kvm -cpu Haswell-noTSX-IBRS,vmx=on
- then the guest hypervisor will subsequently be capable of running a
- nested guest with accelerated KVM.
- Enabling "nested" (s390x)
- -------------------------
- 1. On the host hypervisor (L0), enable the ``nested`` parameter on
- s390x::
- $ rmmod kvm
- $ modprobe kvm nested=1
- .. note:: On s390x, the kernel parameter ``hpage`` is mutually exclusive
- with the ``nested`` paramter — i.e. to be able to enable
- ``nested``, the ``hpage`` parameter *must* be disabled.
- 2. The guest hypervisor (L1) must be provided with the ``sie`` CPU
- feature — with QEMU, this can be done by using "host passthrough"
- (via the command-line ``-cpu host``).
- 3. Now the KVM module can be loaded in the L1 (guest hypervisor)::
- $ modprobe kvm
- Live migration with nested KVM
- ------------------------------
- Migrating an L1 guest, with a *live* nested guest in it, to another
- bare metal host, works as of Linux kernel 5.3 and QEMU 4.2.0 for
- Intel x86 systems, and even on older versions for s390x.
- On AMD systems, once an L1 guest has started an L2 guest, the L1 guest
- should no longer be migrated or saved (refer to QEMU documentation on
- "savevm"/"loadvm") until the L2 guest shuts down. Attempting to migrate
- or save-and-load an L1 guest while an L2 guest is running will result in
- undefined behavior. You might see a ``kernel BUG!`` entry in ``dmesg``, a
- kernel 'oops', or an outright kernel panic. Such a migrated or loaded L1
- guest can no longer be considered stable or secure, and must be restarted.
- Migrating an L1 guest merely configured to support nesting, while not
- actually running L2 guests, is expected to function normally even on AMD
- systems but may fail once guests are started.
- Migrating an L2 guest is always expected to succeed, so all the following
- scenarios should work even on AMD systems:
- - Migrating a nested guest (L2) to another L1 guest on the *same* bare
- metal host.
- - Migrating a nested guest (L2) to another L1 guest on a *different*
- bare metal host.
- - Migrating a nested guest (L2) to a bare metal host.
- Reporting bugs from nested setups
- -----------------------------------
- Debugging "nested" problems can involve sifting through log files across
- L0, L1 and L2; this can result in tedious back-n-forth between the bug
- reporter and the bug fixer.
- - Mention that you are in a "nested" setup. If you are running any kind
- of "nesting" at all, say so. Unfortunately, this needs to be called
- out because when reporting bugs, people tend to forget to even
- *mention* that they're using nested virtualization.
- - Ensure you are actually running KVM on KVM. Sometimes people do not
- have KVM enabled for their guest hypervisor (L1), which results in
- them running with pure emulation or what QEMU calls it as "TCG", but
- they think they're running nested KVM. Thus confusing "nested Virt"
- (which could also mean, QEMU on KVM) with "nested KVM" (KVM on KVM).
- Information to collect (generic)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The following is not an exhaustive list, but a very good starting point:
- - Kernel, libvirt, and QEMU version from L0
- - Kernel, libvirt and QEMU version from L1
- - QEMU command-line of L1 -- when using libvirt, you'll find it here:
- ``/var/log/libvirt/qemu/instance.log``
- - QEMU command-line of L2 -- as above, when using libvirt, get the
- complete libvirt-generated QEMU command-line
- - ``cat /sys/cpuinfo`` from L0
- - ``cat /sys/cpuinfo`` from L1
- - ``lscpu`` from L0
- - ``lscpu`` from L1
- - Full ``dmesg`` output from L0
- - Full ``dmesg`` output from L1
- x86-specific info to collect
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Both the below commands, ``x86info`` and ``dmidecode``, should be
- available on most Linux distributions with the same name:
- - Output of: ``x86info -a`` from L0
- - Output of: ``x86info -a`` from L1
- - Output of: ``dmidecode`` from L0
- - Output of: ``dmidecode`` from L1
- s390x-specific info to collect
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Along with the earlier mentioned generic details, the below is
- also recommended:
- - ``/proc/sysinfo`` from L1; this will also include the info from L0
|