Commit 39fee313 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-guest_memfd_fixes-6.8' of https://github.com/kvm-x86/linux into HEAD

KVM GUEST_MEMFD fixes for 6.8:

 - Make KVM_MEM_GUEST_MEMFD mutually exclusive with KVM_MEM_READONLY to
   avoid creating ABI that KVM can't sanely support.

 - Update documentation for KVM_SW_PROTECTED_VM to make it abundantly
   clear that such VMs are purely a development and testing vehicle, and
   come with zero guarantees.

 - Limit KVM_SW_PROTECTED_VM guests to the TDP MMU, as the long term plan
   is to support confidential VMs with deterministic private memory (SNP
   and TDX) only in the TDP MMU.

 - Fix a bug in a GUEST_MEMFD negative test that resulted in false passes
   when verifying that KVM_MEM_GUEST_MEMFD memslots can't be dirty logged.
parents 1b6c146d 2dfd2383
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -8791,6 +8791,11 @@ means the VM type with value @n is supported. Possible values of @n are::
  #define KVM_X86_DEFAULT_VM	0
  #define KVM_X86_SW_PROTECTED_VM	1

Note, KVM_X86_SW_PROTECTED_VM is currently only for development and testing.
Do not use KVM_X86_SW_PROTECTED_VM for "real" VMs, and especially not in
production.  The behavior and effective ABI for software-protected VMs is
unstable.

9. Known KVM API problems
=========================

+4 −3
Original line number Diff line number Diff line
@@ -80,9 +80,10 @@ config KVM_SW_PROTECTED_VM
	depends on KVM && X86_64
	select KVM_GENERIC_PRIVATE_MEM
	help
	  Enable support for KVM software-protected VMs.  Currently "protected"
	  means the VM can be backed with memory provided by
	  KVM_CREATE_GUEST_MEMFD.
	  Enable support for KVM software-protected VMs.  Currently, software-
	  protected VMs are purely a development and testing vehicle for
	  KVM_CREATE_GUEST_MEMFD.  Attempting to run a "real" VM workload as a
	  software-protected VM will fail miserably.

	  If unsure, say "N".

+1 −1
Original line number Diff line number Diff line
@@ -4580,7 +4580,7 @@ static bool kvm_is_vm_type_supported(unsigned long type)
{
	return type == KVM_X86_DEFAULT_VM ||
	       (type == KVM_X86_SW_PROTECTED_VM &&
		IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) && tdp_enabled);
		IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) && tdp_mmu_enabled);
}

int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+11 −1
Original line number Diff line number Diff line
@@ -367,11 +367,21 @@ static void test_invalid_memory_region_flags(void)
	}

	if (supported_flags & KVM_MEM_GUEST_MEMFD) {
		int guest_memfd = vm_create_guest_memfd(vm, MEM_REGION_SIZE, 0);

		r = __vm_set_user_memory_region2(vm, 0,
						 KVM_MEM_LOG_DIRTY_PAGES | KVM_MEM_GUEST_MEMFD,
						 0, MEM_REGION_SIZE, NULL, 0, 0);
						 0, MEM_REGION_SIZE, NULL, guest_memfd, 0);
		TEST_ASSERT(r && errno == EINVAL,
			    "KVM_SET_USER_MEMORY_REGION2 should have failed, dirty logging private memory is unsupported");

		r = __vm_set_user_memory_region2(vm, 0,
						 KVM_MEM_READONLY | KVM_MEM_GUEST_MEMFD,
						 0, MEM_REGION_SIZE, NULL, guest_memfd, 0);
		TEST_ASSERT(r && errno == EINVAL,
			    "KVM_SET_USER_MEMORY_REGION2 should have failed, read-only GUEST_MEMFD memslots are unsupported");

		close(guest_memfd);
	}
}

+7 −1
Original line number Diff line number Diff line
@@ -1615,6 +1615,12 @@ static int check_memory_region_flags(struct kvm *kvm,
		valid_flags &= ~KVM_MEM_LOG_DIRTY_PAGES;

#ifdef __KVM_HAVE_READONLY_MEM
	/*
	 * GUEST_MEMFD is incompatible with read-only memslots, as writes to
	 * read-only memslots have emulated MMIO, not page fault, semantics,
	 * and KVM doesn't allow emulated MMIO for private memory.
	 */
	if (!(mem->flags & KVM_MEM_GUEST_MEMFD))
		valid_flags |= KVM_MEM_READONLY;
#endif