KVM: Avoid a lurking guest_memfd ABI mess
From: | Sean Christopherson <seanjc-AT-google.com> | |
To: | Paolo Bonzini <pbonzini-AT-redhat.com>, Christian Borntraeger <borntraeger-AT-linux.ibm.com>, Janosch Frank <frankja-AT-linux.ibm.com>, Claudio Imbrenda <imbrenda-AT-linux.ibm.com> | |
Subject: | [PATCH 0/6] KVM: Avoid a lurking guest_memfd ABI mess | |
Date: | Fri, 26 Sep 2025 09:31:01 -0700 | |
Message-ID: | <20250926163114.2626257-1-seanjc@google.com> | |
Cc: | kvm-AT-vger.kernel.org, linux-kernel-AT-vger.kernel.org, David Hildenbrand <david-AT-redhat.com>, Fuad Tabba <tabba-AT-google.com>, Sean Christopherson <seanjc-AT-google.com>, Ackerley Tng <ackerleytng-AT-google.com> | |
Archive-link: | Article |
Add a guest_memfd flag, DEFAULT_SHARED, to let userspace explicitly state whether the underlying memory should default to private vs. shared. As-is, the default state is implicitly derived from the MMAP flag: guest_memfd without MMAP is private, and with MMAP is shared. That implicit behavior is going to create a mess of an ABI once in-place conversion support comes along. If the default state is implicit, then x86 CoCo VMs will end up with default state that varies based on whether or not a guest_memfd instance is configured for mmap() support. To avoid breaking guest<=>host ABI for CoCo VMs when utilizing in-place conversion, i.e. MMAP, userspace would need to immediately convert all memory from shared=>private. Ackerley's RFC for in-place conversion fudged around this by adding a flag to let userspace set the default to _private_, but that will result in a messy and hard to document ABI. For x86 CoCo VMs, memory would be private by default, unless MMAP but not INIT_PRIVATE is specified. For everything else, memory would be shared by default, sort of? Because without MMAP, the memory would be inaccessible, leading to Schrödinger's cat situation. Since odds are very good we'll end up with a flag of some kind, add one now (for 6.18) so that the default state is explicit and simple: without DEFAULT_SHARED == private, with DEFAULT_SHARED == shared. As a bonus, this allows for adding test coverage that KVM rejects faults to private memory. Ackerley Tng (1): KVM: selftests: Add test coverage for guest_memfd without GUEST_MEMFD_FLAG_MMAP Sean Christopherson (5): KVM: guest_memfd: Add DEFAULT_SHARED flag, reject user page faults if not set KVM: selftests: Stash the host page size in a global in the guest_memfd test KVM: selftests: Create a new guest_memfd for each testcase KVM: selftests: Add wrappers for mmap() and munmap() to assert success KVM: selftests: Verify that faulting in private guest_memfd memory fails Documentation/virt/kvm/api.rst | 10 +- include/uapi/linux/kvm.h | 3 +- .../testing/selftests/kvm/guest_memfd_test.c | 162 +++++++++++------- .../testing/selftests/kvm/include/kvm_util.h | 25 +++ tools/testing/selftests/kvm/lib/kvm_util.c | 44 ++--- tools/testing/selftests/kvm/mmu_stress_test.c | 5 +- .../selftests/kvm/s390/ucontrol_test.c | 16 +- .../selftests/kvm/set_memory_region_test.c | 17 +- virt/kvm/guest_memfd.c | 6 +- 9 files changed, 169 insertions(+), 119 deletions(-) base-commit: a6ad54137af92535cfe32e19e5f3bc1bb7dbd383 -- 2.51.0.536.g15c5d4f767-goog