mbox series

[RFC,v2,00/11] KVM: Mapping guest_memfd backed memory at the host for software protected VMs

Message ID 20250129172320.950523-1-tabba@google.com (mailing list archive)
Headers show
Series KVM: Mapping guest_memfd backed memory at the host for software protected VMs | expand

Message

Fuad Tabba Jan. 29, 2025, 5:23 p.m. UTC
Main changes since v1 [1]:
- Added x86 support for mapping guest_memfd at the host, enabled
 only for the KVM_X86_SW_PROTECTED_VM type.
- Require setting memslot userspace_addr for guest_memfd slots
 even if shared, and remove patches that worked around that.
- Brought in more of the infrastructure from the patch series
 that allows restricted mapping of guest_memfd backed memory.
- Renamed references to "mappable" -> "shared".
- Expanded the selftests.
- Added instructions to test on x86 and arm64 (below).
- Rebased on Linux 6.13.

The purpose of this series is to serve as a base for _restricted_
mmap() support for guest_memfd backed memory at the host [2]. It
would allow experimentation with what that support would be like
in the safe environment of the software VM types, which are meant
for testing and experimentation.

This series adds a new VM type for arm64,
KVM_VM_TYPE_ARM_SW_PROTECTED, analogous to the x86
KVM_X86_SW_PROTECTED_VM. This type is to serve as a development
and testing vehicle for Confidential (CoCo) VMs.

Similar to its x86 counterpart, SW_PROTECTED is meant only for
development and testing. It's not meant to be used for "real"
VMs, and especially not in production. The behavior and effective
ABI for software-protected VMs is unstable.

This series enables mmap() and fault() support for guest_memfd
backed memory specifically for the software-protected VM types
(in x86 and arm64), only when explicitly enabled in the config.

The series is based on Linux 6.13 and much of the code within
is a subset of the latest series I sent [2], with the addition of
the new software protected vm type.

To test this series, I've pushed a kvmtool branch with support
for guest_memfd for x86 and arm64 and the new runtime options of
--guest_memfd and --sw_protected, which marks the VM as software
protected [3]. I plan on upstreaming this branch once I've tested
it more and tidied it up a bit (or a lot).

To test this patch series on x86 (I use a standard Debian image):

Build:

- Build the kernel with the following config options enabled:
defconfigs:
	x86_64_defconfig
	kvm_guest.config
config options:
	KVM
	KVM_INTEL
	KVM_PRIVATE_MEM
	KVM_SW_PROTECTED_VM
	KVM_GMEM_SHARED_MEM

- Build the kernel kvm selftest tools/testing/selftests/kvm, you
only need guest_memfd_test, e.g.:
	make EXTRA_CFLAGS="-static -DDEBUG" -C tools/testing/selftests/kvm

- Build kvmtool [3] lkvm-static (I build it on a different machine).
	make lkvm-static

Run:
Boot your Linux image with the kernel you built above.

The selftest you can run as it is:
	./guest_memfd_test

For kvmtool, where bzImage is the same as the host's:
	./lkvm-static run -c 2 -m 512 -p "break=mount" --kernel bzImage --debug --guest_memfd --sw_protected

To test this patch series on arm64 (I use a standard Debian image):

Build:

- Build the kernel with defconfig

- Build the kernel kvm selftest tools/testing/selftests/kvm, you
only need guest_memfd_test.

- Build kvmtool [3] lkvm-static (I cross compile it on a different machine).
You are likely to need libfdt as well.

For libfdt (in the same directory as kvmtool):
	git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git
	cd dtc
	export CC=aarch64-linux-gnu-gcc
	make
	cd ..

Then for kvmtool:
	make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LIBFDT_DIR=./dtc/libfdt/ lkvm-static

Run:
Boot your Linux image with the kernel you built above.

The selftest you can run as it is:
	./guest_memfd_test

