From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85967258CE2 for ; Tue, 7 Oct 2025 22:14:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875281; cv=none; b=PRyUIofzJy0939KVUkSZSWQkvMmY8poOK6e0ND6/k51l33/cCQj0uYeEiQ0+3w/dPW9fBuItkO+xOq4TXrZ965qrA3BwR9EU8/1akT/Tlp8ZyrsW8X/Tdya/d5H2wp1NbC2fvmtBm1FXO7XDZ73lhf13xA+avzwg/raPOqUC46k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875281; c=relaxed/simple; bh=UIqBgwsb+vRNqfEauPUfOsNdF2dMfog0jQ1gcUf0ha8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=UjulBNFvxky7zNbfUchNx0LUmegliPWRxOIRp15pjoAZ3v95ZcT14Kpebprlkkhj/szsvT33DiOAjd9Ie/lxeVghVSqeQJNgT4UUEnIFnAg1xq51bWMN0wNteHUQXqu9BEGATEd0ZodS1sP/lTN8MvrUwI99xSx9bTM+vS1SWuE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=St5gLDbT; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="St5gLDbT" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-277f0ea6ee6so87745865ad.0 for ; Tue, 07 Oct 2025 15:14:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875279; x=1760480079; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=icsR5rcCxPu2mbO19M+4yBFFv/b0hAKJOcgfFqtENIY=; b=St5gLDbTcQhOJs48MPfPI3mZvE8mIUVkx/7HWgvPGmL2uCb5m64uILR0+8wWCzDY/O La3zDvWNEB23Coxo+LmajMnvL4e3RXtKHH4+ESXgB/Td1FBVasi4HGTzPHqFPsWQYRch cNF+fhhkcZemumF8TOdiTAZbpZomzLDgFkHZ9HsWX7T7/RutSPk3CaDjnwNRTCWYuxMj UslMXxVz/yTS1RtdZCgUOZy7RMD9UfRITL4I3jwIhmz4T1/5LsRCxkcoJ8COITdMEL4m WEiqbwLErqK3f8kHDt76SMsojOl5fKY9Yy15Q7wb7Of1/dz2UxLCN0dprVtSPW3Xxb+u 9+vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875279; x=1760480079; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=icsR5rcCxPu2mbO19M+4yBFFv/b0hAKJOcgfFqtENIY=; b=xBIA7SlCHreQWEvyevQuCJ/XdryYKCvRvQcmPZvpdKU5ZlxW9XPQbL92V3FTkNQZ4b V8bw7ZBk4S0HtUFYezyubzd4ocTGmzUuDVZwJnQyrMTlP8e2iQ7mcgmfmOldIasSPoBw yoMhMh+Xe+LkfXnqNO9ZxmqS2QDGQ4LBRQUdAU1ZD8LZdFc8nZEbt350SOz9SnrENNhR 3jba4iKI3khH3x8iUoGEpjxtzNGPugjA74fEFICot3UZ42QcFacPYMtSdJg/nC3JD+eu we6OWJOUaeTbKd0MQ+uJCuq/8SRlHTwEZrAVtPvXj6CD7vtgC6LBYa7f2PaIuoCclelx /PxQ== X-Forwarded-Encrypted: i=1; AJvYcCUdwRlqwXYkZcJ08Z5sdbh/DV1xh6PgvEC38KRwH/kliAVE3FRXUpXlL+j6ZTVUAvXRAz/2Y6JfjkN4TaI=@vger.kernel.org X-Gm-Message-State: AOJu0Yyuf9NzR/pLxJG59DqAMbRSuKi7QY7A1z/wEHxRVUyEU9voR4GR sgZ45wypfgrjUAYrkSvCrO/3L1bXKAjVdgB/GSlX8Pu12EAf++FkQXvu4zkaCgVwnYgHwJIoe+N 1PzDufg== X-Google-Smtp-Source: AGHT+IFzjZnIWMgQjMlS5yIf3CAjQgFHrvUBdvw28xfclFFsf//YAI6F0Vd324LvQxWiJFyU7jWQTlDOCyA= X-Received: from plbcp5.prod.google.com ([2002:a17:902:e785:b0:290:28e2:ce55]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:1aa4:b0:27c:a35a:1321 with SMTP id d9443c01a7336-290272e6f79mr13157245ad.51.1759875278814; Tue, 07 Oct 2025 15:14:38 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:09 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-2-seanjc@google.com> Subject: [PATCH v12 01/12] KVM: guest_memfd: Rename "struct kvm_gmem" to "struct gmem_file" From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rename the "kvm_gmem" structure to "gmem_file" in anticipation of using dedicated guest_memfd inodes instead of anonyomous inodes, at which point the "kvm_gmem" nomenclature becomes quite misleading. In guest_memfd, inodes are effectively the raw underlying physical storage, and will be used to track properties of the physical memory, while each gmem file is effectively a single VM's view of that storage, and is used to track assets specific to its associated VM, e.g. memslots=3D>gmem bindings. Using "kvm_gmem" suggests that the per-VM/per-file structures are _the_ guest_memfd instance, which almost the exact opposite of reality. Opportunistically rename local variables from "gmem" to "f", again to avoid confusion once guest_memfd specific inodes come along. No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Reviewed-by: Shivank Garg Tested-by: Ackerley Tng --- virt/kvm/guest_memfd.c | 100 ++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index fbca8c0972da..3c57fb42f12c 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -7,7 +7,16 @@ =20 #include "kvm_mm.h" =20 -struct kvm_gmem { +/* + * A guest_memfd instance can be associated multiple VMs, each with its own + * "view" of the underlying physical memory. + * + * The gmem's inode is effectively the raw underlying physical storage, an= d is + * used to track properties of the physical memory, while each gmem file is + * effectively a single VM's view of that storage, and is used to track as= sets + * specific to its associated VM, e.g. memslots=3D>gmem bindings. + */ +struct gmem_file { struct kvm *kvm; struct xarray bindings; struct list_head entry; @@ -110,16 +119,16 @@ static enum kvm_gfn_range_filter kvm_gmem_get_invalid= ate_filter(struct inode *in return KVM_FILTER_PRIVATE; } =20 -static void __kvm_gmem_invalidate_begin(struct kvm_gmem *gmem, pgoff_t sta= rt, +static void __kvm_gmem_invalidate_begin(struct gmem_file *f, pgoff_t start, pgoff_t end, enum kvm_gfn_range_filter attr_filter) { bool flush =3D false, found_memslot =3D false; struct kvm_memory_slot *slot; - struct kvm *kvm =3D gmem->kvm; + struct kvm *kvm =3D f->kvm; unsigned long index; =20 - xa_for_each_range(&gmem->bindings, index, slot, start, end - 1) { + xa_for_each_range(&f->bindings, index, slot, start, end - 1) { pgoff_t pgoff =3D slot->gmem.pgoff; =20 struct kvm_gfn_range gfn_range =3D { @@ -152,20 +161,20 @@ static void kvm_gmem_invalidate_begin(struct inode *i= node, pgoff_t start, { struct list_head *gmem_list =3D &inode->i_mapping->i_private_list; enum kvm_gfn_range_filter attr_filter; - struct kvm_gmem *gmem; + struct gmem_file *f; =20 attr_filter =3D kvm_gmem_get_invalidate_filter(inode); =20 - list_for_each_entry(gmem, gmem_list, entry) - __kvm_gmem_invalidate_begin(gmem, start, end, attr_filter); + list_for_each_entry(f, gmem_list, entry) + __kvm_gmem_invalidate_begin(f, start, end, attr_filter); } =20 -static void __kvm_gmem_invalidate_end(struct kvm_gmem *gmem, pgoff_t start, +static void __kvm_gmem_invalidate_end(struct gmem_file *f, pgoff_t start, pgoff_t end) { - struct kvm *kvm =3D gmem->kvm; + struct kvm *kvm =3D f->kvm; =20 - if (xa_find(&gmem->bindings, &start, end - 1, XA_PRESENT)) { + if (xa_find(&f->bindings, &start, end - 1, XA_PRESENT)) { KVM_MMU_LOCK(kvm); kvm_mmu_invalidate_end(kvm); KVM_MMU_UNLOCK(kvm); @@ -176,10 +185,10 @@ static void kvm_gmem_invalidate_end(struct inode *ino= de, pgoff_t start, pgoff_t end) { struct list_head *gmem_list =3D &inode->i_mapping->i_private_list; - struct kvm_gmem *gmem; + struct gmem_file *f; =20 - list_for_each_entry(gmem, gmem_list, entry) - __kvm_gmem_invalidate_end(gmem, start, end); + list_for_each_entry(f, gmem_list, entry) + __kvm_gmem_invalidate_end(f, start, end); } =20 static long kvm_gmem_punch_hole(struct inode *inode, loff_t offset, loff_t= len) @@ -277,9 +286,9 @@ static long kvm_gmem_fallocate(struct file *file, int m= ode, loff_t offset, =20 static int kvm_gmem_release(struct inode *inode, struct file *file) { - struct kvm_gmem *gmem =3D file->private_data; + struct gmem_file *f =3D file->private_data; struct kvm_memory_slot *slot; - struct kvm *kvm =3D gmem->kvm; + struct kvm *kvm =3D f->kvm; unsigned long index; =20 /* @@ -299,7 +308,7 @@ static int kvm_gmem_release(struct inode *inode, struct= file *file) =20 filemap_invalidate_lock(inode->i_mapping); =20 - xa_for_each(&gmem->bindings, index, slot) + xa_for_each(&f->bindings, index, slot) WRITE_ONCE(slot->gmem.file, NULL); =20 /* @@ -307,18 +316,18 @@ static int kvm_gmem_release(struct inode *inode, stru= ct file *file) * Zap all SPTEs pointed at by this file. Do not free the backing * memory, as its lifetime is associated with the inode, not the file. */ - __kvm_gmem_invalidate_begin(gmem, 0, -1ul, + __kvm_gmem_invalidate_begin(f, 0, -1ul, kvm_gmem_get_invalidate_filter(inode)); - __kvm_gmem_invalidate_end(gmem, 0, -1ul); + __kvm_gmem_invalidate_end(f, 0, -1ul); =20 - list_del(&gmem->entry); + list_del(&f->entry); =20 filemap_invalidate_unlock(inode->i_mapping); =20 mutex_unlock(&kvm->slots_lock); =20 - xa_destroy(&gmem->bindings); - kfree(gmem); + xa_destroy(&f->bindings); + kfree(f); =20 kvm_put_kvm(kvm); =20 @@ -493,7 +502,7 @@ bool __weak kvm_arch_supports_gmem_init_shared(struct k= vm *kvm) static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) { const char *anon_name =3D "[kvm-gmem]"; - struct kvm_gmem *gmem; + struct gmem_file *f; struct inode *inode; struct file *file; int fd, err; @@ -502,14 +511,13 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t = size, u64 flags) if (fd < 0) return fd; =20 - gmem =3D kzalloc(sizeof(*gmem), GFP_KERNEL); - if (!gmem) { + f =3D kzalloc(sizeof(*f), GFP_KERNEL); + if (!f) { err =3D -ENOMEM; goto err_fd; } =20 - file =3D anon_inode_create_getfile(anon_name, &kvm_gmem_fops, gmem, - O_RDWR, NULL); + file =3D anon_inode_create_getfile(anon_name, &kvm_gmem_fops, f, O_RDWR, = NULL); if (IS_ERR(file)) { err =3D PTR_ERR(file); goto err_gmem; @@ -531,15 +539,15 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t = size, u64 flags) WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping)); =20 kvm_get_kvm(kvm); - gmem->kvm =3D kvm; - xa_init(&gmem->bindings); - list_add(&gmem->entry, &inode->i_mapping->i_private_list); + f->kvm =3D kvm; + xa_init(&f->bindings); + list_add(&f->entry, &inode->i_mapping->i_private_list); =20 fd_install(fd, file); return fd; =20 err_gmem: - kfree(gmem); + kfree(f); err_fd: put_unused_fd(fd); return err; @@ -564,7 +572,7 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_sl= ot *slot, { loff_t size =3D slot->npages << PAGE_SHIFT; unsigned long start, end; - struct kvm_gmem *gmem; + struct gmem_file *f; struct inode *inode; struct file *file; int r =3D -EINVAL; @@ -578,8 +586,8 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_sl= ot *slot, if (file->f_op !=3D &kvm_gmem_fops) goto err; =20 - gmem =3D file->private_data; - if (gmem->kvm !=3D kvm) + f =3D file->private_data; + if (f->kvm !=3D kvm) goto err; =20 inode =3D file_inode(file); @@ -593,8 +601,8 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_sl= ot *slot, start =3D offset >> PAGE_SHIFT; end =3D start + slot->npages; =20 - if (!xa_empty(&gmem->bindings) && - xa_find(&gmem->bindings, &start, end - 1, XA_PRESENT)) { + if (!xa_empty(&f->bindings) && + xa_find(&f->bindings, &start, end - 1, XA_PRESENT)) { filemap_invalidate_unlock(inode->i_mapping); goto err; } @@ -609,7 +617,7 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_sl= ot *slot, if (kvm_gmem_supports_mmap(inode)) slot->flags |=3D KVM_MEMSLOT_GMEM_ONLY; =20 - xa_store_range(&gmem->bindings, start, end - 1, slot, GFP_KERNEL); + xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNEL); filemap_invalidate_unlock(inode->i_mapping); =20 /* @@ -627,7 +635,7 @@ void kvm_gmem_unbind(struct kvm_memory_slot *slot) { unsigned long start =3D slot->gmem.pgoff; unsigned long end =3D start + slot->npages; - struct kvm_gmem *gmem; + struct gmem_file *f; struct file *file; =20 /* @@ -638,10 +646,10 @@ void kvm_gmem_unbind(struct kvm_memory_slot *slot) if (!file) return; =20 - gmem =3D file->private_data; + f =3D file->private_data; =20 filemap_invalidate_lock(file->f_mapping); - xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL); + xa_store_range(&f->bindings, start, end - 1, NULL, GFP_KERNEL); =20 /* * synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn() @@ -659,18 +667,18 @@ static struct folio *__kvm_gmem_get_pfn(struct file *= file, pgoff_t index, kvm_pfn_t *pfn, bool *is_prepared, int *max_order) { - struct file *gmem_file =3D READ_ONCE(slot->gmem.file); - struct kvm_gmem *gmem =3D file->private_data; + struct file *slot_file =3D READ_ONCE(slot->gmem.file); + struct gmem_file *f =3D file->private_data; struct folio *folio; =20 - if (file !=3D gmem_file) { - WARN_ON_ONCE(gmem_file); + if (file !=3D slot_file) { + WARN_ON_ONCE(slot_file); return ERR_PTR(-EFAULT); } =20 - gmem =3D file->private_data; - if (xa_load(&gmem->bindings, index) !=3D slot) { - WARN_ON_ONCE(xa_load(&gmem->bindings, index)); + f =3D file->private_data; + if (xa_load(&f->bindings, index) !=3D slot) { + WARN_ON_ONCE(xa_load(&f->bindings, index)); return ERR_PTR(-EIO); } =20 --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4126125A2A5 for ; Tue, 7 Oct 2025 22:14:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875282; cv=none; b=kr1F9q8GBcTlDPJB9Lby4AQ6ttBlqsEZ53nEBK6a6cPX8KPvXzwxEe0HgbMoHCLLmTBzAk/iAJc5qGONqeQ70Mj99dKqTYwcW6jOzNxpCh8lnCBgLSt67PLIZU5Zp/5XfLRxUwgd1s17gt9WJng8YRU+mMU5o4hNEUacQCQXm94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875282; c=relaxed/simple; bh=D88a6T3cHwEivrt11hcB7FfmUSn6F2rkXBumHlnlYb0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Nxr4rPHdrouZWtLKXg5A+CeLSxL33GKvPLfgrh9V57bKRdKDDYA1Q3JqNa4Zy0m0GWmmxu8ghG4YfmXoZmpv4S21NDMa+K7zxymrelpNkaN19ARH0/7n03S60zhbJg6Jvl2JBoPgCDoPfrbS1YFZCexRJLh8tksijmPWlxL6HKA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=KNfUiqfu; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KNfUiqfu" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-33428befd39so12941521a91.0 for ; Tue, 07 Oct 2025 15:14:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875281; x=1760480081; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=5dmbXUVSLKd9bSlEnT0VG6XHvP3bFxOE7VRW3AC7JgU=; b=KNfUiqfuB58nFu9qPb2P7wotXj46X72vhz+mYAy7yez0izig2Jd2gIBwSP+1G+imcI 80a6yPjWfCz11jgNha11Hhge8j9ABRCTL3tbq5YNNUG6ytsvtSANOqbCTBj6zK/hIbgE 2vsRSBQkaprW9vkcJqF2Q6wn/gQ2wjWJ66aGErNtN4/8bSTvvdyaXVipJSs2WaS4kdA3 wzZvF3q6zIW58SWnG+ry4sNKk2f9UnGQK+tMty2A2dPmLwWFZE1cEkzoLTvY16BrxQy3 2FoaDWVB5sOScOH2gjzVcF7SGF3emRGev2Dvt3RStJl/7rEucq1Thkkr1Hy6Dlh4qHWT 0T2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875281; x=1760480081; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=5dmbXUVSLKd9bSlEnT0VG6XHvP3bFxOE7VRW3AC7JgU=; b=knDNY5WV4QYnUkCJvtWjKHKX0i3Ob+0aAftE5naXK9X6k2BXBwlo7QW2KsslDG8cpe MJGOKlYMOC6pbL3b13UbguEIUwmxPtVE4nkx0JPgdmYp13HdOEozPvPcR4o4m3UNTp1e PGIsZ/54snCLPmVbqRFSRfOqFcjhCzwzAsOU58176j93b45sQc4w/hTCNV7AHH9wa97F +cCMB/hNVbyQMhtyCnxZGKp2OoI9bzheKY2uwQMT3zx967vj3P7MLquWXtXdYYhoUWgx eueoBzmANuT5G7CWD+OEalGVhDBGAJDzTLKWSc02NqXKFUZ5Q0IFAcTWhzuK2CP96Mw8 mJrA== X-Forwarded-Encrypted: i=1; AJvYcCXCKMsWnIxIe75tSshuyhPrMrYqK262WrBAFaDiptfJExG1XP5xz5kevZTAbmmGUwqtBLipH+oieW77H00=@vger.kernel.org X-Gm-Message-State: AOJu0Yyp3k2jb91musy4B+JyNZa8+Fiq4omedwx/VDXWYLz6xPmsgzQV AKLHphBquDn7wjuwd/e3BFjz7HLkmiVQhaOWpCfW1tmm/bwmO27SB0OoaJkhuR/PGTOAtr2AfQ/ EDgfZLw== X-Google-Smtp-Source: AGHT+IFtELfPuC1E9Gi/gZ0IIwRTquQz/eR0bBtgh0yn3iXudV5xJa4KSH0/8AxoiBoCF/S9YIizGIBH2jI= X-Received: from plow6.prod.google.com ([2002:a17:903:1b06:b0:290:28e2:ce51]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f602:b0:274:9dae:6a6d with SMTP id d9443c01a7336-290272c1a67mr16678315ad.34.1759875280674; Tue, 07 Oct 2025 15:14:40 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:10 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-3-seanjc@google.com> Subject: [PATCH v12 02/12] KVM: guest_memfd: Add macro to iterate over gmem_files for a mapping/inode From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a kvm_gmem_for_each_file() to make it more obvious that KVM is iterating over guest_memfd _files_, not guest_memfd instances, as could be assumed given the name "gmem_list". No functional change intended. Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Reviewed-by: Shivank Garg Tested-by: Ackerley Tng --- virt/kvm/guest_memfd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 3c57fb42f12c..9b9e239b3073 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -22,6 +22,9 @@ struct gmem_file { struct list_head entry; }; =20 +#define kvm_gmem_for_each_file(f, mapping) \ + list_for_each_entry(f, &(mapping)->i_private_list, entry) + /** * folio_file_pfn - like folio_file_page, but return a pfn. * @folio: The folio which contains this index. @@ -159,13 +162,12 @@ static void __kvm_gmem_invalidate_begin(struct gmem_f= ile *f, pgoff_t start, static void kvm_gmem_invalidate_begin(struct inode *inode, pgoff_t start, pgoff_t end) { - struct list_head *gmem_list =3D &inode->i_mapping->i_private_list; enum kvm_gfn_range_filter attr_filter; struct gmem_file *f; =20 attr_filter =3D kvm_gmem_get_invalidate_filter(inode); =20 - list_for_each_entry(f, gmem_list, entry) + kvm_gmem_for_each_file(f, inode->i_mapping) __kvm_gmem_invalidate_begin(f, start, end, attr_filter); } =20 @@ -184,10 +186,9 @@ static void __kvm_gmem_invalidate_end(struct gmem_file= *f, pgoff_t start, static void kvm_gmem_invalidate_end(struct inode *inode, pgoff_t start, pgoff_t end) { - struct list_head *gmem_list =3D &inode->i_mapping->i_private_list; struct gmem_file *f; =20 - list_for_each_entry(f, gmem_list, entry) + kvm_gmem_for_each_file(f, inode->i_mapping) __kvm_gmem_invalidate_end(f, start, end); } =20 --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33AA325DB0A for ; Tue, 7 Oct 2025 22:14:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875284; cv=none; b=LvyGk3tqVG073Qo8gyuwt7pOYp5XMdCt2o0h/YUS90KM0J72HpUWkkh0gs37V/Y2qC9/nkPDoMqRF7H08TG4wDXS/Eh2QemgzpcL49mreIb/3RMc2B0xpEgPgu1Q/0HzGlgPBXwo4fBOGCNDZ2RzfSFRofT8S3yX8Ce2e00eP50= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875284; c=relaxed/simple; bh=hk3P/iMlQ4ykxksWA+57q4ope7eH8XLXI1gf+T3z+mQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=f/yfgmBX7MxTW3xb3M1h6OH1FYvdpL1U7kzQy663z45YAmuO1XYmYqHQTqt0nAqs2Gd2zLnbm4c7aJWaRwA1QIoVy5kRAnyoptfLq7I0CffNtNNR38+MdQKxKHgN/4gZOkmoA7qR+GQXShBdv7VcHV+F+xu+/hOgat6MZVI9lnk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=saptMWIR; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="saptMWIR" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-3352a336ee1so12590063a91.0 for ; Tue, 07 Oct 2025 15:14:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875282; x=1760480082; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=XeONchAeZ2W/BnYW50Y0JuCpKNk/eh0ylYTeKOoopl0=; b=saptMWIRdKNMLNqEXGXm4a8KoGPn0bj1JmrtLpsOrCHn5eItrT5iB5fM8FPBKznQgU QdRFSTIONvBQXh77NFnGriR5f1m4L6ehixFRl4mv9RcS2yWkj31lSVcX5mTkJ2eYxPla wto56KFbdE1zU/0hgDanTXLzuqB1Vl3wkf8SJo5KTHaDejrTI5VTvvEQVLl6PYoOonOR pD+zRnUlmigIAA5Kxi5B767IQZKViilffdbwnqTeQA4zCiyd4dd1j2eRD0Nm3S+Z8Li3 BYlbQoAyuvR/U9I4+P/WSX+xnwks5ak8PvLP07BLxZzTYFfKUlf9ASU/nsbovmdtuLsA jz4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875282; x=1760480082; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=XeONchAeZ2W/BnYW50Y0JuCpKNk/eh0ylYTeKOoopl0=; b=QX35qY8VAX14jaU4gUwnFyXkaUASn6zLNrf3rTVLKomsHPS5s2jf92x2UoFFtasx8i DkgreDjDY5cWCJyYsaPhxJJ+nJqxA5Wb45Gsa10xjhpjWUiayhDjDGaMTlwzJBVm4YuX KeLmA6NYnLBxUrx+tXJNb2z6J9+z0ceSpOyryefmTT2JSubbkILPitNQGV4nSLHpCBep 91JuZ23UdMK9h3UbFXnycnblCgtUgqINa5iHSPlEEx/boGlGCriJh3oCQrQGOvyRtg+4 GDxtMsLzI09wo2e+Jl+2WPMlpUyi4bbQ7wYTAJLv8c6NHsJ2MroW+DCHGKT1N2BtmPwb mW6A== X-Forwarded-Encrypted: i=1; AJvYcCX4DUtTjCSwXZgaRjJu3ROd9ksGIfw857yj7pCImlTqE8X6DiE1FuTZW3UEETayqErCvxY98ErZMHyCR24=@vger.kernel.org X-Gm-Message-State: AOJu0YwZ4xcUOORD1HtmbH226EHIe9ZnWQ+pwxAM1wJRaXc3TMYb37SU dPoIhOjBVmK4XjvKjyfTCJZ1CXDj6HZaoLBxKNtLM7VBzVFQMdiMli1gubzNK999dmill6c9B8e 257XdTQ== X-Google-Smtp-Source: AGHT+IE2+221EmFwqFBWMvoQR4yGg9P25ItxnENkIb2SOi1cibrAfb57GoNKRhcdEePQSic/GlYtZWJds1k= X-Received: from pjwo13.prod.google.com ([2002:a17:90a:d24d:b0:32b:35fb:187f]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:3d87:b0:32e:d011:ea1c with SMTP id 98e67ed59e1d1-33b51112272mr1450486a91.15.1759875282455; Tue, 07 Oct 2025 15:14:42 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:11 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-4-seanjc@google.com> Subject: [PATCH v12 03/12] KVM: guest_memfd: Use guest mem inodes instead of anonymous inodes From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ackerley Tng guest_memfd's inode represents memory the guest_memfd is providing. guest_memfd's file represents a struct kvm's view of that memory. Using a custom inode allows customization of the inode teardown process via callbacks. For example, ->evict_inode() allows customization of the truncation process on file close, and ->destroy_inode() and ->free_inode() allow customization of the inode freeing process. Customizing the truncation process allows flexibility in management of guest_memfd memory and customization of the inode freeing process allows proper cleanup of memory metadata stored on the inode. Memory metadata is more appropriately stored on the inode (as opposed to the file), since the metadata is for the memory and is not unique to a specific binding and struct kvm. Acked-by: David Hildenbrand Co-developed-by: Fuad Tabba Signed-off-by: Fuad Tabba Signed-off-by: Ackerley Tng Signed-off-by: Shivank Garg Tested-by: Ashish Kalra [sean: drop helpers, open code logic in __kvm_gmem_create()] Signed-off-by: Sean Christopherson --- include/uapi/linux/magic.h | 1 + virt/kvm/guest_memfd.c | 82 +++++++++++++++++++++++++++++++------- virt/kvm/kvm_main.c | 7 +++- virt/kvm/kvm_mm.h | 9 +++-- 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index bb575f3ab45e..638ca21b7a90 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h @@ -103,5 +103,6 @@ #define DEVMEM_MAGIC 0x454d444d /* "DMEM" */ #define SECRETMEM_MAGIC 0x5345434d /* "SECM" */ #define PID_FS_MAGIC 0x50494446 /* "PIDF" */ +#define GUEST_MEMFD_MAGIC 0x474d454d /* "GMEM" */ =20 #endif /* __LINUX_MAGIC_H__ */ diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 9b9e239b3073..2a580b2bdc9d 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -1,12 +1,16 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include +#include #include +#include #include -#include =20 #include "kvm_mm.h" =20 +static struct vfsmount *kvm_gmem_mnt; + /* * A guest_memfd instance can be associated multiple VMs, each with its own * "view" of the underlying physical memory. @@ -426,11 +430,6 @@ static struct file_operations kvm_gmem_fops =3D { .fallocate =3D kvm_gmem_fallocate, }; =20 -void kvm_gmem_init(struct module *module) -{ - kvm_gmem_fops.owner =3D module; -} - static int kvm_gmem_migrate_folio(struct address_space *mapping, struct folio *dst, struct folio *src, enum migrate_mode mode) @@ -502,7 +501,7 @@ bool __weak kvm_arch_supports_gmem_init_shared(struct k= vm *kvm) =20 static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) { - const char *anon_name =3D "[kvm-gmem]"; + static const char *name =3D "[kvm-gmem]"; struct gmem_file *f; struct inode *inode; struct file *file; @@ -518,16 +517,17 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t = size, u64 flags) goto err_fd; } =20 - file =3D anon_inode_create_getfile(anon_name, &kvm_gmem_fops, f, O_RDWR, = NULL); - if (IS_ERR(file)) { - err =3D PTR_ERR(file); + /* __fput() will take care of fops_put(). */ + if (!fops_get(&kvm_gmem_fops)) { + err =3D -ENOENT; goto err_gmem; } =20 - file->f_flags |=3D O_LARGEFILE; - - inode =3D file->f_inode; - WARN_ON(file->f_mapping !=3D inode->i_mapping); + inode =3D anon_inode_make_secure_inode(kvm_gmem_mnt->mnt_sb, name, NULL); + if (IS_ERR(inode)) { + err =3D PTR_ERR(inode); + goto err_fops; + } =20 inode->i_private =3D (void *)(unsigned long)flags; inode->i_op =3D &kvm_gmem_iops; @@ -539,6 +539,15 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t s= ize, u64 flags) /* Unmovable mappings are supposed to be marked unevictable as well. */ WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping)); =20 + file =3D alloc_file_pseudo(inode, kvm_gmem_mnt, name, O_RDWR, &kvm_gmem_f= ops); + if (IS_ERR(file)) { + err =3D PTR_ERR(file); + goto err_inode; + } + + file->f_flags |=3D O_LARGEFILE; + file->private_data =3D f; + kvm_get_kvm(kvm); f->kvm =3D kvm; xa_init(&f->bindings); @@ -547,6 +556,10 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t s= ize, u64 flags) fd_install(fd, file); return fd; =20 +err_inode: + iput(inode); +err_fops: + fops_put(&kvm_gmem_fops); err_gmem: kfree(f); err_fd: @@ -819,3 +832,44 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gf= n, void __user *src, long } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_populate); #endif + +static int kvm_gmem_init_fs_context(struct fs_context *fc) +{ + if (!init_pseudo(fc, GUEST_MEMFD_MAGIC)) + return -ENOMEM; + + fc->s_iflags |=3D SB_I_NOEXEC; + fc->s_iflags |=3D SB_I_NODEV; + + return 0; +} + +static struct file_system_type kvm_gmem_fs =3D { + .name =3D "guest_memfd", + .init_fs_context =3D kvm_gmem_init_fs_context, + .kill_sb =3D kill_anon_super, +}; + +static int kvm_gmem_init_mount(void) +{ + kvm_gmem_mnt =3D kern_mount(&kvm_gmem_fs); + + if (IS_ERR(kvm_gmem_mnt)) + return PTR_ERR(kvm_gmem_mnt); + + kvm_gmem_mnt->mnt_flags |=3D MNT_NOEXEC; + return 0; +} + +int kvm_gmem_init(struct module *module) +{ + kvm_gmem_fops.owner =3D module; + + return kvm_gmem_init_mount(); +} + +void kvm_gmem_exit(void) +{ + kern_unmount(kvm_gmem_mnt); + kvm_gmem_mnt =3D NULL; +} diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b7a0ae2a7b20..4845e5739436 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -6517,7 +6517,9 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align,= struct module *module) if (WARN_ON_ONCE(r)) goto err_vfio; =20 - kvm_gmem_init(module); + r =3D kvm_gmem_init(module); + if (r) + goto err_gmem; =20 r =3D kvm_init_virtualization(); if (r) @@ -6538,6 +6540,8 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align,= struct module *module) err_register: kvm_uninit_virtualization(); err_virt: + kvm_gmem_exit(); +err_gmem: kvm_vfio_ops_exit(); err_vfio: kvm_async_pf_deinit(); @@ -6569,6 +6573,7 @@ void kvm_exit(void) for_each_possible_cpu(cpu) free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); kmem_cache_destroy(kvm_vcpu_cache); + kvm_gmem_exit(); kvm_vfio_ops_exit(); kvm_async_pf_deinit(); kvm_irqfd_exit(); diff --git a/virt/kvm/kvm_mm.h b/virt/kvm/kvm_mm.h index 31defb08ccba..9fcc5d5b7f8d 100644 --- a/virt/kvm/kvm_mm.h +++ b/virt/kvm/kvm_mm.h @@ -68,17 +68,18 @@ static inline void gfn_to_pfn_cache_invalidate_start(st= ruct kvm *kvm, #endif /* HAVE_KVM_PFNCACHE */ =20 #ifdef CONFIG_KVM_GUEST_MEMFD -void kvm_gmem_init(struct module *module); +int kvm_gmem_init(struct module *module); +void kvm_gmem_exit(void); int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args); int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, unsigned int fd, loff_t offset); void kvm_gmem_unbind(struct kvm_memory_slot *slot); #else -static inline void kvm_gmem_init(struct module *module) +static inline int kvm_gmem_init(struct module *module) { - + return 0; } - +static inline void kvm_gmem_exit(void) {}; static inline int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, unsigned int fd, loff_t offset) --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03C26261B76 for ; Tue, 7 Oct 2025 22:14:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875286; cv=none; b=GRSpMtpdjmH6LvWe8DJIkmCn4c2ydATL2paBmsiPeLAVkUkaBgo7M5RKCgG9K3IsBRC5yXWh1GJD5YHjmhqwtNp6+byHcrll+l+SSn+To7jaCAIdigZ8mcPKvFh/49m2zRRLEPWEIsxByob3iYBPFqurmR1yQPevBR6CL1oVAfQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875286; c=relaxed/simple; bh=hLovmYk8bySz7R8bk2raTs2ZMWeD3KM3QSIpRcC8qVs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EfWKh4n5QD9PGZ19aBnDKVUvHNfs+w9O4qfWEbC/3hOH45yvZ+O7i3MeRykklQe5ISpcHk+su9aDBhZZgWAuFd/El9sODLpmPg4+xJwOQWTcO8oVPzNlgADYuJ1uT7Hcc0NyRhd0QLMW2EHxeLvYd74w7uYLrKBtBCU4YF9mRjw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=QfR+x7kz; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="QfR+x7kz" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-28e8112143fso31353275ad.2 for ; Tue, 07 Oct 2025 15:14:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875284; x=1760480084; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=taWA6Z3KD+nH98ISDpDB0Js/qA9hrmRliA7l8Dl3Bbs=; b=QfR+x7kzntzdHnNzlqEseSWlf2/sqHtvjOBi3XpUrRsSnPGc8sUNvU/QtznXgaAtlE DdPq4dSfmw8Jt7R0le9XQGAOfvlz4ptKVuhSlECu4cdSmKYwkvxl18Au0XI41vnUdHME So5OnymSuwfHlhINco3ve3NMuQwXarFQcdsZ6Npj8Yrf6CmPkb46LB4G5Nys3vTupsgo Irw1llYBnUtFvgRRZ/XTHfE6g+HBZdF7tqTcLF3gIgyDIyeqqvhscUguqh59CmOmPzg4 szd7gZAPOBXVPeF9UwsGSXazDSsQde1Rf+Wl8oDbzX/1M7iLCClaOUobEYBXZ5Nzix9K rpzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875284; x=1760480084; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=taWA6Z3KD+nH98ISDpDB0Js/qA9hrmRliA7l8Dl3Bbs=; b=hZ0Om7Ca5t30QUbL6cd8DpSjScCp+MfW4k1KTG80dOfeI0x2HtLNjp/XsO1fV+8QhS zqBd/VUKvm5ys98TJJRVA2lh6uAg15WhxBZWDdyFQi7MBMF375NBOHH1hvC0Zc/4lf4z YG9FAyQp8GCLE6Nw/dhJ1sNmPhlxDNVj39sMjzbIR184b4BCronfEzDRwTl5Kdg1Jj9P 9HXv+VXNJkZVOkEoLSu3568XQwc0svO6MJzOxsB8uMYKECGuKTWqNjHDn4jvKepF20rk o9TyUqod9YyDKG6NjSfd7jIQbGO/Vmh0EWdEcnnO1CjjK1HvST5yVKEcrANIee+62fuF EyTg== X-Forwarded-Encrypted: i=1; AJvYcCXzdmi7GVFq7S7GKOJH619dzGoE3CI2kCURpNjr3JxNUGOPFXWliNHAIgTGvstHP1e0EsSJOL8h0OEoskw=@vger.kernel.org X-Gm-Message-State: AOJu0YzLrAt9K7mRBTBWW/zwY5cHUIUaixrps1Khhu45rAS+hVHlEqS8 i90tczg3dCHqMQ8BqKueVhynbDDq2vvzZvNwkclSv+qzhSRZaIq1oJ8z4rdx9bHowHUhIu+c8wN X/HfZFg== X-Google-Smtp-Source: AGHT+IG9oleyJb8iura9cqY09UwB/z7uMhOzD+raOSeu/vbFWL+mfa3tRg9JWsWtb4qRWng07qdUpuou8jY= X-Received: from pjbsx11.prod.google.com ([2002:a17:90b:2ccb:b0:32e:d644:b829]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:38cc:b0:32e:f1c:e778 with SMTP id 98e67ed59e1d1-33b51105f5dmr1325599a91.3.1759875284309; Tue, 07 Oct 2025 15:14:44 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:12 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-5-seanjc@google.com> Subject: [PATCH v12 04/12] KVM: guest_memfd: Add slab-allocated inode cache From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Shivank Garg Add a dedicated gmem_inode structure and a slab-allocateda inode cache for guest memory backing, similar to how shmem handles inodes. This adds the necessary allocation/destruction functions and prepares for upcoming guest_memfd NUMA policy support changes. Using a dedicated structure will also allow for additional cleanups, e.g. to track flags in gmem_inode instead of i_private. Signed-off-by: Shivank Garg Tested-by: Ashish Kalra [sean: s/kvm_gmem_inode_info/gmem_inode, name init_once()] Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Tested-by: Ackerley Tng --- virt/kvm/guest_memfd.c | 77 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 2a580b2bdc9d..cc3b25155726 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -26,6 +26,15 @@ struct gmem_file { struct list_head entry; }; =20 +struct gmem_inode { + struct inode vfs_inode; +}; + +static __always_inline struct gmem_inode *GMEM_I(struct inode *inode) +{ + return container_of(inode, struct gmem_inode, vfs_inode); +} + #define kvm_gmem_for_each_file(f, mapping) \ list_for_each_entry(f, &(mapping)->i_private_list, entry) =20 @@ -833,13 +842,61 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_g= fn, void __user *src, long EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gmem_populate); #endif =20 +static struct kmem_cache *kvm_gmem_inode_cachep; + +static void kvm_gmem_init_inode_once(void *__gi) +{ + struct gmem_inode *gi =3D __gi; + + /* + * Note! Don't initialize the inode with anything specific to the + * guest_memfd instance, or that might be specific to how the inode is + * used (from the VFS-layer's perspective). This hook is called only + * during the initial slab allocation, i.e. only fields/state that are + * idempotent across _all_ use of the inode _object_ can be initialized + * at this time! + */ + inode_init_once(&gi->vfs_inode); +} + +static struct inode *kvm_gmem_alloc_inode(struct super_block *sb) +{ + struct gmem_inode *gi; + + gi =3D alloc_inode_sb(sb, kvm_gmem_inode_cachep, GFP_KERNEL); + if (!gi) + return NULL; + + return &gi->vfs_inode; +} + +static void kvm_gmem_destroy_inode(struct inode *inode) +{ +} + +static void kvm_gmem_free_inode(struct inode *inode) +{ + kmem_cache_free(kvm_gmem_inode_cachep, GMEM_I(inode)); +} + +static const struct super_operations kvm_gmem_super_operations =3D { + .statfs =3D simple_statfs, + .alloc_inode =3D kvm_gmem_alloc_inode, + .destroy_inode =3D kvm_gmem_destroy_inode, + .free_inode =3D kvm_gmem_free_inode, +}; + static int kvm_gmem_init_fs_context(struct fs_context *fc) { + struct pseudo_fs_context *ctx; + if (!init_pseudo(fc, GUEST_MEMFD_MAGIC)) return -ENOMEM; =20 fc->s_iflags |=3D SB_I_NOEXEC; fc->s_iflags |=3D SB_I_NODEV; + ctx =3D fc->fs_private; + ctx->ops =3D &kvm_gmem_super_operations; =20 return 0; } @@ -863,13 +920,31 @@ static int kvm_gmem_init_mount(void) =20 int kvm_gmem_init(struct module *module) { + struct kmem_cache_args args =3D { + .align =3D 0, + .ctor =3D kvm_gmem_init_inode_once, + }; + int ret; + kvm_gmem_fops.owner =3D module; + kvm_gmem_inode_cachep =3D kmem_cache_create("kvm_gmem_inode_cache", + sizeof(struct gmem_inode), + &args, SLAB_ACCOUNT); + if (!kvm_gmem_inode_cachep) + return -ENOMEM; =20 - return kvm_gmem_init_mount(); + ret =3D kvm_gmem_init_mount(); + if (ret) { + kmem_cache_destroy(kvm_gmem_inode_cachep); + return ret; + } + return 0; } =20 void kvm_gmem_exit(void) { kern_unmount(kvm_gmem_mnt); kvm_gmem_mnt =3D NULL; + rcu_barrier(); + kmem_cache_destroy(kvm_gmem_inode_cachep); } --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DEAE4261B94 for ; Tue, 7 Oct 2025 22:14:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875288; cv=none; b=S9O2FSlZC9h3G9Jgk1fmSEghjqqQFPw5dTNATXWe64FZWUngh3OmIKIkJD2XAdoGmmDBaz3Ktz+WG21iqFcHsp/1Z2yJhqt1hQolfHVHLUlHSx4xVKI7O56ATK+KMCS2a5M1GRd4nAaTmpjzRXA+w7K5CrGml6zPaEjcx1TWbdE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875288; c=relaxed/simple; bh=vJiVcm/hHEBDVcPDPylwZWAoBHhJCbfQE2uP4IJza8w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BM3O0N8yM9Rh+UXNCu3kH+qGIz3S1+OtATjDBHkC7C3EFoNhv5aFiKSFP+C3hiiPeVb4GdswzcXalX2M4q+c1CueVrnUviKnLhZv2r9onIpL5/ANOj/VAoH9zxKU8MWskWnCW7XmVgdBxZ8G/6TU6EeVEfwlb1U4x6P7IEeJSM4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=JihKOyBM; arc=none smtp.client-ip=209.85.215.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="JihKOyBM" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-b471737e673so8567971a12.1 for ; Tue, 07 Oct 2025 15:14:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875286; x=1760480086; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=gNU+HQsGvlmXwK42mozGB/w8m3B2kCFg6kDxESGSNsw=; b=JihKOyBMq9MxSARhV6e27Rutc+dMr8Bou+rrm1b4wWYdwvo3m+pmEQcN1PqwW/iPWA 2aHSdsgS+UaXsQT/7b59Hx1f0ABRDeRnrzICPqgevQAljmKEBZNYyj3vVsf4PdrtuZKg 6YYCKGIe4d97Kyx20zeu30O9Ts7+Kj+xCtzKlgrhM+ISXECTjalgE/hOhawtKSbsHvk8 kqH4Z/qY+TC781ZZN+I0DB9M4ovb5MNLE1cj5iWilr3yseqeBaNZwUa28rSRhERQblFX O5CzmMogZGeqSP2nnaVzTTRJYXX/sNkxZnVR7IUzJF+ldGpREA1y3R8hAXJgV4s36I3h sAPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875286; x=1760480086; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=gNU+HQsGvlmXwK42mozGB/w8m3B2kCFg6kDxESGSNsw=; b=CSvIjBBl5KWWJ/4LXA9RMc9VpvXOupcjdcRno2hHPAMl1wlgKRWWC2fF6Mt1fk1EPF S2Mjeu2QJGiq2Ar9B9lWaaCBkKxgsUUrrqc6vB4I+lWk0JWZLdD0nqm/tQrj1Veek5/R tdMXZce1ks8x2aM4ozMH5V2Mgq/BDjjU0l5ZgtKzm8HtsZMuP/ely5tFWEIzOJ1PE1yy QEYllojvssbpk0LIRveUmumllaQ8A0YjfITDnAvABmWYXx+xzI1hGsRjNIlwHxFzK73y R2BmJq21v/7opxegCzhdEudXzt57wc6ljfjC1r03o0kMWQ4oPyOWu/1Qy89UNQx8CaHY MVhQ== X-Forwarded-Encrypted: i=1; AJvYcCWeCf4lI18gWu+GhFpDJdYjtbrVCJqQUIKKBOmA+DDTOamwF7ggTItbePWKd+ngtZCetrCPVwaZECD4cuA=@vger.kernel.org X-Gm-Message-State: AOJu0YxNUgGH+BvOdxUmlmNcdz4u0hQa/+gRaH/o+C9IfDMOBEwSNmAy 7rMtBK2QvRC85zlL2n/5gGn2XOlIXyplkK7Su+vkSAlHV6aJXPIaA4VWd2vKDSyDXKgQB5nX5t6 zO9unbQ== X-Google-Smtp-Source: AGHT+IGsPoJFOynSay0ELmZDfFhnfNRyjkBL7llPocXzISl5rOG0O7IaOg1XPUo94bJb1i3k0OW8/UjXMo0= X-Received: from pgam19.prod.google.com ([2002:a05:6a02:2b53:b0:b63:2a6b:80b4]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7187:b0:2fb:add5:5574 with SMTP id adf61e73a8af0-32da845e5d8mr1080588637.47.1759875286183; Tue, 07 Oct 2025 15:14:46 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:13 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-6-seanjc@google.com> Subject: [PATCH v12 05/12] KVM: guest_memfd: Enforce NUMA mempolicy using shared policy From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Shivank Garg Previously, guest-memfd allocations followed local NUMA node id in absence of process mempolicy, resulting in arbitrary memory allocation. Moreover, mbind() couldn't be used by the VMM as guest memory wasn't mapped into userspace when allocation occurred. Enable NUMA policy support by implementing vm_ops for guest-memfd mmap operation. This allows the VMM to map the memory and use mbind() to set the desired NUMA policy. The policy is stored in the inode structure via kvm_gmem_inode_info, as memory policy is a property of the memory (struct inode) itself. The policy is then retrieved via mpol_shared_policy_lookup() and passed to filemap_grab_folio_mpol() to ensure that allocations follow the specified memory policy. This enables the VMM to control guest memory NUMA placement by calling mbind() on the mapped memory regions, providing fine-grained control over guest memory allocation across NUMA nodes. The policy change only affect future allocations and does not migrate existing memory. This matches mbind(2)'s default behavior which affects only new allocations unless overridden with MPOL_MF_MOVE/MPOL_MF_MOVE_ALL flags, which are not supported for guest_memfd as it is unmovable. Suggested-by: David Hildenbrand Acked-by: David Hildenbrand Acked-by: Vlastimil Babka Signed-off-by: Shivank Garg Tested-by: Ashish Kalra [sean: document the ABI impact of the ->get_policy() hook] Signed-off-by: Sean Christopherson --- virt/kvm/guest_memfd.c | 69 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index cc3b25155726..95267c92983b 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include =20 @@ -27,6 +28,7 @@ struct gmem_file { }; =20 struct gmem_inode { + struct shared_policy policy; struct inode vfs_inode; }; =20 @@ -112,6 +114,19 @@ static int kvm_gmem_prepare_folio(struct kvm *kvm, str= uct kvm_memory_slot *slot, return r; } =20 +static struct mempolicy *kvm_gmem_get_folio_policy(struct gmem_inode *gi, + pgoff_t index) +{ +#ifdef CONFIG_NUMA + struct mempolicy *mpol; + + mpol =3D mpol_shared_policy_lookup(&gi->policy, index); + return mpol ? mpol : get_task_policy(current); +#else + return NULL; +#endif +} + /* * Returns a locked folio on success. The caller is responsible for * setting the up-to-date flag before the memory is mapped into the guest. @@ -124,7 +139,25 @@ static int kvm_gmem_prepare_folio(struct kvm *kvm, str= uct kvm_memory_slot *slot, static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) { /* TODO: Support huge pages. */ - return filemap_grab_folio(inode->i_mapping, index); + struct mempolicy *policy; + struct folio *folio; + + /* + * Fast-path: See if folio is already present in mapping to avoid + * policy_lookup. + */ + folio =3D __filemap_get_folio(inode->i_mapping, index, + FGP_LOCK | FGP_ACCESSED, 0); + if (!IS_ERR(folio)) + return folio; + + policy =3D kvm_gmem_get_folio_policy(GMEM_I(inode), index); + folio =3D __filemap_get_folio_mpol(inode->i_mapping, index, + FGP_LOCK | FGP_ACCESSED | FGP_CREAT, + mapping_gfp_mask(inode->i_mapping), policy); + mpol_cond_put(policy); + + return folio; } =20 static enum kvm_gfn_range_filter kvm_gmem_get_invalidate_filter(struct ino= de *inode) @@ -413,8 +446,38 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct v= m_fault *vmf) return ret; } =20 +#ifdef CONFIG_NUMA +static int kvm_gmem_set_policy(struct vm_area_struct *vma, struct mempolic= y *mpol) +{ + struct inode *inode =3D file_inode(vma->vm_file); + + return mpol_set_shared_policy(&GMEM_I(inode)->policy, vma, mpol); +} + +static struct mempolicy *kvm_gmem_get_policy(struct vm_area_struct *vma, + unsigned long addr, pgoff_t *pgoff) +{ + struct inode *inode =3D file_inode(vma->vm_file); + + *pgoff =3D vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); + + /* + * Note! Directly return whatever the lookup returns, do NOT return + * the current task's policy as is done when looking up the policy for + * a specific folio. Kernel ABI for get_mempolicy() is to return + * MPOL_DEFAULT when there is no defined policy, not whatever the + * default policy resolves to. + */ + return mpol_shared_policy_lookup(&GMEM_I(inode)->policy, *pgoff); +} +#endif /* CONFIG_NUMA */ + static const struct vm_operations_struct kvm_gmem_vm_ops =3D { - .fault =3D kvm_gmem_fault_user_mapping, + .fault =3D kvm_gmem_fault_user_mapping, +#ifdef CONFIG_NUMA + .get_policy =3D kvm_gmem_get_policy, + .set_policy =3D kvm_gmem_set_policy, +#endif }; =20 static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) @@ -867,11 +930,13 @@ static struct inode *kvm_gmem_alloc_inode(struct supe= r_block *sb) if (!gi) return NULL; =20 + mpol_shared_policy_init(&gi->policy, NULL); return &gi->vfs_inode; } =20 static void kvm_gmem_destroy_inode(struct inode *inode) { + mpol_free_shared_policy(&GMEM_I(inode)->policy); } =20 static void kvm_gmem_free_inode(struct inode *inode) --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9EB8D266EEA for ; Tue, 7 Oct 2025 22:14:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875290; cv=none; b=twqV6e9fX+scPu9W6vDrWVGxwIK6Cvkoqu5NYRGJafC8Hm44Kxtqzu+5LyO53gub/L6EITedLrkXUMrG69wdhY4c2oTQBGY/kAHDKPtbCdWyi0AErl2HRElhKBsiHp1my2GDFsQ+c6bQB96pQUb9tSy2XmHwKMWJixokLLVP32Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875290; c=relaxed/simple; bh=9QNfABOWraA3taQoApqjT7Pwa5AuzjKaFuc0/UUE1Pg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ZpZXwwVlVQA70VDhi7jzFrLbIjj1Gl8Pawqjm48o+1KVcIgrC5AGkBxrfMcyncjUDycbpNGMBrHn6KRgBg3Pd+nJPAJ8U5Hs5L7H+rLb44bSLgO53rFLQkHJxlSPGZ2+IXY+awwUxzh3whyGXqq7blMBRurBH1TyUm+9DGsQvpE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3uxT0e+P; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3uxT0e+P" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-32ecab3865dso9738972a91.1 for ; Tue, 07 Oct 2025 15:14:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875288; x=1760480088; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=4KNNgsguWMAVMteoKqbz2qkx1TQM7zG2UmyWb4nmWLc=; b=3uxT0e+Pr6XrtdEkZqp3ijc3qZD4WWvfy9cl1pPtgZolSOzzCU/03X17zDBGT/0dxP D+8UflqoCGr1xqOQpOS+QofLyYOuyDOYSIvXKNr5ZRhQw3adjm435AZREXHO/ZUnmU95 wK23FgIDJL+cyOphdRWFdyIPdd8OFyWVnzdctAgzRqF4mxkysXgzX16khn7TmHIgRiFD OtbuSnxhBlny238rxtg5yE3C3GpArTIW9bEfOvSH5Vy0kqWU9TjDWKHx4PknVLzDK+0s LwsgP/zA/EZwO1z37baqQnGs4zG+q2ixRmUyrB06+C8/Mszs5Xjd25UzhDfnEXujVhAw a/aQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875288; x=1760480088; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=4KNNgsguWMAVMteoKqbz2qkx1TQM7zG2UmyWb4nmWLc=; b=vGsK3iNIWY/EbtcaGePyk/6noQFYlaqM93ArEoK2lLBLL6763AfkwcxlA00ONLF8vf 4Gex2UuFWkW5AfHHSmriy5shHxRyvi5KSnZcoKR+Tt2QGtF1Lq0YPC+TnPKduYKJORKh 7KaG7ogpCgO1fO00Uzeld0x2+EJwc40pMkM+KEhKqR6G0a56/m6nwa2Zl9ZhUHP7INFa EuZg1Pj+YfRumwIR64dMZWSK8Lqchg00TRdGLA0e33+7himszvNuRPF4a1AXAjfhPWZK Nf88tjRRY1xRdPattuvnEpx7neiofgdL6bi2Al3t5B9yaVrC7FG2gxFY+tcjUERUvTMv IJXA== X-Forwarded-Encrypted: i=1; AJvYcCVfL6+Xp41G0/mkhng0vO6nA4/swxvnc93TDOL6Pyc0WgxmSvIFftJgfrezjOp0dx5+y3Htlqe6XP5CiyM=@vger.kernel.org X-Gm-Message-State: AOJu0YwKb6o2jMlYMvWF0aBBqHKaBEFRB/9oCYMRehcTutHAwFpl+mdI IWkb5/P+mH5t5/ms5bBk7BBWMUtxykzdSoSaMG/jhvAU2oJiAuJAs5hMJLDCUcvDx9AFnhC0Ts4 1mQ+LZA== X-Google-Smtp-Source: AGHT+IGgExOMV0YIM7rmm9IiUJFl3PZd47hgnUxkpuhuP1B/XsRQRkmjfiWNgh6xxO8JVQv67XJShabxkfw= X-Received: from pjbot13.prod.google.com ([2002:a17:90b:3b4d:b0:33b:51fe:1a92]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:4a87:b0:335:2d4:8b3d with SMTP id 98e67ed59e1d1-33b5138625emr1311365a91.31.1759875288025; Tue, 07 Oct 2025 15:14:48 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:14 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-7-seanjc@google.com> Subject: [PATCH v12 06/12] KVM: selftests: Define wrappers for common syscalls to assert success From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add kvm_ wrappers for munmap(), close(), fallocate(), and ftruncate() to cut down on boilerplate code when a sycall is expected to succeed, and to make it easier for developers to remember to assert success. Implement and use a macro framework similar to the kernel's SYSCALL_DEFINE infrastructure to further cut down on boilerplate code, and to drastically reduce the probability of typos as the kernel's syscall definitions can be copy+paste almost verbatim. Provide macros to build the raw () wrappers as well, e.g. to replace hand-coded wrappers (NUMA) or pure open-coded calls. Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Tested-by: Ackerley Tng --- tools/testing/selftests/kvm/arm64/vgic_irq.c | 2 +- .../selftests/kvm/include/kvm_syscalls.h | 81 +++++++++++++++++++ .../testing/selftests/kvm/include/kvm_util.h | 29 +------ .../selftests/kvm/kvm_binary_stats_test.c | 4 +- tools/testing/selftests/kvm/lib/kvm_util.c | 31 ++----- .../kvm/x86/private_mem_conversions_test.c | 9 +-- 6 files changed, 96 insertions(+), 60 deletions(-) create mode 100644 tools/testing/selftests/kvm/include/kvm_syscalls.h diff --git a/tools/testing/selftests/kvm/arm64/vgic_irq.c b/tools/testing/s= elftests/kvm/arm64/vgic_irq.c index 6338f5bbdb70..8d7758f12280 100644 --- a/tools/testing/selftests/kvm/arm64/vgic_irq.c +++ b/tools/testing/selftests/kvm/arm64/vgic_irq.c @@ -636,7 +636,7 @@ static void kvm_routing_and_irqfd_check(struct kvm_vm *= vm, } =20 for (f =3D 0, i =3D intid; i < (uint64_t)intid + num; i++, f++) - close(fd[f]); + kvm_close(fd[f]); } =20 /* handles the valid case: intid=3D0xffffffff num=3D1 */ diff --git a/tools/testing/selftests/kvm/include/kvm_syscalls.h b/tools/tes= ting/selftests/kvm/include/kvm_syscalls.h new file mode 100644 index 000000000000..d4e613162bba --- /dev/null +++ b/tools/testing/selftests/kvm/include/kvm_syscalls.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTEST_KVM_SYSCALLS_H +#define SELFTEST_KVM_SYSCALLS_H + +#include + +#define MAP_ARGS0(m,...) +#define MAP_ARGS1(m,t,a,...) m(t,a) +#define MAP_ARGS2(m,t,a,...) m(t,a), MAP_ARGS1(m,__VA_ARGS__) +#define MAP_ARGS3(m,t,a,...) m(t,a), MAP_ARGS2(m,__VA_ARGS__) +#define MAP_ARGS4(m,t,a,...) m(t,a), MAP_ARGS3(m,__VA_ARGS__) +#define MAP_ARGS5(m,t,a,...) m(t,a), MAP_ARGS4(m,__VA_ARGS__) +#define MAP_ARGS6(m,t,a,...) m(t,a), MAP_ARGS5(m,__VA_ARGS__) +#define MAP_ARGS(n,...) MAP_ARGS##n(__VA_ARGS__) + +#define __DECLARE_ARGS(t, a) t a +#define __UNPACK_ARGS(t, a) a + +#define DECLARE_ARGS(nr_args, args...) MAP_ARGS(nr_args, __DECLARE_ARGS, a= rgs) +#define UNPACK_ARGS(nr_args, args...) MAP_ARGS(nr_args, __UNPACK_ARGS, arg= s) + +#define __KVM_SYSCALL_ERROR(_name, _ret) \ + "%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errn= o) + +/* Define a kvm_() API to assert success. */ +#define __KVM_SYSCALL_DEFINE(name, nr_args, args...) \ +static inline void kvm_##name(DECLARE_ARGS(nr_args, args)) \ +{ \ + int r; \ + \ + r =3D name(UNPACK_ARGS(nr_args, args)); \ + TEST_ASSERT(!r, __KVM_SYSCALL_ERROR(#name, r)); \ +} + +/* + * Macro to define syscall APIs, either because KVM selftests doesn't link= to + * the standard library, e.g. libnuma, or because there is no library that= yet + * provides the syscall. These + */ +#define KVM_SYSCALL_DEFINE(name, nr_args, args...) \ +static inline long name(DECLARE_ARGS(nr_args, args)) \ +{ \ + return syscall(__NR_##name, UNPACK_ARGS(nr_args, args)); \ +} \ +__KVM_SYSCALL_DEFINE(name, nr_args, args) + +/* + * Special case mmap(), as KVM selftest rarely/never specific an address, + * rarely specify an offset, and because the unique return code requires + * special handling anyways. + */ +static inline void *__kvm_mmap(size_t size, int prot, int flags, int fd, + off_t offset) +{ + void *mem; + + mem =3D mmap(NULL, size, prot, flags, fd, offset); + TEST_ASSERT(mem !=3D MAP_FAILED, __KVM_SYSCALL_ERROR("mmap()", + (int)(unsigned long)MAP_FAILED)); + return mem; +} + +static inline void *kvm_mmap(size_t size, int prot, int flags, int fd) +{ + return __kvm_mmap(size, prot, flags, fd, 0); +} + +static inline int kvm_dup(int fd) +{ + int new_fd =3D dup(fd); + + TEST_ASSERT(new_fd >=3D 0, __KVM_SYSCALL_ERROR("dup()", new_fd)); + return new_fd; +} + +__KVM_SYSCALL_DEFINE(munmap, 2, void *, mem, size_t, size); +__KVM_SYSCALL_DEFINE(close, 1, int, fd); +__KVM_SYSCALL_DEFINE(fallocate, 4, int, fd, int, mode, loff_t, offset, lof= f_t, len); +__KVM_SYSCALL_DEFINE(ftruncate, 2, unsigned int, fd, off_t, length); + +#endif /* SELFTEST_KVM_SYSCALLS_H */ diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing= /selftests/kvm/include/kvm_util.h index ee60dbf5208a..c610169933ef 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -23,6 +23,7 @@ =20 #include =20 +#include "kvm_syscalls.h" #include "kvm_util_arch.h" #include "kvm_util_types.h" #include "sparsebit.h" @@ -283,34 +284,6 @@ static inline bool kvm_has_cap(long cap) return kvm_check_cap(cap); } =20 -#define __KVM_SYSCALL_ERROR(_name, _ret) \ - "%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errn= o) - -static inline void *__kvm_mmap(size_t size, int prot, int flags, int fd, - off_t offset) -{ - void *mem; - - mem =3D mmap(NULL, size, prot, flags, fd, offset); - TEST_ASSERT(mem !=3D MAP_FAILED, __KVM_SYSCALL_ERROR("mmap()", - (int)(unsigned long)MAP_FAILED)); - - return mem; -} - -static inline void *kvm_mmap(size_t size, int prot, int flags, int fd) -{ - return __kvm_mmap(size, prot, flags, fd, 0); -} - -static inline void kvm_munmap(void *mem, size_t size) -{ - int ret; - - ret =3D munmap(mem, size); - TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); -} - /* * Use the "inner", double-underscore macro when reporting errors from wit= hin * other macros so that the name of ioctl() and not its literal numeric va= lue diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/te= sting/selftests/kvm/kvm_binary_stats_test.c index f02355c3c4c2..b7dbde9c0843 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -239,14 +239,14 @@ int main(int argc, char *argv[]) * single stats file works and doesn't cause explosions. */ vm_stats_fds =3D vm_get_stats_fd(vms[i]); - stats_test(dup(vm_stats_fds)); + stats_test(kvm_dup(vm_stats_fds)); =20 /* Verify userspace can instantiate multiple stats files. */ stats_test(vm_get_stats_fd(vms[i])); =20 for (j =3D 0; j < max_vcpu; ++j) { vcpu_stats_fds[j] =3D vcpu_get_stats_fd(vcpus[i * max_vcpu + j]); - stats_test(dup(vcpu_stats_fds[j])); + stats_test(kvm_dup(vcpu_stats_fds[j])); stats_test(vcpu_get_stats_fd(vcpus[i * max_vcpu + j])); } =20 diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 83a721be7ec5..8b60b767224b 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -704,8 +704,6 @@ userspace_mem_region_find(struct kvm_vm *vm, uint64_t s= tart, uint64_t end) =20 static void kvm_stats_release(struct kvm_binary_stats *stats) { - int ret; - if (stats->fd < 0) return; =20 @@ -714,8 +712,7 @@ static void kvm_stats_release(struct kvm_binary_stats *= stats) stats->desc =3D NULL; } =20 - ret =3D close(stats->fd); - TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("close()", ret)); + kvm_close(stats->fd); stats->fd =3D -1; } =20 @@ -738,8 +735,6 @@ __weak void vcpu_arch_free(struct kvm_vcpu *vcpu) */ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_vcpu *vcpu) { - int ret; - if (vcpu->dirty_gfns) { kvm_munmap(vcpu->dirty_gfns, vm->dirty_ring_size); vcpu->dirty_gfns =3D NULL; @@ -747,9 +742,7 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_vc= pu *vcpu) =20 kvm_munmap(vcpu->run, vcpu_mmap_sz()); =20 - ret =3D close(vcpu->fd); - TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("close()", ret)); - + kvm_close(vcpu->fd); kvm_stats_release(&vcpu->stats); =20 list_del(&vcpu->list); @@ -761,16 +754,12 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_= vcpu *vcpu) void kvm_vm_release(struct kvm_vm *vmp) { struct kvm_vcpu *vcpu, *tmp; - int ret; =20 list_for_each_entry_safe(vcpu, tmp, &vmp->vcpus, list) vm_vcpu_rm(vmp, vcpu); =20 - ret =3D close(vmp->fd); - TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("close()", ret)); - - ret =3D close(vmp->kvm_fd); - TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("close()", ret)); + kvm_close(vmp->fd); + kvm_close(vmp->kvm_fd); =20 /* Free cached stats metadata and close FD */ kvm_stats_release(&vmp->stats); @@ -828,7 +817,7 @@ void kvm_vm_free(struct kvm_vm *vmp) int kvm_memfd_alloc(size_t size, bool hugepages) { int memfd_flags =3D MFD_CLOEXEC; - int fd, r; + int fd; =20 if (hugepages) memfd_flags |=3D MFD_HUGETLB; @@ -836,11 +825,8 @@ int kvm_memfd_alloc(size_t size, bool hugepages) fd =3D memfd_create("kvm_selftest", memfd_flags); TEST_ASSERT(fd !=3D -1, __KVM_SYSCALL_ERROR("memfd_create()", fd)); =20 - r =3D ftruncate(fd, size); - TEST_ASSERT(!r, __KVM_SYSCALL_ERROR("ftruncate()", r)); - - r =3D fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, size); - TEST_ASSERT(!r, __KVM_SYSCALL_ERROR("fallocate()", r)); + kvm_ftruncate(fd, size); + kvm_fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, size); =20 return fd; } @@ -1084,8 +1070,7 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backin= g_src_type src_type, * needing to track if the fd is owned by the framework * or by the caller. */ - guest_memfd =3D dup(guest_memfd); - TEST_ASSERT(guest_memfd >=3D 0, __KVM_SYSCALL_ERROR("dup()", guest_memf= d)); + guest_memfd =3D kvm_dup(guest_memfd); } =20 region->region.guest_memfd =3D guest_memfd; diff --git a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c= b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c index 82a8d88b5338..1969f4ab9b28 100644 --- a/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c +++ b/tools/testing/selftests/kvm/x86/private_mem_conversions_test.c @@ -380,7 +380,7 @@ static void test_mem_conversions(enum vm_mem_backing_sr= c_type src_type, uint32_t struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; pthread_t threads[KVM_MAX_VCPUS]; struct kvm_vm *vm; - int memfd, i, r; + int memfd, i; =20 const struct vm_shape shape =3D { .mode =3D VM_MODE_DEFAULT, @@ -428,11 +428,8 @@ static void test_mem_conversions(enum vm_mem_backing_s= rc_type src_type, uint32_t * should prevent the VM from being fully destroyed until the last * reference to the guest_memfd is also put. */ - r =3D fallocate(memfd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, 0, mem= fd_size); - TEST_ASSERT(!r, __KVM_SYSCALL_ERROR("fallocate()", r)); - - r =3D fallocate(memfd, FALLOC_FL_KEEP_SIZE, 0, memfd_size); - TEST_ASSERT(!r, __KVM_SYSCALL_ERROR("fallocate()", r)); + kvm_fallocate(memfd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, 0, memfd= _size); + kvm_fallocate(memfd, FALLOC_FL_KEEP_SIZE, 0, memfd_size); =20 close(memfd); } --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 579E326B2AD for ; Tue, 7 Oct 2025 22:14:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875291; cv=none; b=gdkYu/bPaM/v0fsdyQdjTTrvePaISVza72ALes+xZRztazOeVHmqXqo0Iqw+q45JHAY7xJtW4B8Jo7FUU1EYWoBCoRZmhelpAkO5RCkVXj+DfFzsZGrHibnOpT+s4NlwaOuIeXGr2tX+LKc0hqXDLwKvgfOnWeyuvEEhqFQQ0FE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875291; c=relaxed/simple; bh=DQgULNgEfY1Jt0H2/OfuNvBsjc9CKm5CpMZ3jXWuIWw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hXnasWvE/kAzYbMJKlOUS/e2w6y7rtALwPJIkl0qSmA1UAgOD/FRAFBzlVJ22UEGtm9x3I/q1PKcQr3jRInEVsau/BohD8Wfq3x5y8AR+ImjT/9zsC1LeG6r3qqa+JX48rtayMNKxdTHMRhbncAluoi5c5dHOG3pyTrxVybAtRs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=hfXdHTBv; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="hfXdHTBv" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-792722e4ebeso1501356b3a.3 for ; Tue, 07 Oct 2025 15:14:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875290; x=1760480090; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=ZRjLOkLi9BSY1X/Dn5kuYV5Nji5pDR3uoMZxLkUFt2o=; b=hfXdHTBv15rANbphNVIFd1wb+x+WpzC/F+r+BCt9D9MdWv1N3c1n7RO/njPl1bq64P w0l+cWXfUg1RCpwt1EEzrfU1OHPuXjZFztPnSytFuAjWEQTfC648fwPrWWa/sWIWgrN0 FcY0GLBqV6nx+pKlyZA0lmMAjuCUwJhjv2FOPWaIhnuaIMV+SOx9pFQ2IjIUdC2K2nvn rVW7yUPZPOVJx74TZ9C0RoR+1CTLK6d1b4pgTKopTBm0C+kteDsURXDvExAHEG91bbzk dA1YHeB1FT83zZJdrd7b26Jv1N/nNcURkAXOFhJ2tYbPKiVCxBkPITKG/ksNmRgnxIwn 7CRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875290; x=1760480090; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ZRjLOkLi9BSY1X/Dn5kuYV5Nji5pDR3uoMZxLkUFt2o=; b=WiXPxeN6YcoM7b/+LjP+pDS+0/nYkTnSXUh756yuKwjVZCHwrAnuZYyPyI9f3CfsQO VxnlXs9NmDnHsB3mTDzLEpSQ/In6xPVj+zT/mu+hk4w9KeITNpazkKfMAFF77fIjU4RX /+gSM/HFuflGGVAXBmG1zKV2wxkILI/cg9kRtPzClPsee9JBHavvPPmoxdML6xu3HO+/ JnxEiKJOEOa8CIiIpn+83gxmbkDtA55BXqrP8GGGpNjtYr7XQOWGqw8Ijbmxm2zliA11 oEEFf5VsBqkrnWVfdpo6nRPZvMHn+4AMtiJNNv8tcpbuFtpzXZpXLiXLnGhe0vm8Rij5 kgUw== X-Forwarded-Encrypted: i=1; AJvYcCUBhCgTE764n2WLTk7K6dRzY9/xuzEsy1LzOngP9g2kLozVLb8EWinJmfmw7BTK4qHfcXyfSksNeeGMYV4=@vger.kernel.org X-Gm-Message-State: AOJu0Yzt/VwVL9q+xqmYoQv9jrJdLRBgFfaegbmJSo+vjL8DiFpeZTDt 5/fxpnwKch4pUsFSvA5vvq0NOeX7P6Z/iTf+hBb4HzKHhP3wsxKEVhfOEntn+3tgChZHMn19OxI /3ELyMA== X-Google-Smtp-Source: AGHT+IEms4qpmxT3+KnDpQ4qOyqPi3vhEOg4w0WfOhks0tfRQIlFpS+IHju/WYm3RYsFn35p+Bdpiaz8XEQ= X-Received: from pfbig5.prod.google.com ([2002:a05:6a00:8b85:b0:77f:33ea:96e9]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:3cce:b0:77e:5c9f:f85a with SMTP id d2e1a72fcca58-79385ce1122mr1342534b3a.14.1759875289698; Tue, 07 Oct 2025 15:14:49 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:15 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-8-seanjc@google.com> Subject: [PATCH v12 07/12] KVM: selftests: Report stacktraces SIGBUS, SIGSEGV, SIGILL, and SIGFPE by default From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Register handlers for signals for all selftests that are likely happen due to test (or kernel) bugs, and explicitly fail tests on unexpected signals so that users get a stack trace, i.e. don't have to go spelunking to do basic triage. Register the handlers as early as possible, to catch as many unexpected signals as possible, and also so that the common code doesn't clobber a handler that's installed by test (or arch) code. Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Tested-by: Ackerley Tng --- tools/testing/selftests/kvm/lib/kvm_util.c | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/sel= ftests/kvm/lib/kvm_util.c index 8b60b767224b..0c3a6a40d1a9 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2290,11 +2290,35 @@ __weak void kvm_selftest_arch_init(void) { } =20 +static void report_unexpected_signal(int signum) +{ +#define KVM_CASE_SIGNUM(sig) \ + case sig: TEST_FAIL("Unexpected " #sig " (%d)\n", signum) + + switch (signum) { + KVM_CASE_SIGNUM(SIGBUS); + KVM_CASE_SIGNUM(SIGSEGV); + KVM_CASE_SIGNUM(SIGILL); + KVM_CASE_SIGNUM(SIGFPE); + default: + TEST_FAIL("Unexpected signal %d\n", signum); + } +} + void __attribute((constructor)) kvm_selftest_init(void) { + struct sigaction sig_sa =3D { + .sa_handler =3D report_unexpected_signal, + }; + /* Tell stdout not to buffer its content. */ setbuf(stdout, NULL); =20 + sigaction(SIGBUS, &sig_sa, NULL); + sigaction(SIGSEGV, &sig_sa, NULL); + sigaction(SIGILL, &sig_sa, NULL); + sigaction(SIGFPE, &sig_sa, NULL); + guest_random_seed =3D last_guest_seed =3D random(); pr_info("Random seed: 0x%x\n", guest_random_seed); =20 --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10B2C26D4EA for ; Tue, 7 Oct 2025 22:14:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875293; cv=none; b=uSiSseuFCP6h+gFBDAWUxsI2BtLpxKFLW4WfztGBeo+FAIDPbSVNw7sz84ow3OIoFA8GPca3+6qVALj4cKWJT05L7WB7qKTvNydzp+0gAn5/f2IJ/F1Nq7UB/kHBd+h71+adfbUUQf8wJsu4g/v0SpwPpqESeBrT14Qcy8FCYUY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875293; c=relaxed/simple; bh=5cUK2vsz2aeKXQeo1630DELsLZCEu5/ef8gHUAuGDsQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=VBkmRqXJ8ukPdyL58Ln7nQ/s90gJ+MF/6IpLegA7vlTboQU2v6v3YiL8Wlb2boUSvAXMJpGA2wY3r6ccIVeyamjMClR1v8AOyEweBkOfMpB8avvolos9mwMHJtigBbYRZotQjn6/iMOQguoheKJ9hlGNh0agBNDPZEFu8Mp/mI0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dfcjkn+F; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dfcjkn+F" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-7810af03a63so11561613b3a.3 for ; Tue, 07 Oct 2025 15:14:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875291; x=1760480091; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=rE2tP6gNwSGYC+ytU0WdagFGaT6zZ0FH31dgxqOixoc=; b=dfcjkn+F7j6cCOfVolJ5HJ7VuCv3sVn70G4xOjfEE1+rkNQxt0D7v9CoQftuhFiG3j cN6QsPA0HlNc4Uz74tcP+qomSGRfAF+F5HrTNfcTn9V57CgBqG3E2NuEHUrDUctYNAG2 /ZPFDg5BYR3mBDh9C6nwBDn8hSsRrZdSjLSvh3cncdulbmE/zAKBKDaYVoPAfm/w/ucD 5Kh3LsZ/LhJQAERUd1NUDY3Zf/UPgKYou+7xOBjrZ/uwAkIXfa5r8gybpupa+0ix21DE vPSjT2AcSn5GQpbColTUyVhkdvb0gzY+FozzOHutpOjb1Qipas4XxILBf8Xd6oCaEelW 3qDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875291; x=1760480091; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=rE2tP6gNwSGYC+ytU0WdagFGaT6zZ0FH31dgxqOixoc=; b=wfz50V8Ur/PyWmysZtJPRwBW17FfaxindzeaBH6TNr5NTczecQFlgRPtoAMCjqVhbn 6McDlIntLHMTSmZKDJerb7I+HIqfM0T50YdZ7yQYPCu1K2gef98lw7oRZFlN49pxGYIh o3nZyxMQGYgV8Ef8AtheVz3yTGcCT53p8Q3CDGF87S0wIr7f2u25Qkvd6sCYecINDxMi cwfhXhy8EZuxRdb1qKesGDID/y+8lHURtifMXPtWlM3bUvl/hCRTProslpR4Y2UbIv9G JiiO6AKfmTK2V85OHt3a66xiQgLyc0FIteFHkWNC1hLKWYiTvu/hKJ694w0iSRwWUlwz paqw== X-Forwarded-Encrypted: i=1; AJvYcCXG4TVnR8f2ObbEWLGFqP4l6lYOv5T7X5IHFoOgQH0hEPoSwH1mkAuKLNgR+HCGrqJviYLTwHn8GAwZ1i0=@vger.kernel.org X-Gm-Message-State: AOJu0Yxmh9kqhr3Hn51bD+JzePSKjkidUYtdsEa7SU7nl15TS+flZKxP A8g7OxU7iIrK9dQn1bdUihFrDI5vk81C+DJ5EAViNQ+Uv5nT3OUoPGKZxhV1dBT0T8xIZNtM8on L7LO46A== X-Google-Smtp-Source: AGHT+IHT/CfaeIxGRmxefyc3Lic0lFv3xjNb/u7y6hJFRFl3s3gaiIHFCNdvEBNOqVG5LYVtjeYwLccHX/o= X-Received: from pgkh14.prod.google.com ([2002:a63:e14e:0:b0:b4e:4eb5:3895]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:914c:b0:32b:7220:8536 with SMTP id adf61e73a8af0-32da8138b18mr1530904637.16.1759875291520; Tue, 07 Oct 2025 15:14:51 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:16 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-9-seanjc@google.com> Subject: [PATCH v12 08/12] KVM: selftests: Add additional equivalents to libnuma APIs in KVM's numaif.h From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add APIs for all syscalls defined in the kernel's mm/mempolicy.c to match those that would be provided by linking to libnuma. Opportunistically use the recently inroduced KVM_SYSCALL_DEFINE() builders to take care of the boilderplate, and to fix a flaw where the two existing wrappers would generate multiple symbols if numaif.h were to be included multiple times. Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Tested-by: Ackerley Tng --- tools/testing/selftests/kvm/include/numaif.h | 36 +++++++++++-------- .../selftests/kvm/x86/xapic_ipi_test.c | 5 ++- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/kvm/include/numaif.h b/tools/testing/s= elftests/kvm/include/numaif.h index b020547403fd..aaa4ac174890 100644 --- a/tools/testing/selftests/kvm/include/numaif.h +++ b/tools/testing/selftests/kvm/include/numaif.h @@ -13,23 +13,29 @@ #ifndef SELFTEST_KVM_NUMAIF_H #define SELFTEST_KVM_NUMAIF_H =20 -#define __NR_get_mempolicy 239 -#define __NR_migrate_pages 256 +#include =20 -/* System calls */ -long get_mempolicy(int *policy, const unsigned long *nmask, - unsigned long maxnode, void *addr, int flags) -{ - return syscall(__NR_get_mempolicy, policy, nmask, - maxnode, addr, flags); -} +#include "kvm_syscalls.h" =20 -long migrate_pages(int pid, unsigned long maxnode, - const unsigned long *frommask, - const unsigned long *tomask) -{ - return syscall(__NR_migrate_pages, pid, maxnode, frommask, tomask); -} +KVM_SYSCALL_DEFINE(get_mempolicy, 5, int *, policy, const unsigned long *,= nmask, + unsigned long, maxnode, void *, addr, int, flags); + +KVM_SYSCALL_DEFINE(set_mempolicy, 3, int, mode, const unsigned long *, nma= sk, + unsigned long, maxnode); + +KVM_SYSCALL_DEFINE(set_mempolicy_home_node, 4, unsigned long, start, + unsigned long, len, unsigned long, home_node, + unsigned long, flags); + +KVM_SYSCALL_DEFINE(migrate_pages, 4, int, pid, unsigned long, maxnode, + const unsigned long *, frommask, const unsigned long *, tomask); + +KVM_SYSCALL_DEFINE(move_pages, 6, int, pid, unsigned long, count, void *, = pages, + const int *, nodes, int *, status, int, flags); + +KVM_SYSCALL_DEFINE(mbind, 6, void *, addr, unsigned long, size, int, mode, + const unsigned long *, nodemask, unsigned long, maxnode, + unsigned int, flags); =20 /* Policies */ #define MPOL_DEFAULT 0 diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testi= ng/selftests/kvm/x86/xapic_ipi_test.c index 35cb9de54a82..ae4a4b6c05ca 100644 --- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c +++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c @@ -256,7 +256,7 @@ void do_migrations(struct test_data_page *data, int run= _secs, int delay_usecs, int nodes =3D 0; time_t start_time, last_update, now; time_t interval_secs =3D 1; - int i, r; + int i; int from, to; unsigned long bit; uint64_t hlt_count; @@ -267,9 +267,8 @@ void do_migrations(struct test_data_page *data, int run= _secs, int delay_usecs, delay_usecs); =20 /* Get set of first 64 numa nodes available */ - r =3D get_mempolicy(NULL, &nodemask, sizeof(nodemask) * 8, + kvm_get_mempolicy(NULL, &nodemask, sizeof(nodemask) * 8, 0, MPOL_F_MEMS_ALLOWED); - TEST_ASSERT(r =3D=3D 0, "get_mempolicy failed errno=3D%d", errno); =20 fprintf(stderr, "Numa nodes found amongst first %lu possible nodes " "(each 1-bit indicates node is present): %#lx\n", --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C5D98270540 for ; Tue, 7 Oct 2025 22:14:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875295; cv=none; b=WLfeth7Z6aHihli74HqfVo3/REpXQtJt3gM2Cg7yu1VpCtptkZ87J/jvSpHYUqLT2P8Fo9RmtWIKZ9wOi5wbsQDpffVV+TyFxBkMwOR/1+yaFwp+kI7E/YlLNsyt0kPaZKjbOBruOBTHfKx5WFSwaLBpaYJhDW3MJDw9+wTxJgc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875295; c=relaxed/simple; bh=iKrUI9LQBOh4k9pZFLc/fEW3XuLEnIsg8figDKSsXGA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RULYVdSnwY7iMMQc1hT7fEKu9LKXBT5JIiIu3pWZWsMWl910ylP5et4O+6sp2WFkKaaTuZPozZPLAtChJ8wfNQ9zhH6xydqsMGKRWsj6KBQsEgvW13P9p1kCQl1nj40cUhb3q64qkAJBKTQ13VFS+HwYzXAezwVANqmzdydAGFs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=vcMV4QfK; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="vcMV4QfK" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-32ee62ed6beso11279047a91.2 for ; Tue, 07 Oct 2025 15:14:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875293; x=1760480093; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=efPtgGQoMr4oubNxAv1qKprX0Kma5wbATW1PH+6tg30=; b=vcMV4QfKo2kxGdvra5XBptOVM9oPG/9lY8hsuCunTcIXK4MUZAu5JEFSZs9gszv2lQ Eo/x0Z9n6CLvh2ncOutm63mC7BK3QndH2EpEPGpQTuzMFoNn9/WhYG4K/0DV9H/7Vrku bvtwUzG13cKkiF5Tvcm+qg6fJu3w3tSfxFirnb1l+GRjRWlzfb5EAkul2nZWXoRs9F8Q SCgOKu1nZEc3Qc9FN13xyeeV+6l5bvrjOzaBuz/swpRfUTYWaipxBpd9E2AxgQJ6uxe7 FaQOyYq3Ip0PFVChFzHtr1YnE28covXBwzWiAE83v4f/G313dZ3KF/IxfpPjyCtisPQX CI6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875293; x=1760480093; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=efPtgGQoMr4oubNxAv1qKprX0Kma5wbATW1PH+6tg30=; b=Xw9CTBRvp76VIrH2i8X6aX7YcvgC90GYETUpElHXXJHlWqUO50gpsnzXO2yT1nU9E2 NZX/iAzikqqrBsmaH/9U9pE6vCSaderZS059OTGpc8jhg3cGYzDMtVWaKniBnftmi7Ob yl8jOuoMHkGROR0BoAxpiCzHmFvAZQ6t+6cH3P4zsQbBSly262aXqoPdsVreAidfYNgj x7Q/eLBQZOXUmtF0mTZ4ivsKZU8UCznNRoeUan3rRWFK3akhMckidIioNQibyElkMIyQ eg+VOQqTgwW+hhyt6RwwErLpd1ZDRPp/SHbnnYhrj9hxQGvRtUK1VRHv5YzJZOGhPl8T CRjA== X-Forwarded-Encrypted: i=1; AJvYcCUnDQgKCduEU2+hGNMvfUo3L7cc07Zi8B8WyWsI0QMMfl1s/PEW0/JI2CGUgIW9UNA8d2KJoWBws0CMt3M=@vger.kernel.org X-Gm-Message-State: AOJu0YyUlfXgt5vinlXKo6Q83oNvYX4On7KMve+r2oOQyYfgM+07o6OS 6ps0pLTyBW7u5BEw0mcSC8kGByWY4ljJvVNgJHGKxVP+TSIrqCKTKvp16EYZx1FEQuZGjR4vDuX OHzYBPg== X-Google-Smtp-Source: AGHT+IFTaBPktlqVR37VqVA9cZzZZ/8OTio3uAd9mQ94N7kdyxx902DDy6/7iqhCbZbcOwfgNKOb2jtvL6Q= X-Received: from pjbsn6.prod.google.com ([2002:a17:90b:2e86:b0:32b:61c4:e48b]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1806:b0:32d:db5b:7636 with SMTP id 98e67ed59e1d1-33b513cdaf5mr1179313a91.27.1759875293062; Tue, 07 Oct 2025 15:14:53 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:17 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-10-seanjc@google.com> Subject: [PATCH v12 09/12] KVM: selftests: Use proper uAPI headers to pick up mempolicy.h definitions From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Include mempolicy.h in KVM's numaif.h to pick up the kernel-provided NUMA definitions, and drop selftests' definitions, which are _mostly_ equivalent. The syscall numbers in particular are subtly x86_64-specific, i.e. will cause problems if/when numaif.h is used outsize of x86. Opportunistically clean up the file comment and make the syscall wrappers static inline so that including the header multiple times won't lead to weirdness (currently numaif.h is included by exactly one header). Fixes: 346b59f220a2 ("KVM: selftests: Add missing header file needed by xAP= IC IPI tests") Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/include/numaif.h | 32 +------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/tools/testing/selftests/kvm/include/numaif.h b/tools/testing/s= elftests/kvm/include/numaif.h index aaa4ac174890..1554003c40a1 100644 --- a/tools/testing/selftests/kvm/include/numaif.h +++ b/tools/testing/selftests/kvm/include/numaif.h @@ -1,14 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tools/testing/selftests/kvm/include/numaif.h - * - * Copyright (C) 2020, Google LLC. - * - * This work is licensed under the terms of the GNU GPL, version 2. - * - * Header file that provides access to NUMA API functions not explicitly - * exported to user space. - */ +/* Copyright (C) 2020, Google LLC. */ =20 #ifndef SELFTEST_KVM_NUMAIF_H #define SELFTEST_KVM_NUMAIF_H @@ -37,25 +28,4 @@ KVM_SYSCALL_DEFINE(mbind, 6, void *, addr, unsigned long= , size, int, mode, const unsigned long *, nodemask, unsigned long, maxnode, unsigned int, flags); =20 -/* Policies */ -#define MPOL_DEFAULT 0 -#define MPOL_PREFERRED 1 -#define MPOL_BIND 2 -#define MPOL_INTERLEAVE 3 - -#define MPOL_MAX MPOL_INTERLEAVE - -/* Flags for get_mem_policy */ -#define MPOL_F_NODE (1<<0) /* return next il node or node of address = */ - /* Warning: MPOL_F_NODE is unsupported and - * subject to change. Don't use. - */ -#define MPOL_F_ADDR (1<<1) /* look up vma using address */ -#define MPOL_F_MEMS_ALLOWED (1<<2) /* query nodes allowed in cpuset */ - -/* Flags for mbind */ -#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping= */ -#define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to co= nform to mapping */ -#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mappi= ng */ - #endif /* SELFTEST_KVM_NUMAIF_H */ --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54DB927381B for ; Tue, 7 Oct 2025 22:14:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875297; cv=none; b=MC7nTrO3VtLwBUL+I+MWKTKIgLCnaEa/ThsKvnrqVd/9y1JGg46sQuLJA8JQdWSprNV1fc9F4bJD6LE4GaYVHEd4HgIZ/TXmed71qxHRr4tQKf6s59dTsJiLXWcDB1uokBNrBsR/7G4LyQc4NOAWeMokwbwShfgFqG/RIl2iVuY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875297; c=relaxed/simple; bh=pEAhEjGmE/6E3+3IorVbdBNzf37J42NibPq0N4C1YsA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=byXTqv61JojCuLRfowGC1Sp7gxTVjosTFMIo4vJKIYnqY5TYe2ukoPYFQF7dezSh8avSPIQv1hSB7iBtbNjEjdwBIoSAdSFAdH+CgRxKDlAtwZxU4eUQZipqbrpLvf+tygZ+I11G2jDd4uqc2pF/rNSdQg3eTlZnFhSjm4l/8J8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AZ7RNk4l; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AZ7RNk4l" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-27eeb9730d9so67946005ad.0 for ; Tue, 07 Oct 2025 15:14:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875295; x=1760480095; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=zTQs0EnNDco2mpUUW8A1kWTJ2V3fPeD2Oux5tvQu97s=; b=AZ7RNk4lRemOUJ1AQ+l0/R311etQWhq16/9XadfgFbK/bpEjz5Jd3Wgu32razvWC+H S2QDEa9N6GSPZ6qyyGXpnuGeOzxBNsihz/y+Eii5BoY4xWnGC7JY7O7Y8Ybo+wpzcHo+ lmEgA9mzTkelrKaVzaEf1ixU7Rbi3HMZOU3jnWKWMUUxiT57TewXx1RjB3l6Rpt01F1m oqWBqWZ/NkNRm4WpZStxWa4xQjoSSh8CP7hejF3OwxKiU+/TOifRRtw05YkaBg2Ooof3 T9rkAskaTRHYd+Xm3/b/H3ev2r/vHkOk9lNO+j9R0PA6WOGm1kzBa0K/Ri+P8tMr+T4m LHoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875295; x=1760480095; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=zTQs0EnNDco2mpUUW8A1kWTJ2V3fPeD2Oux5tvQu97s=; b=Gr9pVYfbebxw//lx+nqVOPHDqo6QoObQliS6P8QC8b7Vdf+/NjY8ECV2Xr+/d0duZX eTfs2id/Jb9UsgUzpnNCGt6p2m8A4sMqM+qpONXPLm3LkrSrQ7dd8gw5Q7Z6WvDAQxrC fQpo+k89n9cgnS2agk/0Kc7Uu+zuUOfh1Jq65C1knwZ3QFgzY9Id7xwKBLziNQXWNZAk i6BOwpQkmo3/tNgAQMSkZKOMl9YYFFafYHHNfWAIbuOibDHQgiM/g27IZ87Qge0O6GQ7 10gJEF6WFMFNRIbJM2a7yuZvsg0puTr/Gg20EeutzeXIde1lguYtLSOhADdHB9IpNKUu BdMg== X-Forwarded-Encrypted: i=1; AJvYcCUArQso2I9UhzYhF9alZg5Z7/yoljX3xmQD4S7EWbdBhGj0XWkIOK2oX3ZE8D/mECqshUAJZdHCSpJrPog=@vger.kernel.org X-Gm-Message-State: AOJu0YyPPiZ63eWuBD7s+KOS+vdrKpSsnl1r6b4gcXF1D6HdK/tqvrQc qE+XKxiEPWB7uRdOJapZr/+LeAT0TSv86cfELbhJhaRWBV9bupXCYQGjlovh0RqIzHHTG4s0Cq3 aEMHsUQ== X-Google-Smtp-Source: AGHT+IE4iOU9kwHgBlllnocBeU6IrHkDCIzq84NfugFiFee0pXpv+6bFVeJqE6gHwaZr6A6SdSFRTrYPG7c= X-Received: from plhx16.prod.google.com ([2002:a17:903:2c10:b0:269:8ca7:6998]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:e943:b0:269:ba8b:8476 with SMTP id d9443c01a7336-2902741f0c1mr13607885ad.56.1759875294643; Tue, 07 Oct 2025 15:14:54 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:18 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-11-seanjc@google.com> Subject: [PATCH v12 10/12] KVM: selftests: Add helpers to probe for NUMA support, and multi-node systems From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Shivank Garg Add NUMA helpers to probe for support/availability and to check if the test is running on a multi-node system. The APIs will be used to verify guest_memfd NUMA support. Signed-off-by: Shivank Garg [sean: land helpers in numaif.h, add comments, tweak names] Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/include/numaif.h | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tools/testing/selftests/kvm/include/numaif.h b/tools/testing/s= elftests/kvm/include/numaif.h index 1554003c40a1..29572a6d789c 100644 --- a/tools/testing/selftests/kvm/include/numaif.h +++ b/tools/testing/selftests/kvm/include/numaif.h @@ -4,6 +4,8 @@ #ifndef SELFTEST_KVM_NUMAIF_H #define SELFTEST_KVM_NUMAIF_H =20 +#include + #include =20 #include "kvm_syscalls.h" @@ -28,4 +30,54 @@ KVM_SYSCALL_DEFINE(mbind, 6, void *, addr, unsigned long= , size, int, mode, const unsigned long *, nodemask, unsigned long, maxnode, unsigned int, flags); =20 +static inline int get_max_numa_node(void) +{ + struct dirent *de; + int max_node =3D 0; + DIR *d; + + /* + * Assume there's a single node if the kernel doesn't support NUMA, + * or if no nodes are found. + */ + d =3D opendir("/sys/devices/system/node"); + if (!d) + return 0; + + while ((de =3D readdir(d)) !=3D NULL) { + int node_id; + char *endptr; + + if (strncmp(de->d_name, "node", 4) !=3D 0) + continue; + + node_id =3D strtol(de->d_name + 4, &endptr, 10); + if (*endptr !=3D '\0') + continue; + + if (node_id > max_node) + max_node =3D node_id; + } + closedir(d); + + return max_node; +} + +static bool is_numa_available(void) +{ + /* + * Probe for NUMA by doing a dummy get_mempolicy(). If the syscall + * fails with ENOSYS, then the kernel was built without NUMA support. + * if the syscall fails with EPERM, then the process/user lacks the + * necessary capabilities (CAP_SYS_NICE). + */ + return !get_mempolicy(NULL, NULL, 0, NULL, 0) || + (errno !=3D ENOSYS && errno !=3D EPERM); +} + +static inline bool is_multi_numa_node_system(void) +{ + return is_numa_available() && get_max_numa_node() >=3D 1; +} + #endif /* SELFTEST_KVM_NUMAIF_H */ --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 375852701B1 for ; Tue, 7 Oct 2025 22:14:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875299; cv=none; b=g9DsIBop7AsdpVx9V5bByZF4oc71VD1Zqpdb9rdTt/ym9xiSD+ZrSmNPSfE7vyv9Lqs8DvA5gi9c3upSC6cbhVXlD51A/1HF1XDa+j4KwjjIB6uTTJ16EiI+DZvo+4rkTTY/3iUCr48dc+txCj+hqvqC1td6zMYtheDrjQ7Jwq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875299; c=relaxed/simple; bh=CDrOrMNO9l5cLoWd98CveZ7KTkfm+YOe4TpGJ/Wt4fA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=taofAPGM4A4hoyolH/CjDHg3t9x2RU9FUKvimNtQTVjzY3uJIA0n+wXoKn3vIgPN49jt/33C0GWyMqn4eNgUlEqrnGsFZi7jLHeY5U7w0mAtASBkxCDuwK99IfIfjbh5Bg3t5yQoVPT6PCH0/xWiiGbqyMwDZoOLyztaBCnmcys= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=FLWPwpq8; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="FLWPwpq8" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-3304def7909so6405222a91.3 for ; Tue, 07 Oct 2025 15:14:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875296; x=1760480096; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=pq3jKNyKi/1WXgeEr4Kt/LxPicRmmT3+M3Z6Wud5iC8=; b=FLWPwpq8qHzErasoo0s+GiCDnuNienIoDh3KHs2K9VzAVAtpG8pMjwLOlOO4PbKkA+ HZbw51XqkuHfXX7Jr6XQsgtq6a3Klbx+IKrhcepWh/MengsZhfuqLhcklu1SnSW7+XzF Bk2X/EtNrU0cAAccKOgXNxF1T64b/LZq8+L89c6lxTsUc5VtR5bWXl4CqM+DdWOm0JzV FYaSOq/Bo8hQ8ghkMbaJc68C4urD6ZH/lE1aDj6FkLwhVLbzKMmhEilHKglQyaaX53k9 hqjvrMKyI1UFXFqQjB7stZINuWSlXVzkkrf82pfbhxpHZ3tQxoJDTzNYZf5+bp1kVXOT zJiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875296; x=1760480096; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=pq3jKNyKi/1WXgeEr4Kt/LxPicRmmT3+M3Z6Wud5iC8=; b=BL2Fch+U9Ys2dJR/GLC67k2tOMDqJCdDIth3jAYaGvmmo+hMJUUgojuVZfUsrtUBLq CTQlfPNjY7k6mGD5tTE5w5n16RJKw1+atw0WVZRuLphvhj8oG4oAfvXkKdevtbC01P+o U6gJFTSEP7RxjbnE6iv+/PqIEWhAjP21LfzHOTAfhgccZO3sHS1Zu92fC/FoVWj9J5OI gPC+PqinjzP3wlfWgkaP0pzefxO37wB7pgFEpF3QtOmgwXPdsHmi4nqQruj/YnH+ubXf Adjm+2y8CQIJp1lsRuNHhs328gRNfsnpitfm7hc9YrP7j6b+cHtSRJApON8ATWzNJllr ybMQ== X-Forwarded-Encrypted: i=1; AJvYcCX2h9LFhhI0fxFWq37f1IprQnAJIuP2Z1QgJCTGvpXGo7dw5Nwv69u5J4N+6JZ9+X48FAtuH0B3ihXx3J4=@vger.kernel.org X-Gm-Message-State: AOJu0YxJ9pI77SPSd4gb5Zu9j4P58SIna70puDeVoEUbDg//dt9tSrzW 6SaALQOh4VEc3GE+Afg+SFWn5ZiXBryE+NUZwv8cJCIVbHwZPPj4uE11Ia1qiyIFGHAM1Xs+sVo qyp/5UQ== X-Google-Smtp-Source: AGHT+IFr1z+OHs2pqkHxNhtbO8xQGrGNQletDRxpDZROHoK8rGfdZgYkQaGuDGapxPz1ninSCtdpRZhLQBs= X-Received: from pjbmw12.prod.google.com ([2002:a17:90b:4d0c:b0:329:b272:45a7]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:1b4c:b0:327:9e88:7714 with SMTP id 98e67ed59e1d1-33b513ebf89mr1315059a91.37.1759875296568; Tue, 07 Oct 2025 15:14:56 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:19 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-12-seanjc@google.com> Subject: [PATCH v12 11/12] KVM: selftests: Add guest_memfd tests for mmap and NUMA policy support From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Shivank Garg Add tests for NUMA memory policy binding and NUMA aware allocation in guest_memfd. This extends the existing selftests by adding proper validation for: - KVM GMEM set_policy and get_policy() vm_ops functionality using mbind() and get_mempolicy() - NUMA policy application before and after memory allocation Run the NUMA mbind() test with and without INIT_SHARED, as KVM should allow doing mbind(), madvise(), etc. on guest-private memory, e.g. so that userspace can set NUMA policy for CoCo VMs. Run the NUMA allocation test only for INIT_SHARED, i.e. if the host can't fault-in memory (via direct access, madvise(), etc.) as move_pages() returns -ENOENT if the page hasn't been faulted in (walks the host page tables to find the associated folio) Signed-off-by: Shivank Garg Tested-by: Ashish Kalra [sean: don't skip entire test when running on non-NUMA system, test mbind() with private memory, provide more info in assert messages] Signed-off-by: Sean Christopherson --- .../testing/selftests/kvm/guest_memfd_test.c | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing= /selftests/kvm/guest_memfd_test.c index e7d9aeb418d3..618c937f3c90 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -19,6 +19,7 @@ #include =20 #include "kvm_util.h" +#include "numaif.h" #include "test_util.h" #include "ucall_common.h" =20 @@ -75,6 +76,101 @@ static void test_mmap_supported(int fd, size_t total_si= ze) kvm_munmap(mem, total_size); } =20 +static void test_mbind(int fd, size_t total_size) +{ + const unsigned long nodemask_0 =3D 1; /* nid: 0 */ + unsigned long nodemask =3D 0; + unsigned long maxnode =3D 8; + int policy; + char *mem; + int ret; + + if (!is_multi_numa_node_system()) + return; + + mem =3D kvm_mmap(total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd); + + /* Test MPOL_INTERLEAVE policy */ + kvm_mbind(mem, page_size * 2, MPOL_INTERLEAVE, &nodemask_0, maxnode, 0); + kvm_get_mempolicy(&policy, &nodemask, maxnode, mem, MPOL_F_ADDR); + TEST_ASSERT(policy =3D=3D MPOL_INTERLEAVE && nodemask =3D=3D nodemask_0, + "Wanted MPOL_INTERLEAVE (%u) and nodemask 0x%lx, got %u and 0x%lx", + MPOL_INTERLEAVE, nodemask_0, policy, nodemask); + + /* Test basic MPOL_BIND policy */ + kvm_mbind(mem + page_size * 2, page_size * 2, MPOL_BIND, &nodemask_0, max= node, 0); + kvm_get_mempolicy(&policy, &nodemask, maxnode, mem + page_size * 2, MPOL_= F_ADDR); + TEST_ASSERT(policy =3D=3D MPOL_BIND && nodemask =3D=3D nodemask_0, + "Wanted MPOL_BIND (%u) and nodemask 0x%lx, got %u and 0x%lx", + MPOL_BIND, nodemask_0, policy, nodemask); + + /* Test MPOL_DEFAULT policy */ + kvm_mbind(mem, total_size, MPOL_DEFAULT, NULL, 0, 0); + kvm_get_mempolicy(&policy, &nodemask, maxnode, mem, MPOL_F_ADDR); + TEST_ASSERT(policy =3D=3D MPOL_DEFAULT && !nodemask, + "Wanted MPOL_DEFAULT (%u) and nodemask 0x0, got %u and 0x%lx", + MPOL_DEFAULT, policy, nodemask); + + /* Test with invalid policy */ + ret =3D mbind(mem, page_size, 999, &nodemask_0, maxnode, 0); + TEST_ASSERT(ret =3D=3D -1 && errno =3D=3D EINVAL, + "mbind with invalid policy should fail with EINVAL"); + + kvm_munmap(mem, total_size); +} + +static void test_numa_allocation(int fd, size_t total_size) +{ + unsigned long node0_mask =3D 1; /* Node 0 */ + unsigned long node1_mask =3D 2; /* Node 1 */ + unsigned long maxnode =3D 8; + void *pages[4]; + int status[4]; + char *mem; + int i; + + if (!is_multi_numa_node_system()) + return; + + mem =3D kvm_mmap(total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd); + + for (i =3D 0; i < 4; i++) + pages[i] =3D (char *)mem + page_size * i; + + /* Set NUMA policy after allocation */ + memset(mem, 0xaa, page_size); + kvm_mbind(pages[0], page_size, MPOL_BIND, &node0_mask, maxnode, 0); + kvm_fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, page_siz= e); + + /* Set NUMA policy before allocation */ + kvm_mbind(pages[0], page_size * 2, MPOL_BIND, &node1_mask, maxnode, 0); + kvm_mbind(pages[2], page_size * 2, MPOL_BIND, &node0_mask, maxnode, 0); + memset(mem, 0xaa, total_size); + + /* Validate if pages are allocated on specified NUMA nodes */ + kvm_move_pages(0, 4, pages, NULL, status, 0); + TEST_ASSERT(status[0] =3D=3D 1, "Expected page 0 on node 1, got it on nod= e %d", status[0]); + TEST_ASSERT(status[1] =3D=3D 1, "Expected page 1 on node 1, got it on nod= e %d", status[1]); + TEST_ASSERT(status[2] =3D=3D 0, "Expected page 2 on node 0, got it on nod= e %d", status[2]); + TEST_ASSERT(status[3] =3D=3D 0, "Expected page 3 on node 0, got it on nod= e %d", status[3]); + + /* Punch hole for all pages */ + kvm_fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, total_si= ze); + + /* Change NUMA policy nodes and reallocate */ + kvm_mbind(pages[0], page_size * 2, MPOL_BIND, &node0_mask, maxnode, 0); + kvm_mbind(pages[2], page_size * 2, MPOL_BIND, &node1_mask, maxnode, 0); + memset(mem, 0xaa, total_size); + + kvm_move_pages(0, 4, pages, NULL, status, 0); + TEST_ASSERT(status[0] =3D=3D 0, "Expected page 0 on node 0, got it on nod= e %d", status[0]); + TEST_ASSERT(status[1] =3D=3D 0, "Expected page 1 on node 0, got it on nod= e %d", status[1]); + TEST_ASSERT(status[2] =3D=3D 1, "Expected page 2 on node 1, got it on nod= e %d", status[2]); + TEST_ASSERT(status[3] =3D=3D 1, "Expected page 3 on node 1, got it on nod= e %d", status[3]); + + kvm_munmap(mem, total_size); +} + static void test_fault_sigbus(int fd, size_t accessible_size, size_t map_s= ize) { const char val =3D 0xaa; @@ -273,11 +369,13 @@ static void __test_guest_memfd(struct kvm_vm *vm, uin= t64_t flags) if (flags & GUEST_MEMFD_FLAG_INIT_SHARED) { gmem_test(mmap_supported, vm, flags); gmem_test(fault_overflow, vm, flags); + gmem_test(numa_allocation, vm, flags); } else { gmem_test(fault_private, vm, flags); } =20 gmem_test(mmap_cow, vm, flags); + gmem_test(mbind, vm, flags); } else { gmem_test(mmap_not_supported, vm, flags); } --=20 2.51.0.710.ga91ca5db03-goog From nobody Sat Feb 7 23:23:05 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2B8427381B for ; Tue, 7 Oct 2025 22:15:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875303; cv=none; b=PTvukgjHfgslnHbg2lw/cA1P+MreadXzVonUu7vynZIG0BgFJkJyjKk9aBtN5UaU1Q/qlWWF1iJxWmqpTZ0RPzkw0kYoBa8L5YhHGx8mVnr93cogrLymJC+nntoOqoYpAOyTcOrcP6V9QqX7TZGPW2EwOcEEWCFcHeKmcUZR8ZA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759875303; c=relaxed/simple; bh=ercJrCIZ2Uh4j1w9fwtjPtGjrYq3ynhNx8655WKwJ3E=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qqHcSdKMyzRm1ogsE+koc3XshMG8QJB+hX5zeL/coatRN7y1BuemWotwf3XYOkQer6MfvIqXuldRirWtTgWyWOtLILy3JQWeOCpS4emxhmVR5sxyjq4sLbKbTZ71aVkO1RjkXpGeX1VYp/YtYeK/D4CU/SN3FWM+rZI6FVS6va4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=v9BSHA4w; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="v9BSHA4w" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-269af520712so74212105ad.2 for ; Tue, 07 Oct 2025 15:15:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759875300; x=1760480100; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=7fMZ7OhM8JOlJvnfA26tbvkth+uO96Z3bmtnJ/qhoYI=; b=v9BSHA4wm104IZvMDEZUSR6qTlukB4o9tl66BHKw1fgWMoMl4rVd0XT8u2UkiYOgId KKJlqnKJC+icJGrLcI3SjhH0gBmEJw4QNgsajBuk+sLHuhqk6uvdEXpobwhHCnebSc/j YTjA1uilfDt51KF5Q3eHQ6lMG7umrmXtL3RTFA/WdYTF9QcejgQpK1rZ5binrKoJtQcX lG+eJRReuKjF3KnsWEFE/MkREF9Hl2PDkJwUMPXzWqZVnTjd5WRgjMT5Afmp0n2wxd1M jrOqwhgqmMuZSeyix39DXtg0kuInQyyESyrtjvvBnxM6qQax2ih+4t3XVkzCbo2TKoSy Ne9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759875300; x=1760480100; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=7fMZ7OhM8JOlJvnfA26tbvkth+uO96Z3bmtnJ/qhoYI=; b=IMHi24A2QVAoAkXgEJn7QtKpM3M4wEl7QKcAXa4lt+fsd3wTSOtPmCEw6VGpv/9fAo wZ3+/YaC33zuTOAX3/9TroHskaBJDoe6NFMsrEoi3vMe+6AupnXew8Jr4WSon+Ebh631 dDEEDSUbwG9VOhKaZToHUaiLQ9dknWHBaMgdmiMkKwUegLsAyiEcPdgvLoza+ab/QQ0j 8Vio07jVtgvAjV9i3UaN/c06/fSWTr9aQ8ZqhRMIDhvBp3VjdlQj5V36+iP/e3DAx56S hotf+T6Ov/eEZ+zN1Mym0V1s68BOvoVOmdki/IJt8WF3VNZnkOKbSzTyHx/O7kPyMUzU gB3w== X-Forwarded-Encrypted: i=1; AJvYcCVTAP7DzDOf+0D3sNwMzXfMB8MWg7/u9BsjBYcTq34060uyQxyWMaMSAVaoVVqdibsa37gCIGNUl+FsZdc=@vger.kernel.org X-Gm-Message-State: AOJu0YyxHwanDuDHqgZFK4TwSZlt3dlz3duxuHO3Nsp0hk6zNV2bG6nQ gh/J0FAv7SbMcBwSYrq2DnRiQqa1mAeLDHed3WEcy34DW3ykAeUXOusOqR7+VOtf2M0hYll60iG kvg1sxw== X-Google-Smtp-Source: AGHT+IECKNXtIHUW5N14ZiXdwr22UXg6a0qRVDT9HGhdqQLa/WqCTYC09KfmHy6MwiN8aQHU+fr/YvGCioI= X-Received: from plblb3.prod.google.com ([2002:a17:902:fa43:b0:269:a2bc:79bc]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2c5:b0:27f:1c1a:ee57 with SMTP id d9443c01a7336-290273736d4mr15592295ad.16.1759875300207; Tue, 07 Oct 2025 15:15:00 -0700 (PDT) Reply-To: Sean Christopherson Date: Tue, 7 Oct 2025 15:14:20 -0700 In-Reply-To: <20251007221420.344669-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251007221420.344669-1-seanjc@google.com> X-Mailer: git-send-email 2.51.0.710.ga91ca5db03-goog Message-ID: <20251007221420.344669-13-seanjc@google.com> Subject: [PATCH v12 12/12] KVM: guest_memfd: Add gmem_inode.flags field instead of using i_private From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Paolo Bonzini , Sean Christopherson Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, David Hildenbrand , Fuad Tabba , Ackerley Tng , Shivank Garg , Ashish Kalra , Vlastimil Babka Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Track a guest_memfd instance's flags in gmem_inode instead of burying them in i_private. Burning an extra 8 bytes per inode is well worth the added clarity provided by explicit tracking. Signed-off-by: Sean Christopherson --- virt/kvm/guest_memfd.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 95267c92983b..10df35a9ffd4 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -30,6 +30,8 @@ struct gmem_file { struct gmem_inode { struct shared_policy policy; struct inode vfs_inode; + + u64 flags; }; =20 static __always_inline struct gmem_inode *GMEM_I(struct inode *inode) @@ -162,7 +164,7 @@ static struct folio *kvm_gmem_get_folio(struct inode *i= node, pgoff_t index) =20 static enum kvm_gfn_range_filter kvm_gmem_get_invalidate_filter(struct ino= de *inode) { - if ((u64)inode->i_private & GUEST_MEMFD_FLAG_INIT_SHARED) + if (GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_INIT_SHARED) return KVM_FILTER_SHARED; =20 return KVM_FILTER_PRIVATE; @@ -398,9 +400,7 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slo= t *slot, gfn_t gfn) =20 static bool kvm_gmem_supports_mmap(struct inode *inode) { - const u64 flags =3D (u64)inode->i_private; - - return flags & GUEST_MEMFD_FLAG_MMAP; + return GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_MMAP; } =20 static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) @@ -412,7 +412,7 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct vm= _fault *vmf) if (((loff_t)vmf->pgoff << PAGE_SHIFT) >=3D i_size_read(inode)) return VM_FAULT_SIGBUS; =20 - if (!((u64)inode->i_private & GUEST_MEMFD_FLAG_INIT_SHARED)) + if (!(GMEM_I(inode)->flags & GUEST_MEMFD_FLAG_INIT_SHARED)) return VM_FAULT_SIGBUS; =20 folio =3D kvm_gmem_get_folio(inode, vmf->pgoff); @@ -601,7 +601,6 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t si= ze, u64 flags) goto err_fops; } =20 - inode->i_private =3D (void *)(unsigned long)flags; inode->i_op =3D &kvm_gmem_iops; inode->i_mapping->a_ops =3D &kvm_gmem_aops; inode->i_mode |=3D S_IFREG; @@ -611,6 +610,8 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t si= ze, u64 flags) /* Unmovable mappings are supposed to be marked unevictable as well. */ WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping)); =20 + GMEM_I(inode)->flags =3D flags; + file =3D alloc_file_pseudo(inode, kvm_gmem_mnt, name, O_RDWR, &kvm_gmem_f= ops); if (IS_ERR(file)) { err =3D PTR_ERR(file); @@ -931,6 +932,8 @@ static struct inode *kvm_gmem_alloc_inode(struct super_= block *sb) return NULL; =20 mpol_shared_policy_init(&gi->policy, NULL); + + gi->flags =3D 0; return &gi->vfs_inode; } =20 --=20 2.51.0.710.ga91ca5db03-goog