Skip to content

Commit 39fee31

Browse files
committed
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.
2 parents 1b6c146 + 2dfd238 commit 39fee31

File tree

5 files changed

+28
-6
lines changed

5 files changed

+28
-6
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8791,6 +8791,11 @@ means the VM type with value @n is supported. Possible values of @n are::
87918791
#define KVM_X86_DEFAULT_VM 0
87928792
#define KVM_X86_SW_PROTECTED_VM 1
87938793

8794+
Note, KVM_X86_SW_PROTECTED_VM is currently only for development and testing.
8795+
Do not use KVM_X86_SW_PROTECTED_VM for "real" VMs, and especially not in
8796+
production. The behavior and effective ABI for software-protected VMs is
8797+
unstable.
8798+
87948799
9. Known KVM API problems
87958800
=========================
87968801

arch/x86/kvm/Kconfig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,10 @@ config KVM_SW_PROTECTED_VM
8080
depends on KVM && X86_64
8181
select KVM_GENERIC_PRIVATE_MEM
8282
help
83-
Enable support for KVM software-protected VMs. Currently "protected"
84-
means the VM can be backed with memory provided by
85-
KVM_CREATE_GUEST_MEMFD.
83+
Enable support for KVM software-protected VMs. Currently, software-
84+
protected VMs are purely a development and testing vehicle for
85+
KVM_CREATE_GUEST_MEMFD. Attempting to run a "real" VM workload as a
86+
software-protected VM will fail miserably.
8687

8788
If unsure, say "N".
8889

arch/x86/kvm/x86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4580,7 +4580,7 @@ static bool kvm_is_vm_type_supported(unsigned long type)
45804580
{
45814581
return type == KVM_X86_DEFAULT_VM ||
45824582
(type == KVM_X86_SW_PROTECTED_VM &&
4583-
IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) && tdp_enabled);
4583+
IS_ENABLED(CONFIG_KVM_SW_PROTECTED_VM) && tdp_mmu_enabled);
45844584
}
45854585

45864586
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)

tools/testing/selftests/kvm/set_memory_region_test.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,21 @@ static void test_invalid_memory_region_flags(void)
367367
}
368368

369369
if (supported_flags & KVM_MEM_GUEST_MEMFD) {
370+
int guest_memfd = vm_create_guest_memfd(vm, MEM_REGION_SIZE, 0);
371+
370372
r = __vm_set_user_memory_region2(vm, 0,
371373
KVM_MEM_LOG_DIRTY_PAGES | KVM_MEM_GUEST_MEMFD,
372-
0, MEM_REGION_SIZE, NULL, 0, 0);
374+
0, MEM_REGION_SIZE, NULL, guest_memfd, 0);
373375
TEST_ASSERT(r && errno == EINVAL,
374376
"KVM_SET_USER_MEMORY_REGION2 should have failed, dirty logging private memory is unsupported");
377+
378+
r = __vm_set_user_memory_region2(vm, 0,
379+
KVM_MEM_READONLY | KVM_MEM_GUEST_MEMFD,
380+
0, MEM_REGION_SIZE, NULL, guest_memfd, 0);
381+
TEST_ASSERT(r && errno == EINVAL,
382+
"KVM_SET_USER_MEMORY_REGION2 should have failed, read-only GUEST_MEMFD memslots are unsupported");
383+
384+
close(guest_memfd);
375385
}
376386
}
377387

virt/kvm/kvm_main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1615,7 +1615,13 @@ static int check_memory_region_flags(struct kvm *kvm,
16151615
valid_flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
16161616

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

16211627
if (mem->flags & ~valid_flags)

0 commit comments

Comments
 (0)