KVM planes head for takeoff
By Jonathan Corbet August 11, 2026
Virtualization places a guest system into a separate security domain, typically with fewer privileges than software running directly on the host. Increasingly, there is interest in creating multiple security domains within a single virtualized system as well. CPU vendors (and software vendors too) are implementing solutions; each of which, of course, is different from all of the others. KVM planes, currently under development by Jörg Rödel, Paolo Bonzini, and others in the KVM community, is an attempt to provide an abstraction layer that makes all of these features available on Linux systems; it is not a small task.
When an operating-system kernel launches within a virtual machine, it typically has full access to all aspects of that machine. Interest in confidential computing, though, is driving efforts to split up that access. So, for example, a virtual machine may have a smaller kernel within it that is charged with implementing a trusted platform module (TPM) in software; if the virtual machine as a whole can manipulate that TPM, its results cannot be trusted. But if the TPM has its own range of memory that only it can access (and which might be encrypted to strengthen that protection) and its CPU state cannot be changed from the containing VM, then it should be secure — until somebody inevitably figures out a way to break that security, of course.
Many processor families have features meant to support this sort of secure enclave. Arm CPUs can provide Realm Planes, which have varying levels of privilege regarding memory protections, exception handling, and more. AMD's SEV-SNPsecure-virtualization feature can support up to four virtual machine privilege levels with similar sorts of controls, and Intel's TDXimplements partitions. Microsoft's Hyper-Vhypervisor has the concept of Virtual Trust Levels, which supports a secure kernel and "trustlets" that carry out security-related operations. In the end, each of these features works toward the same goal, and systems developers would naturally prefer to not have to worry about the details of the specific CPU their code is running on today.
The proposed answer to this need is KVM planes, the patches for which were last posted by Rödel in June. According to this documentation patch, the "planes" name was chosen this way: "Ah, and because x86 has three names for it and Arm has one, choose the Arm name for all architectures to avoid bikeshedding and to displease everyone---including the KVM/arm64 folks, probably". This posting derives from an earlier implementation posted by Bonzini in 2025.
A plane encapsulates a privilege level implemented by the processor or hypervisor; one plane would represent an SEV-SNP virtual machine privilege level, a TDX partition, a Hyper-V virtual trust level or, yes, an Arm Realm Plane. All planes share the same address space and many processor resources, but have their own copies of the CPU register set and some other resources. Switching between planes (to allow a lower-privileged plane to request a service from a more-privileged one) is handled with calls back into the hypervisor. Each plane is represented by an integer ID, with no defined relationship between IDs and relative privilege level.
A virtual machine, at creation, will have a single plane, running in the most privileged mode. There is a new KVM ioctl()(KVM\_CREATE\_PLANE) to create a new plane; it returns a file descriptor that can be used to control that plane. Virtual CPUs are contained within planes, so each created plane must have at least one virtual CPU added to it for it to be useful. The virtual CPUs contained within a plane must be a subset of those configured for any more-privileged planes.
A plane at a given privilege level can generally set the rules for planes with lower privilege. A plane cannot, however, grant any privileges (such as access to a specific range of memory) that it does not possess itself. Certain privileges, such as the ability to control the injection and handling of interrupts, may be restricted to the most-privileged plane.
For any given virtual CPU, only one plane can be executing at any given time. The policy built into the posted patch set is that, if more than one plane is runnable, the lowest-numbered of them is run. That is a somewhat interesting choice, since the above-linked documentation patch states clearly that "KVM is currently agnostic to whether low ids are more or less privileged"; arguably, the natural expectation is that the most privileged plane would run first. Bonzini questionedthis decision, which had changed from previous versions of the patch set. He also suggested that there would be value in making it possible for the scheduling decision to be made in user space, "though that may not be very important in the grand scheme of things". There are many details in this proposal that are likely to change as the requirements come into better focus; the decision of which plane to run may well be one of them.
The patch set includes support for AMD's SEV-SNP privilege levels. It works with the Coconut secure VM service module to install that module at virtual machine privilege level zero, and a Linux system running in privilege level two. There is also a separate patch set from Sriram Nambakam using planes with the Hyper-V virtual trust levels, running the secure kernel at trust level one, and the guest kernel at trust level zero:
The RFC demonstrates loading and starting the secure kernel, communication between VTL0 and VTL1, and hypervisor-enforced kernel integrity (HEKI). The secure plane can protect VTL0 memory independently of VTL0, seal kernel text and read-only data, participate in module validation and permission changes, and validate kexec images.
The patches are intended to show how planes can be made to work with Hyper-V. Unfortunately, they are mercilessly undocumented, to the point of lacking even changelogs on most of the individual patches, making review somewhat more difficult. Some of the ideas behind HEKI in particular, which is aimed at having the privileged plane ensure the integrity of the unprivileged plane, can be seen in this (unmerged) 2023 patch series from Mickaël Salaün. (Nambakam posted a new version of these patches, with better changelogs, just as this article was being published. The work has been split into multiple parts, with one series adding host-side support and another with guest support).
The planes concept has been explored with a few patch postings at this point, along with discussions at a number of gatherings at community conferences. The KVM community is clearly trying to come up with an abstraction that can handle the features produced by CPU vendors in a general way. Chances are that this abstraction will have to evolve for a while yet before it is considered ready to set into stone, but considerable progress has been made to get it to this point.
| Index entries for this article | | | -------------------------------------- | ------------------------------------------------------------------------------- | | Kernel | Confidential computing | | Kernel | KVM | | Kernel | Virtualization |
---
to post comments
privilege levels
Posted Aug 11, 2026 18:21 UTC (Tue) by pbonzini (subscriber, #60935) \[Link\]
\> the natural expectation is that the most privileged plane would run first
Indeed it does, the problem is that in the Hyper-V VBS case the startup VTL remains the most privileged only while it's the only one (VTL0). It then creates a more privileged one (VTL1) that can arbitrarily deprivilege VTL0. The idea is that the more privileged VTLs are created before being exposed to untrusted data, and therefore VTL1 can assume that it's created in a "safe" environment.
To complicate the numbering situation, AMD VMPLs follow the same numbering as x86 rings, with 0 being the most privileged one—the opposite compared to VTLs—and in this case the starting privilege level, VMPL0, creates the \less\ privileged VMPLs.
This is the main reason why I preferred the core code to have no preferences as to which levels are more privileged and which are less privileged. Then if you enable a specific in-kernel acceleration (e.g. VBS or VMPLs) the kernel of course will assume the corresponding numbering.