For kvmtool, where Image is the same as the host's, and rootfs is
your rootfs image (in case kvmtool can't figure it out):
	./lkvm-static run -c 2 -m 512 -d rootfs --kernel Image --force-pci --irqchip gicv3 --debug --guest_memfd --sw_protected

You can find (potentially slightly outdated) instructions on how
to a full arm64 system stack under QEMU here [4].

Cheers,
/fuad

[1] https://lore.kernel.org/all/20250122152738.1173160-1-tabba@google.com/
[2] https://lore.kernel.org/all/20250117163001.2326672-1-tabba@google.com/
[3] https://android-kvm.googlesource.com/kvmtool/+/refs/heads/tabba/guestmem-6.13
[4] https://mirrors.edge.kernel.org/pub/linux/kernel/people/will/docs/qemu/qemu-arm64-howto.html

Fuad Tabba (11):
  mm: Consolidate freeing of typed folios on final folio_put()
  KVM: guest_memfd: Handle final folio_put() of guest_memfd pages
  KVM: guest_memfd: Allow host to map guest_memfd() pages
  KVM: guest_memfd: Add KVM capability to check if guest_memfd is shared
  KVM: guest_memfd: Handle in-place shared memory as guest_memfd backed
    memory
  KVM: x86: Mark KVM_X86_SW_PROTECTED_VM as supporting guest_memfd
    shared memory
  KVM: arm64: Refactor user_mem_abort() calculation of force_pte
  KVM: arm64: Handle guest_memfd()-backed guest page faults
  KVM: arm64: Introduce KVM_VM_TYPE_ARM_SW_PROTECTED machine type
  KVM: arm64: Enable mapping guest_memfd in arm64
  KVM: guest_memfd: selftests: guest_memfd mmap() test when mapping is
    allowed

 Documentation/virt/kvm/api.rst                |  5 +
 arch/arm64/include/asm/kvm_host.h             | 10 ++
 arch/arm64/kvm/Kconfig                        |  1 +
 arch/arm64/kvm/arm.c                          |  5 +
 arch/arm64/kvm/mmu.c                          | 91 ++++++++++++-------
 arch/x86/include/asm/kvm_host.h               |  5 +
 arch/x86/kvm/Kconfig                          |  3 +-
 include/linux/kvm_host.h                      | 19 +++-
 include/linux/page-flags.h                    | 22 +++++
 include/uapi/linux/kvm.h                      |  7 ++
 mm/debug.c                                    |  1 +
 mm/swap.c                                     | 27 +++++-
 tools/testing/selftests/kvm/Makefile          |  1 +
 .../testing/selftests/kvm/guest_memfd_test.c  | 75 +++++++++++++--
 tools/testing/selftests/kvm/lib/kvm_util.c    |  3 +-
 virt/kvm/Kconfig                              |  4 +
 virt/kvm/guest_memfd.c                        | 90 ++++++++++++++++++
 virt/kvm/kvm_main.c                           |  9 +-
 18 files changed, 326 insertions(+), 52 deletions(-)


base-commit: ffd294d346d185b70e28b1a28abe367bbfe53c04

Comments

David Hildenbrand Jan. 30, 2025, 4:50 p.m. UTC | #1
On 29.01.25 18:23, Fuad Tabba wrote:

Thanks for the new version

> Main changes since v1 [1]:
> - Added x86 support for mapping guest_memfd at the host, enabled
>   only for the KVM_X86_SW_PROTECTED_VM type.

Nice!

> - Require setting memslot userspace_addr for guest_memfd slots
>   even if shared, and remove patches that worked around that.
> - Brought in more of the infrastructure from the patch series
>   that allows restricted mapping of guest_memfd backed memory.

Ah, that explains why we see the page_type stuff in here now :)

> - Renamed references to "mappable" -> "shared".
> - Expanded the selftests.
> - Added instructions to test on x86 and arm64 (below).

Very nice!


I assume there is still no page conversion happening -- or is there now 
that the page_stuff thing is in here?

Would be good to spell out what's supported and what's still TBD 
regarding mmap support.
Fuad Tabba Jan. 30, 2025, 4:57 p.m. UTC | #2
Hi David,

On Thu, 30 Jan 2025 at 16:50, David Hildenbrand <david@redhat.com> wrote:
>
> On 29.01.25 18:23, Fuad Tabba wrote:
>
> Thanks for the new version
>
> > Main changes since v1 [1]:
> > - Added x86 support for mapping guest_memfd at the host, enabled
> >   only for the KVM_X86_SW_PROTECTED_VM type.
>
> Nice!
>
> > - Require setting memslot userspace_addr for guest_memfd slots
> >   even if shared, and remove patches that worked around that.
> > - Brought in more of the infrastructure from the patch series
> >   that allows restricted mapping of guest_memfd backed memory.
>
> Ah, that explains why we see the page_type stuff in here now :)
>
> > - Renamed references to "mappable" -> "shared".
> > - Expanded the selftests.
> > - Added instructions to test on x86 and arm64 (below).
>
> Very nice!
>
>
> I assume there is still no page conversion happening -- or is there now
> that the page_stuff thing is in here?
>
> Would be good to spell out what's supported and what's still TBD
> regarding mmap support.

Thanks! No page conversion happening yet. I'm rebasing the other
series, the one with the conversions, on top of this one, as well as
fixing it based on the feedback that I got.

What this is missing is the infrastructure that tracks the
mappability/shareability at the host and the guest, as well as the
implementation of the callbacks themselves. I thought I'd send this
one out now, while I work on the larger one, since this one is easier
to test, and serves as a base for the coming part.

Cheers,
/fuad

> --
> Cheers,
>
> David / dhildenb
>