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

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
...@@ -8791,6 +8791,11 @@ means the VM type with value @n is supported. Possible values of @n are:: ...@@ -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_DEFAULT_VM 0
#define KVM_X86_SW_PROTECTED_VM 1 #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 9. Known KVM API problems
========================= =========================
......
...@@ -80,9 +80,10 @@ config KVM_SW_PROTECTED_VM ...@@ -80,9 +80,10 @@ config KVM_SW_PROTECTED_VM
depends on KVM && X86_64 depends on KVM && X86_64
select KVM_GENERIC_PRIVATE_MEM select KVM_GENERIC_PRIVATE_MEM
help help
Enable support for KVM software-protected VMs. Currently "protected" Enable support for KVM software-protected VMs. Currently, software-
means the VM can be backed with memory provided by protected VMs are purely a development and testing vehicle for
KVM_CREATE_GUEST_MEMFD. KVM_CREATE_GUEST_MEMFD. Attempting to run a "real" VM workload as a
software-protected VM will fail miserably.
If unsure, say "N". If unsure, say "N".
......
...@@ -4580,7 +4580,7 @@ static bool kvm_is_vm_type_supported(unsigned long type) ...@@ -4580,7 +4580,7 @@ static bool kvm_is_vm_type_supported(unsigned long type)
{ {
return type == KVM_X86_DEFAULT_VM || return type == KVM_X86_DEFAULT_VM ||
(type == KVM_X86_SW_PROTECTED_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) int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
......
...@@ -367,11 +367,21 @@ static void test_invalid_memory_region_flags(void) ...@@ -367,11 +367,21 @@ static void test_invalid_memory_region_flags(void)
} }
if (supported_flags & KVM_MEM_GUEST_MEMFD) { 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, r = __vm_set_user_memory_region2(vm, 0,
KVM_MEM_LOG_DIRTY_PAGES | KVM_MEM_GUEST_MEMFD, 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, TEST_ASSERT(r && errno == EINVAL,
"KVM_SET_USER_MEMORY_REGION2 should have failed, dirty logging private memory is unsupported"); "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);
} }
} }
......
...@@ -1615,7 +1615,13 @@ static int check_memory_region_flags(struct kvm *kvm, ...@@ -1615,7 +1615,13 @@ static int check_memory_region_flags(struct kvm *kvm,
valid_flags &= ~KVM_MEM_LOG_DIRTY_PAGES; valid_flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
#ifdef __KVM_HAVE_READONLY_MEM #ifdef __KVM_HAVE_READONLY_MEM
valid_flags |= KVM_MEM_READONLY; /*
* 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 #endif
if (mem->flags & ~valid_flags) if (mem->flags & ~valid_flags)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment