Skip to content

Commit 4361f5a

Browse files
committed
Merge tag 'kvm-x86-fixes-6.18-rc2' of https://github.com/kvm-x86/linux into HEAD
KVM x86 fixes for 6.18: - Expand the KVM_PRE_FAULT_MEMORY selftest to add a regression test for the bug fixed by commit 3ccbf6f ("KVM: x86/mmu: Return -EAGAIN if userspace deletes/moves memslot during prefault") - Don't try to get PMU capabbilities from perf when running a CPU with hybrid CPUs/PMUs, as perf will rightly WARN. - Rework KVM_CAP_GUEST_MEMFD_MMAP (newly introduced in 6.18) into a more generic KVM_CAP_GUEST_MEMFD_FLAGS - Add a guest_memfd INIT_SHARED flag and require userspace to explicitly set said flag to initialize memory as SHARED, irrespective of MMAP. The behavior merged in 6.18 is that enabling mmap() implicitly initializes memory as SHARED, which would result in an ABI collision for x86 CoCo VMs as their memory is currently always initialized PRIVATE. - Allow mmap() on guest_memfd for x86 CoCo VMs, i.e. on VMs with private memory, to enable testing such setups, i.e. to hopefully flush out any other lurking ABI issues before 6.18 is officially released. - Add testcases to the guest_memfd selftest to cover guest_memfd without MMAP, and host userspace accesses to mmap()'d private memory.
2 parents 5d26eaa + 505f522 commit 4361f5a

File tree

17 files changed

+375
-185
lines changed

17 files changed

+375
-185
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6437,9 +6437,18 @@ most one mapping per page, i.e. binding multiple memory regions to a single
64376437
guest_memfd range is not allowed (any number of memory regions can be bound to
64386438
a single guest_memfd file, but the bound ranges must not overlap).
64396439

6440-
When the capability KVM_CAP_GUEST_MEMFD_MMAP is supported, the 'flags' field
6441-
supports GUEST_MEMFD_FLAG_MMAP. Setting this flag on guest_memfd creation
6442-
enables mmap() and faulting of guest_memfd memory to host userspace.
6440+
The capability KVM_CAP_GUEST_MEMFD_FLAGS enumerates the `flags` that can be
6441+
specified via KVM_CREATE_GUEST_MEMFD. Currently defined flags:
6442+
6443+
============================ ================================================
6444+
GUEST_MEMFD_FLAG_MMAP Enable using mmap() on the guest_memfd file
6445+
descriptor.
6446+
GUEST_MEMFD_FLAG_INIT_SHARED Make all memory in the file shared during
6447+
KVM_CREATE_GUEST_MEMFD (memory files created
6448+
without INIT_SHARED will be marked private).
6449+
Shared memory can be faulted into host userspace
6450+
page tables. Private memory cannot.
6451+
============================ ================================================
64436452

64446453
When the KVM MMU performs a PFN lookup to service a guest fault and the backing
64456454
guest_memfd has the GUEST_MEMFD_FLAG_MMAP set, then the fault will always be

arch/x86/kvm/pmu.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,18 @@ void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
108108
bool is_intel = boot_cpu_data.x86_vendor == X86_VENDOR_INTEL;
109109
int min_nr_gp_ctrs = pmu_ops->MIN_NR_GP_COUNTERS;
110110

111-
perf_get_x86_pmu_capability(&kvm_host_pmu);
112-
113111
/*
114112
* Hybrid PMUs don't play nice with virtualization without careful
115113
* configuration by userspace, and KVM's APIs for reporting supported
116114
* vPMU features do not account for hybrid PMUs. Disable vPMU support
117115
* for hybrid PMUs until KVM gains a way to let userspace opt-in.
118116
*/
119-
if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
117+
if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) {
120118
enable_pmu = false;
119+
memset(&kvm_host_pmu, 0, sizeof(kvm_host_pmu));
120+
} else {
121+
perf_get_x86_pmu_capability(&kvm_host_pmu);
122+
}
121123

122124
if (enable_pmu) {
123125
/*

arch/x86/kvm/x86.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13941,10 +13941,11 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
1394113941

1394213942
#ifdef CONFIG_KVM_GUEST_MEMFD
1394313943
/*
13944-
* KVM doesn't yet support mmap() on guest_memfd for VMs with private memory
13945-
* (the private vs. shared tracking needs to be moved into guest_memfd).
13944+
* KVM doesn't yet support initializing guest_memfd memory as shared for VMs
13945+
* with private memory (the private vs. shared tracking needs to be moved into
13946+
* guest_memfd).
1394613947
*/
13947-
bool kvm_arch_supports_gmem_mmap(struct kvm *kvm)
13948+
bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm)
1394813949
{
1394913950
return !kvm_arch_has_private_mem(kvm);
1395013951
}

include/linux/kvm_host.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,17 @@ static inline bool kvm_arch_has_private_mem(struct kvm *kvm)
729729
#endif
730730

731731
#ifdef CONFIG_KVM_GUEST_MEMFD
732-
bool kvm_arch_supports_gmem_mmap(struct kvm *kvm);
732+
bool kvm_arch_supports_gmem_init_shared(struct kvm *kvm);
733+
734+
static inline u64 kvm_gmem_get_supported_flags(struct kvm *kvm)
735+
{
736+
u64 flags = GUEST_MEMFD_FLAG_MMAP;
737+
738+
if (!kvm || kvm_arch_supports_gmem_init_shared(kvm))
739+
flags |= GUEST_MEMFD_FLAG_INIT_SHARED;
740+
741+
return flags;
742+
}
733743
#endif
734744

735745
#ifndef kvm_arch_has_readonly_mem

include/uapi/linux/kvm.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ struct kvm_enable_cap {
962962
#define KVM_CAP_ARM_EL2_E2H0 241
963963
#define KVM_CAP_RISCV_MP_STATE_RESET 242
964964
#define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243
965-
#define KVM_CAP_GUEST_MEMFD_MMAP 244
965+
#define KVM_CAP_GUEST_MEMFD_FLAGS 244
966966

967967
struct kvm_irq_routing_irqchip {
968968
__u32 irqchip;
@@ -1599,7 +1599,8 @@ struct kvm_memory_attributes {
15991599
#define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3)
16001600

16011601
#define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd)
1602-
#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0)
1602+
#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0)
1603+
#define GUEST_MEMFD_FLAG_INIT_SHARED (1ULL << 1)
16031604

16041605
struct kvm_create_guest_memfd {
16051606
__u64 size;

0 commit comments

Comments
 (0)