Re: [PATCH v5 00/13] KVM: mm: fd-based approach for supporting KVM guest private memory
From: Quentin Perret <hidden>
Date: 2022-03-24 15:52:00
Also in:
kvm, linux-fsdevel, linux-mm, lkml, qemu-devel
Hi Chao, +CC Will and Marc for visibility. On Thursday 10 Mar 2022 at 22:08:58 (+0800), Chao Peng wrote:
This is the v5 of this series which tries to implement the fd-based KVM
guest private memory. The patches are based on latest kvm/queue branch
commit:
d5089416b7fb KVM: x86: Introduce KVM_CAP_DISABLE_QUIRKS2
Introduction
------------
In general this patch series introduce fd-based memslot which provides
guest memory through memory file descriptor fd[offset,size] instead of
hva/size. The fd can be created from a supported memory filesystem
like tmpfs/hugetlbfs etc. which we refer as memory backing store. KVM
and the the memory backing store exchange callbacks when such memslot
gets created. At runtime KVM will call into callbacks provided by the
backing store to get the pfn with the fd+offset. Memory backing store
will also call into KVM callbacks when userspace fallocate/punch hole
on the fd to notify KVM to map/unmap secondary MMU page tables.
Comparing to existing hva-based memslot, this new type of memslot allows
guest memory unmapped from host userspace like QEMU and even the kernel
itself, therefore reduce attack surface and prevent bugs.
Based on this fd-based memslot, we can build guest private memory that
is going to be used in confidential computing environments such as Intel
TDX and AMD SEV. When supported, the memory backing store can provide
more enforcement on the fd and KVM can use a single memslot to hold both
the private and shared part of the guest memory.
mm extension
---------------------
Introduces new MFD_INACCESSIBLE flag for memfd_create(), the file created
with these flags cannot read(), write() or mmap() etc via normal
MMU operations. The file content can only be used with the newly
introduced memfile_notifier extension.
The memfile_notifier extension provides two sets of callbacks for KVM to
interact with the memory backing store:
- memfile_notifier_ops: callbacks for memory backing store to notify
KVM when memory gets allocated/invalidated.
- memfile_pfn_ops: callbacks for KVM to call into memory backing store
to request memory pages for guest private memory.
The memfile_notifier extension also provides APIs for memory backing
store to register/unregister itself and to trigger the notifier when the
bookmarked memory gets fallocated/invalidated.
memslot extension
-----------------
Add the private fd and the fd offset to existing 'shared' memslot so that
both private/shared guest memory can live in one single memslot. A page in
the memslot is either private or shared. A page is private only when it's
already allocated in the backing store fd, all the other cases it's treated
as shared, this includes those already mapped as shared as well as those
having not been mapped. This means the memory backing store is the place
which tells the truth of which page is private.
Private memory map/unmap and conversion
---------------------------------------
Userspace's map/unmap operations are done by fallocate() ioctl on the
backing store fd.
- map: default fallocate() with mode=0.
- unmap: fallocate() with FALLOC_FL_PUNCH_HOLE.
The map/unmap will trigger above memfile_notifier_ops to let KVM map/unmap
secondary MMU page tables.I recently came across this series which is interesting for the Protected KVM work that's currently ongoing in the Android world (see [1], [2] or [3] for more details). The idea is similar in a number of ways to the Intel TDX stuff (from what I understand, but I'm clearly not understanding it all so, ...) or the Arm CCA solution, but using stage-2 MMUs instead of encryption; and leverages the caveat of the nVHE KVM/arm64 implementation to isolate the control of stage-2 MMUs from the host. For Protected KVM (and I suspect most other confidential computing solutions), guests have the ability to share some of their pages back with the host kernel using a dedicated hypercall. This is necessary for e.g. virtio communications, so these shared pages need to be mapped back into the VMM's address space. I'm a bit confused about how that would work with the approach proposed here. What is going to be the approach for TDX? It feels like the most 'natural' thing would be to have a KVM exit reason describing which pages have been shared back by the guest, and to then allow the VMM to mmap those specific pages in response in the memfd. Is this something that has been discussed or considered? Thanks, Quentin [1] https://lwn.net/Articles/836693/ [2] https://www.youtube.com/watch?v=wY-u6n75iXc [3] https://www.youtube.com/watch?v=54q6RzS9BpQ&t=10862s