Message ID | 20250218172500.807733-3-tabba@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | KVM: Mapping guest_memfd backed memory at the host for software protected VMs | expand |
On 18.02.25 18:24, Fuad Tabba wrote: > Before transitioning a guest_memfd folio to unshared, thereby > disallowing access by the host and allowing the hypervisor to > transition its view of the guest page as private, we need to be > sure that the host doesn't have any references to the folio. > > This patch introduces a new type for guest_memfd folios, which > isn't activated in this series but is here as a placeholder and > to facilitate the code in the subsequent patch series. This will > be used in the future to register a callback that informs the > guest_memfd subsystem when the last reference is dropped, > therefore knowing that the host doesn't have any remaining > references. > > This patch also introduces the configuration option, > KVM_GMEM_SHARED_MEM, which toggles support for mapping > guest_memfd shared memory at the host. > > Signed-off-by: Fuad Tabba <tabba@google.com> > Acked-by: Vlastimil Babka <vbabka@suse.cz> > --- > include/linux/kvm_host.h | 4 ++++ > include/linux/page-flags.h | 17 +++++++++++++++++ > mm/debug.c | 1 + > mm/swap.c | 9 +++++++++ > virt/kvm/Kconfig | 5 +++++ > virt/kvm/guest_memfd.c | 7 +++++++ > 6 files changed, 43 insertions(+) > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index f34f4cfaa513..3ad0719bfc4f 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -2571,4 +2571,8 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, > struct kvm_pre_fault_memory *range); > #endif > > +#ifdef CONFIG_KVM_GMEM_SHARED_MEM > +void kvm_gmem_handle_folio_put(struct folio *folio); > +#endif > + > #endif > diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h > index 6dc2494bd002..734afda268ab 100644 > --- a/include/linux/page-flags.h > +++ b/include/linux/page-flags.h > @@ -933,6 +933,17 @@ enum pagetype { > PGTY_slab = 0xf5, > PGTY_zsmalloc = 0xf6, > PGTY_unaccepted = 0xf7, > + /* > + * guestmem folios are used to back VM memory as managed by guest_memfd. > + * Once the last reference is put, instead of freeing these folios back > + * to the page allocator, they are returned to guest_memfd. > + * > + * For now, guestmem will only be set on these folios as long as they > + * cannot be mapped to user space ("private state"), with the plan of > + * always setting that type once typed folios can be mapped to user > + * space cleanly. > + */ Same comment as to v3 regarding moving the comment. kvm_gmem_handle_folio_put() might be fixed with having it as an inline function for the time being as discussed. Acked-by: David Hildenbrand <david@redhat.com>
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f34f4cfaa513..3ad0719bfc4f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2571,4 +2571,8 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, struct kvm_pre_fault_memory *range); #endif +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +void kvm_gmem_handle_folio_put(struct folio *folio); +#endif + #endif diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 6dc2494bd002..734afda268ab 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -933,6 +933,17 @@ enum pagetype { PGTY_slab = 0xf5, PGTY_zsmalloc = 0xf6, PGTY_unaccepted = 0xf7, + /* + * guestmem folios are used to back VM memory as managed by guest_memfd. + * Once the last reference is put, instead of freeing these folios back + * to the page allocator, they are returned to guest_memfd. + * + * For now, guestmem will only be set on these folios as long as they + * cannot be mapped to user space ("private state"), with the plan of + * always setting that type once typed folios can be mapped to user + * space cleanly. + */ + PGTY_guestmem = 0xf8, PGTY_mapcount_underflow = 0xff }; @@ -1082,6 +1093,12 @@ FOLIO_TYPE_OPS(hugetlb, hugetlb) FOLIO_TEST_FLAG_FALSE(hugetlb) #endif +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +FOLIO_TYPE_OPS(guestmem, guestmem) +#else +FOLIO_TEST_FLAG_FALSE(guestmem) +#endif + PAGE_TYPE_OPS(Zsmalloc, zsmalloc, zsmalloc) /* diff --git a/mm/debug.c b/mm/debug.c index 8d2acf432385..08bc42c6cba8 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -56,6 +56,7 @@ static const char *page_type_names[] = { DEF_PAGETYPE_NAME(table), DEF_PAGETYPE_NAME(buddy), DEF_PAGETYPE_NAME(unaccepted), + DEF_PAGETYPE_NAME(guestmem), }; static const char *page_type_name(unsigned int page_type) diff --git a/mm/swap.c b/mm/swap.c index 47bc1bb919cc..241880a46358 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -38,6 +38,10 @@ #include <linux/local_lock.h> #include <linux/buffer_head.h> +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +#include <linux/kvm_host.h> +#endif + #include "internal.h" #define CREATE_TRACE_POINTS @@ -101,6 +105,11 @@ static void free_typed_folio(struct folio *folio) case PGTY_hugetlb: free_huge_folio(folio); return; +#endif +#ifdef CONFIG_KVM_GMEM_SHARED_MEM + case PGTY_guestmem: + kvm_gmem_handle_folio_put(folio); + return; #endif default: WARN_ON_ONCE(1); diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index 54e959e7d68f..37f7734cb10f 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -124,3 +124,8 @@ config HAVE_KVM_ARCH_GMEM_PREPARE config HAVE_KVM_ARCH_GMEM_INVALIDATE bool depends on KVM_PRIVATE_MEM + +config KVM_GMEM_SHARED_MEM + select KVM_PRIVATE_MEM + depends on !KVM_GENERIC_MEMORY_ATTRIBUTES + bool diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index b2aa6bf24d3a..c6f6792bec2a 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -312,6 +312,13 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn) return gfn - slot->base_gfn + slot->gmem.pgoff; } +#ifdef CONFIG_KVM_GMEM_SHARED_MEM +void kvm_gmem_handle_folio_put(struct folio *folio) +{ + WARN_ONCE(1, "A placeholder that shouldn't trigger. Work in progress."); +} +#endif /* CONFIG_KVM_GMEM_SHARED_MEM */ + static struct file_operations kvm_gmem_fops = { .open = generic_file_open, .release = kvm_gmem_release,