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.
This commit is contained in:
@@ -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
|
||||
=========================
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -1615,7 +1615,13 @@ static int check_memory_region_flags(struct kvm *kvm,
|
||||
valid_flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
|
||||
|
||||
#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
|
||||
|
||||
if (mem->flags & ~valid_flags)
|
||||
|
||||
Reference in New Issue
Block a user