From nobody Thu Sep 24 18:41:44 2026 Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) (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 1152E223328 for ; Tue, 22 Sep 2026 00:13:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036017; cv=none; b=kI+FtvhzjJVXEiTxrtorRU2Eu1jYSC1TNtdObKU0SaoVSjp5g5M52YqoBv05gJNQrOVNJExcNDVesEqs/ekwEWxnlh95+nZ0k5R3b6fWYkKFNhaRc4mCZyS78ByvsaeWbXcpQBL4EYoLVJ7mNY1O02YjL5xFBlkpKYOeZ6nwjrk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036017; c=relaxed/simple; bh=+OgMs5FTH885W5hqbW9mZemd9t74Q3YKNRON5By5iS4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LLGUFuctmFIitsNYtd1d5mu/7xEtRSHxiZ5zvJUBvb03uswXfST74uebpDdFavkQrmLDvlVjQ+G5d/WgPeXe6rKKBB/9SnAo9AFuvpDoxOxUzgRQnzEgnP4mf7nD+dCfbFQ8WfMrtzr0S7Gntcn+jZBg91geHR0avMzGxJKu0bs= 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=Zv+xpZf7; arc=none smtp.client-ip=209.85.214.198 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="Zv+xpZf7" Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2d94f086fedso51645525ad.1 for ; Mon, 21 Sep 2026 17:13:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790036015; x=1790640815; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:reply-to:from:to:cc:subject:date:message-id :reply-to:content-type; bh=TG/mu75XYT0SNXMXtTJlKEYyCMKeyuwB8Y7qCUcxVbg=; b=Zv+xpZf7m3MRy4BDsAoYkTpzhbF0wI6WMAdlcignQ0rAQ4pEmhV26c5Q35nZjRi+vV AfxxbgmB1VOmvbOW6BcR7n/jkHC2H3aW6gtnuK3j0E+NFcEaK/kgVPgOjEzp5sCPCOWr 41cnHNbo/a9ESEG1UTwocPPaw1hwNHN2G6j+X7HVBWZZpn15UkwAoxHbE+3sLqrbqGC0 S6vgVQbyn3rTyeCfcCaIMjB8FdMf/buJwxc+KApjPS9sjCp34GxUyR5a5mIrDIr1/lWt mekaHRIYifi6pDUnXsGvkxN71PlqmY2alZZvA2827/uP04HneuI1SFtCtSYawft2skab pY3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790036015; x=1790640815; h=content-type: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:content-type; bh=TG/mu75XYT0SNXMXtTJlKEYyCMKeyuwB8Y7qCUcxVbg=; b=vBfAHE2MoweMAlPC1BtCVSW/T6rU+X2LbBU6OXmGsUubeYF8Xlj+9AibTtfYAjakdH brC4zKmjzSzb8GF83qq8stT+xFi4AI95rgwOLCkfoYkOc73u558PgsDI1edr8Kbh2OMW 9AynHLzmhzwVQY9ovshK/50SJtbDB/OHQmCsEfD3K9Zrtl+V5FWS0wyXfleNHO9e2S2P 0OVuptxYeYUmtkcYq29lRn3zScIw+36FKKyoCu3vl06eJ5O8ikr/nN0LJ+qRHr4JgOWn FPiFdLcg+61Cs/fDjhrv8EGh2OE/pmRqjhb17ci4AI0skn8uSas9+bP0b9rS86Ts7piR w5MQ== X-Forwarded-Encrypted: i=1; AKwUvBy52hV6bXhmO3GPVNWqBARyzLNEDVhG2Tu6LGTbtKkMxt0SRDErl+8PtAhBdOc+OqprBr3ZqRK4O1muTEE=@vger.kernel.org X-Gm-Message-State: AFuF++nwwVj77is+pD9Wtxvq62uY/xgw93/mTLxdzd0l3LrS121omQid CeX3KhX3r2545G6NiY/ptPDNQHRFTNf6zgpnlmkWYb4kbXUfq8aVhgbR/jsq2WyJSp6RpYU04E4 rvuD21A== X-Received: from plem11.prod.google.com ([2002:a17:902:e40b:b0:2dc:fcb9:e5f1]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:e742:b0:2df:5ab2:ea13 with SMTP id d9443c01a7336-2df5ab2f6dbmr10657245ad.10.1790036015093; Mon, 21 Sep 2026 17:13:35 -0700 (PDT) Reply-To: Sean Christopherson Date: Mon, 21 Sep 2026 17:13:27 -0700 In-Reply-To: <20260922001332.1121266-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: <20260922001332.1121266-1-seanjc@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260922001332.1121266-2-seanjc@google.com> Subject: [PATCH v5 1/6] KVM: guest_memfd: Gracefully handle xarray errors when binding a memslot From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: David Hildenbrand , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Teodorescu , Dennis Tighe , Sashiko Bot , Ackerley Tng , Yan Zhao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If inserting a memslot into a guest_memfd's bindings xarray fails, propagate the error back to the caller, i.e. fail memslot creation as well. Signalling success and continuing on with memslot creation results in use-after-free, as the guest_memfd instance will remain reachable via the memslot after the file is freed (kvm_gmem_release() won't nullify the file pointer due to lack of a valid binding). Opportunistically WARN and reject binding if KVM_MEMSLOT_GMEM_ONLY is already set, partly to guard against goofs elsewhere, but mostly so that KVM doesn't need to worry about clobbering flags when unwinding on failure. Regarding the unwind, the slot must be fully prepared before inserting it into the bindings, at which point the slot becomes reachable. I.e. waiting to update the slot in order to avoid the ugly unwind isn't an option. And as part of the unwind, explicitly nullify the relevant bindings, as xarray can store a subset of entries when populating a range. Fixes: a7800aa80ea4 ("KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-spe= cific backing memory") Cc: stable@vger.kernel.org Reported-by: Stefan Teodorescu Reported-by: Dennis Tighe Reported-by: Sashiko Bot Closes: https://lore.kernel.org/all/20260823135031.4F6DC1F000E9%40smtp.kern= el.org Reviewed-by: David Hildenbrand (Arm) Reviewed-by: Ackerley Tng Signed-off-by: Sean Christopherson --- virt/kvm/guest_memfd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 63943aa253d4..c094611f7c7a 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -654,6 +654,9 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_sl= ot *slot, BUILD_BUG_ON(sizeof(gpa_t) !=3D sizeof(offset)); BUILD_BUG_ON(sizeof(gfn_t) !=3D sizeof(slot->gmem.pgoff)); =20 + if (WARN_ON_ONCE(slot->flags & KVM_MEMSLOT_GMEM_ONLY)) + return -EINVAL; + file =3D fget(fd); if (!file) return -EBADF; @@ -692,7 +695,13 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_s= lot *slot, if (kvm_gmem_supports_mmap(inode)) slot->flags |=3D KVM_MEMSLOT_GMEM_ONLY; =20 - xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNEL); + r =3D xa_err(xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNE= L)); + if (r) { + xa_store_range(&f->bindings, start, end - 1, NULL, GFP_KERNEL); + slot->gmem.file =3D NULL; + slot->gmem.pgoff =3D 0; + slot->flags &=3D ~KVM_MEMSLOT_GMEM_ONLY; + } filemap_invalidate_unlock(inode->i_mapping); =20 /* @@ -700,7 +709,6 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_sl= ot *slot, * not the other way 'round. Active bindings are invalidated if the * file is closed before memslots are destroyed. */ - r =3D 0; err: fput(file); return r; --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 18:41:44 2026 Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) (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 D6F852882DE for ; Tue, 22 Sep 2026 00:13:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036019; cv=none; b=upPHPDQw9wL0CldeN3wY4hIWe+gefeAdE+UBQjpeK5x2zZ2W3I94t+rbF9FDePpfsG4bR+LsfiElQEQ485HrVjyNjKFPEOj80HuJcIiT0+/qKDnFKiIJo+ABFR0f4OnLN4DVoJGPi4mvPndXn0GAgjXxkpRl6eSc/MNWMlQFPl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036019; c=relaxed/simple; bh=JdOJf+2+GAEhZwBCGYJCZV2CMdKHgYqKlljHYuL2tJQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=A6ASOsjKerX8qnpW22PFehYG5T4shL6D11UfwwW/HqfSdwSSRCtUO+HCdw+GCCIxSjfghmaGgHiCzwoVnr11Ls49VG0ZgWaq3UsPCX3tQvCKlgx4FCgTWysxqwbfJNOv0ZkNrl9tkSUViZGVD34vaJxKPshY6LQv+9sIp2AjJGQ= 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=pwtTK5eE; arc=none smtp.client-ip=209.85.216.72 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="pwtTK5eE" Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-398dcfabbf8so11633851a91.0 for ; Mon, 21 Sep 2026 17:13:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790036017; x=1790640817; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:reply-to:from:to:cc:subject:date:message-id :reply-to:content-type; bh=jDeElCc4OjANkEErvoKCXV2KgfEdeXF0F1dMXf8gxcA=; b=pwtTK5eECD+wXDjObhofuOs5+YmPekgHUeZYEv50j2WcsO3nWAFP4bsnnGzX8LtLrn 2K+aULdyg/w9cnO+xoRUuaERtXXS2S03qasbUwwYySzo1R79H0nt055SrggL43v49VpZ UqLR5tj2NmldmVsjSqE+dSUrc7X1SnCvD+We/J2yPp+P8q4AWqODjrsf8iwiFdiVZaud /jKGgzBbC7GDAGqDtzgsRbnkMnpm/wB2ftrSUWu5/UKvmSca6zGK+dEgHBJS07hKbtyZ F7AdtRlR4e9MwIxNUXCofCrgEzEyifz1EQP5fWvAfwlSz5dw3/kdEl1iNU5kKm5fa1Xl l//A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790036017; x=1790640817; h=content-type: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:content-type; bh=jDeElCc4OjANkEErvoKCXV2KgfEdeXF0F1dMXf8gxcA=; b=1QliIkJ/ThjwqA8PfVEXUEWJid3Qn0OCkII1eaFE0tYm949U9BocEXK4a1rQNjSq32 4ewzTLDC6kuPHzXMbSKVs/cpF+JxuVh83gJZ8Sc5fwWTFPe/SRnH0VLaRhz9yA3NWhgg wWkniQ0Dh2akO2fSWnNQ9WhN8NX9vGsMD7Za9Y1a3U5epasNj8Zg6yaDTxk1BdmGwSrU GWHid5B/9EUUOBRHv1lFHUySwqso+5lXoXQufwT1YiwdjMKm791TxEvaWxfdpIZ8z5Xt BBKG+oQFdLletU9QQDgFkqfuEH5d9RuH31GgQxSSw1uiHdQ4M+ktkJzRwCMAaRVj56EZ NEtA== X-Forwarded-Encrypted: i=1; AKwUvBzZnEzNXJntEdULb+kkqGeiSEs+K3sxuU5EjQVrccHwkxJ+qO9qZqp8FCi2So1anYUqMdDbqfYNKq5vO4c=@vger.kernel.org X-Gm-Message-State: AFuF++mbfLW+4hyZLWs6nYjO5ShV1NKtApY8TzzNbroN20W/qvm54Xk+ ma1YeTxm+ODZAgXihTRQMSYPq5+Fy8Zeg6okamUPBWkwAotrPbip0EAcImdZXru/YES5yjNxB+W XW1dwIg== X-Received: from pjue21.prod.google.com ([2002:a17:90a:e4d5:b0:39e:6e36:d13d]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90a:c02:b0:39e:5c8a:33b0 with SMTP id 98e67ed59e1d1-39e5c8a354amr11422281a91.33.1790036016788; Mon, 21 Sep 2026 17:13:36 -0700 (PDT) Reply-To: Sean Christopherson Date: Mon, 21 Sep 2026 17:13:28 -0700 In-Reply-To: <20260922001332.1121266-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: <20260922001332.1121266-1-seanjc@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260922001332.1121266-3-seanjc@google.com> Subject: [PATCH v5 2/6] KVM: Use goto to handle errors during memslot preparation From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: David Hildenbrand , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Teodorescu , Dennis Tighe , Sashiko Bot , Ackerley Tng , Yan Zhao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use a goto to unwind early memslot changes if preparing for a memslot operation fails. This will allow moving the creation of guest_memfd bindings into kvm_set_memslot() without needing to copy+paste the unwind logic. No functional change intended. Cc: stable@vger.kernel.org Reviewed-by: David Hildenbrand (Arm) Reviewed-by: Ackerley Tng Signed-off-by: Sean Christopherson --- virt/kvm/kvm_main.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d9da8b51614a..24cf96840827 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1941,21 +1941,8 @@ static int kvm_set_memslot(struct kvm *kvm, } =20 r =3D kvm_prepare_memory_region(kvm, old, new, change); - if (r) { - /* - * For DELETE/MOVE, revert the above INVALID change. No - * modifications required since the original slot was preserved - * in the inactive slots. Changing the active memslots also - * release slots_arch_lock. - */ - if (change =3D=3D KVM_MR_DELETE || change =3D=3D KVM_MR_MOVE) { - kvm_activate_memslot(kvm, invalid_slot, old); - kfree(invalid_slot); - } else { - mutex_unlock(&kvm->slots_arch_lock); - } - return r; - } + if (r) + goto err; =20 /* * For DELETE and MOVE, the working slot is now active as the INVALID @@ -1987,6 +1974,20 @@ static int kvm_set_memslot(struct kvm *kvm, kvm_commit_memory_region(kvm, old, new, change); =20 return 0; + +err: + /* + * For DELETE/MOVE, revert the above INVALID change. No modifications + * required since the original slot was preserved in the inactive slots. + * Changing the active memslots also release slots_arch_lock. + */ + if (change =3D=3D KVM_MR_DELETE || change =3D=3D KVM_MR_MOVE) { + kvm_activate_memslot(kvm, invalid_slot, old); + kfree(invalid_slot); + } else { + mutex_unlock(&kvm->slots_arch_lock); + } + return r; } =20 static bool kvm_check_memslot_overlap(struct kvm_memslots *slots, int id, --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 18:41:44 2026 Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) (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 0F39126CE2C for ; Tue, 22 Sep 2026 00:13:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036020; cv=none; b=MOZV3W03NSAEQgSh9uABNzEqy5kJxflvcc3RQmjM93i7veaWeQkq+mSGmvurmg/h+tVojT0Wm8j38eGjk0wiNBJ07MHEFSL8s2v7fuwb3icqB2dQrxyPEOI2sokRHMh5Sm0Pp0PHIlqvLmkeF8WFcdtg6DaMxmTRuk8GBsOrdIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036020; c=relaxed/simple; bh=/uWjI8Uu4H+jwIc5bzgv2pY2GKSfTMxj6nuLZ1zl2PU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=I0Uxc41SX9Gt/A771RDKxQ3MlEnsoWld5JojF8IsoZDbPljsvzBkmLJAyJRk9BJtfzRMFWP53sCKJ4qfUXS8TPykyUooMY7Zl+4sKm81X/4CgYKjYdmnC5ybPz4udu1/rEhjGy0+wzXCJe9/QdWNZOnOo/ggDlFFw/Q9jfLJxCQ= 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=SWMkc23e; arc=none smtp.client-ip=209.85.215.198 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="SWMkc23e" Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-cb11535e6a1so2789119a12.0 for ; Mon, 21 Sep 2026 17:13:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790036018; x=1790640818; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:reply-to:from:to:cc:subject:date:message-id :reply-to:content-type; bh=turXne4uYV7wcVpOhFPdmOUyNfChurx8+MQeLApE3QQ=; b=SWMkc23eyqHUmYNn9xDXzBgGXhBVq3fwWxL3rbDt4pXFCPz+JhhBMdbxBd06misfcu W4Bg+QaqaZIqHQZeiEYe/39stwqxfV6CopyWWKtCZ41uFn3FS70eN4hdk6KVVbYPI1Wd MnzntsxBTAlmwwkI9p8SjKgWr0WJASEJL6a+4hkZekuN2gRFADoKv9Sz5ZwWWr/z4V+U PPWQUpd8BA7sHq9fs/BC1+gi4RdNbIPgFII6yHR2Fhy4XiZ5Ffzo3u8w5W3G8I4dyATd SbWePZsFf8Wzxda6JfBfck1OaVOFlmKvjp+ljHp97QQG/Q50NHrXa/IcAp8qlfk9qr4X g4pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790036018; x=1790640818; h=content-type: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:content-type; bh=turXne4uYV7wcVpOhFPdmOUyNfChurx8+MQeLApE3QQ=; b=r9CNWItPYFlhmmnzzuH49hwZUALiVBJE66eBZPIcLpvyXkf9jAL0Byf9+KGAmfjky7 Xg9lIrunTnEGPyxuhdNw/7ptym5diAUFYJlFw1Z6BbxlDAmL9uFpS8k57H178MthCQtB VBXg2X7csGX5sGch4HzQ6a/yHGSFK6mkdQ3CtRRhWnO7NTEijV2fs0kTR5mwrtyMEpZi Xj7I2VWfjXQMoakM3EbcmltihlIqo6/FgudbvwQsH7hDW2vG3xfsaroFMNU57DhekxZ+ o4ZaQ8cB8Xm3CGAT5eSlw0AffgsyMYJWL2ZdMW5p06iqOjTshGgsZysgTqugQ4InAH0M 6t4A== X-Forwarded-Encrypted: i=1; AKwUvBwL5n+Fvhrn5E2ONqW5KtNmtGRAo9iNohUGPplSWDgeqBfbDP8qGWITYkZuDYJuK60MiSq3/6/+3w8EBfY=@vger.kernel.org X-Gm-Message-State: AFuF++mizCroBkqbSnU/O9qhS486bKDXMmCBsLbLMMz0Pgb9GvkwOq/M 352JXbIlw2DKUnHp8+LmEaAdc2nsUztARvA33ptEsw8Co6TPga6Zk0qOLQ8VeaKfQ4DsOQCGRYw JQvSqfw== X-Received: from pgvn10.prod.google.com ([2002:a65:63ca:0:b0:cc4:5907:21e9]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:a10f:b0:3dd:85a9:55a0 with SMTP id adf61e73a8af0-3dd8c5ac31emr18020098637.34.1790036018118; Mon, 21 Sep 2026 17:13:38 -0700 (PDT) Reply-To: Sean Christopherson Date: Mon, 21 Sep 2026 17:13:29 -0700 In-Reply-To: <20260922001332.1121266-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: <20260922001332.1121266-1-seanjc@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260922001332.1121266-4-seanjc@google.com> Subject: [PATCH v5 3/6] KVM: Only bind memslot to guest_memfd instance for CREATE operations From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: David Hildenbrand , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Teodorescu , Dennis Tighe , Sashiko Bot , Ackerley Tng , Yan Zhao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For additional defense-in-depth, and to avoid having to handle impossible unwind scenarios when binding to a memslot fails, bind a memslot to a gmem instance only when for CREATE operations, i.e. don't attempt to establish a binding for MOVE and FLAGS_ONLY operations. And when FLAGS_ONLY operations are eventually supported (this is currently all dead code), creating a new binding would be incorrect; KVM instead needs to do a 1:1 replacement of the existing binding, i.e. FLAGS_ONLY will need its own dedicated handling. Update the relevant TODO to make a better guess as to what needs to be done to support toggling dirty logging for guest_memfd memslots. Because it's dead code, no functional change intended. Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Reviewed-by: David Hildenbrand (Arm) --- virt/kvm/kvm_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 24cf96840827..ccfd5f5102a5 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1752,10 +1752,10 @@ static void kvm_commit_memory_region(struct kvm *kv= m, kvm_destroy_dirty_bitmap(old); =20 /* - * Unbind the guest_memfd instance as needed; the @new slot has - * already created its own binding. TODO: Drop the WARN when - * dirty logging guest_memfd memslots is supported. Until then, - * flags-only changes on guest_memfd slots should be impossible. + * TODO: Drop the WARN and do the unbind() call only for MOVE + * when dirty logging guest_memfd memslots is supported. Until + * then, flags-only changes on guest_memfd slots should also be + * impossible; unbind the old memslot for defense-in-depth. */ if (WARN_ON_ONCE(old->flags & KVM_MEM_GUEST_MEMFD)) kvm_gmem_unbind(old); @@ -2116,7 +2116,7 @@ static int kvm_set_memory_region(struct kvm *kvm, new->npages =3D npages; new->flags =3D mem->flags; new->userspace_addr =3D mem->userspace_addr; - if (mem->flags & KVM_MEM_GUEST_MEMFD) { + if (change =3D=3D KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD)) { r =3D kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset); if (r) goto out; @@ -2129,7 +2129,7 @@ static int kvm_set_memory_region(struct kvm *kvm, return 0; =20 out_unbind: - if (mem->flags & KVM_MEM_GUEST_MEMFD) + if (change =3D=3D KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD)) kvm_gmem_unbind(new); out: kfree(new); --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 18:41:44 2026 Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) (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 5B04D2773F7 for ; Tue, 22 Sep 2026 00:13:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036026; cv=none; b=QJndEN1NYpoiexRGYw46jhNtJfvC0s6cOhBWnLws6nbJlbldWfOoiZMt1kY4CnFFJQTzNDUzbx18SPhBDiDZ2MWcAoDt++9j2ZVwiNDttCGzS3CGE5l9qneaeuey76KWxgU6pUDMRl7t4dpHCnsZUV2Og+/YkEoBVi9F3JmHMOI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036026; c=relaxed/simple; bh=zCji+nm6bPfKkfRj+T++V9XtpQDPMG4grJBVw/GKfdM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NgVX6Vuj9/CzFub3VKxU9K7J6H+2eAeGaWlqJReuBM0Ko6bvLC/UoVSzfZhb1S621lFJ0b+uIdq5s1k6McDiE0RmgPyc1w6gCYHGhMjHLJmT4wyZBv6mdW/4XGJpRb3tcYSoYznIEg/tBeNkd/sLSzLDHTpkuE5762jOhx6OBsg= 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=KzhHAdc7; arc=none smtp.client-ip=209.85.215.197 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="KzhHAdc7" Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-cc1cade6b71so364644a12.0 for ; Mon, 21 Sep 2026 17:13:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790036020; x=1790640820; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:reply-to:from:to:cc:subject:date:message-id :reply-to:content-type; bh=mXJYeSwmdO8BSBlAcqHdtDGYHg5nY+v9YdRsbiYIKqY=; b=KzhHAdc7jxNsudFwjffBhoZnWITLpAs3fdkOqTXL1w+NAh3uuAMZsKaHzBdfcCyg7z +CpUUC6oiEcd6PEtZUBQBJ5tu/es8QG1Wx0BzN4wCUwY/rVxCZ2qKR3pwN9FZQfV6uDv DtbhLtoSBHXb9wyuk4TGEWIkfM5WLZ8VVFvc0qPlVaBsFoebxcMjgaFDp1fCMObWhw+O lJyXg7A1bZLVD9c52ACNlrSLE4dk485VwcbSDLz5EN72lFaUkBWn+Uo+d1TGBaOHDQIo Exo5uY68vKl9E8fVVDoYerLUD14s+q+hIHgia/hOySadXpDwZ7f2CFURi0I4e53lACqJ dd6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790036020; x=1790640820; h=content-type: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:content-type; bh=mXJYeSwmdO8BSBlAcqHdtDGYHg5nY+v9YdRsbiYIKqY=; b=FNJZhJc3blFDxKZ5qjjJGked2uNNt4PbDdyr5WQoL9zDr2hizQW9+OaTKa3IbuBB70 2P449L6k+2L7AVA9x/hTK1Sn/NOHlgsUGDeTovO8GayDMYR6K8BWFxHFmygWpAfibBJM 4Tuex0BzHCE7PE4MKZPxv+Uu5uB7SrcNKSEo+DsCNjYf+hfb3S6+C09rxZ9CNPE+hzlU 4Bik4H7WjTb40N8exw3eCr15cLZ7TO+kkiOmmXpTKCZBKqdnsg8OWfEBL7ixlKD/VpgB kyUB/Rd2WjKLlLtjIBefGeaBLRJiT5CK55IgbV5aSLlAp+RH5WBOIHApGtOYTDqVUoE1 A9uA== X-Forwarded-Encrypted: i=1; AKwUvBzaIDTn3MkrubI85lyooPrVneh5A3jt8lTvu+sQF5iFyyh+F8X8v+9GmfamPjeKcym979il9ct252CbKwY=@vger.kernel.org X-Gm-Message-State: AFuF++nEq/kjprDYB7Zj3H2Zgq/9DYr7zloPpkEQHXOmcozn9vCbpB6J IJEF6jHi1XSgTZ4x4oxNTLcJzaVEmTFAN10xIQZplKom9uR23zXodMHKxH2tdmws+YzP+yfLBJQ h7ua2lw== X-Received: from pgvn3.prod.google.com ([2002:a65:63c3:0:b0:cc4:aa2a:ae77]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:2590:b0:3dd:85a8:4c50 with SMTP id adf61e73a8af0-3dde023e07dmr1126632637.20.1790036019241; Mon, 21 Sep 2026 17:13:39 -0700 (PDT) Reply-To: Sean Christopherson Date: Mon, 21 Sep 2026 17:13:30 -0700 In-Reply-To: <20260922001332.1121266-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: <20260922001332.1121266-1-seanjc@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260922001332.1121266-5-seanjc@google.com> Subject: [PATCH v5 4/6] KVM: guest_memfd: Split bind() into prepare()+commit() phases From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: David Hildenbrand , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Teodorescu , Dennis Tighe , Sashiko Bot , Ackerley Tng , Yan Zhao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Split binding a memslot to a guest_memfd instance into prepare() and commit() phases so that KVM can separate preparing the memslot from binding the memslot to the gmem instance, i.e. from committing the memslot. This will allow waiting to commit the memslot+gmem binding until the memslot is fully prepared, which is necessary as the memslot becomes reachable when the binding is created. As a bonus, drop the unwind-on-failure from the commit phase (other than nullifying the bindings), as the only reason bind() did the full unwind is because it technically didn't own the memslot, i.e. "needed" to leave memslot in the same state it started in. No functional change intended (the unwinding down on bind() failure was effectively dead code since KVM simply deletes the memslot on failure, i.e. there was nothing that could actually observe the unwind). Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng Reviewed-by: David Hildenbrand (Arm) --- virt/kvm/guest_memfd.c | 68 ++++++++++++++++++++++++------------------ virt/kvm/guest_memfd.h | 19 ++++++++---- virt/kvm/kvm_main.c | 18 ++++++++++- 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index c094611f7c7a..80932f4ec4a3 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -641,15 +641,14 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_creat= e_guest_memfd *args) return __kvm_gmem_create(kvm, size, flags); } =20 -int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, - unsigned int fd, uoff_t offset) +int kvm_gmem_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot= *slot, + unsigned int fd, uoff_t offset) { uoff_t size =3D slot->npages << PAGE_SHIFT; - unsigned long start, end; struct gmem_file *f; struct inode *inode; struct file *file; - int r =3D -EINVAL; + =20 BUILD_BUG_ON(sizeof(gpa_t) !=3D sizeof(offset)); BUILD_BUG_ON(sizeof(gfn_t) !=3D sizeof(slot->gmem.pgoff)); @@ -673,44 +672,55 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_= slot *slot, if (!PAGE_ALIGNED(offset) || offset + size > i_size_read(inode)) goto err; =20 - filemap_invalidate_lock(inode->i_mapping); - - start =3D offset >> PAGE_SHIFT; - end =3D start + slot->npages; - - if (!xa_empty(&f->bindings) && - xa_find(&f->bindings, &start, end - 1, XA_PRESENT)) { - r =3D -EEXIST; - filemap_invalidate_unlock(inode->i_mapping); - goto err; - } - /* * memslots of flag KVM_MEM_GUEST_MEMFD are immutable to change, so * kvm_gmem_bind() must occur on a new memslot. Because the memslot * is not visible yet, kvm_gmem_get_pfn() is guaranteed to see the file. */ WRITE_ONCE(slot->gmem.file, file); - slot->gmem.pgoff =3D start; + slot->gmem.pgoff =3D offset >> PAGE_SHIFT; if (kvm_gmem_supports_mmap(inode)) slot->flags |=3D KVM_MEMSLOT_GMEM_ONLY; =20 - r =3D xa_err(xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNE= L)); - if (r) { - xa_store_range(&f->bindings, start, end - 1, NULL, GFP_KERNEL); - slot->gmem.file =3D NULL; - slot->gmem.pgoff =3D 0; - slot->flags &=3D ~KVM_MEMSLOT_GMEM_ONLY; - } - filemap_invalidate_unlock(inode->i_mapping); - /* - * Drop the reference to the file, even on success. The file pins KVM, - * not the other way 'round. Active bindings are invalidated if the - * file is closed before memslots are destroyed. + * Gift the caller a reference to the file. The reference will be + * dropped after bindings are established, or if installing the new + * memslot ultimately fails. */ + return 0; + err: fput(file); + return -EINVAL; +} + +int kvm_gmem_commit_memory_region(struct kvm *kvm, struct kvm_memory_slot = *slot) +{ + struct gmem_file *f =3D slot->gmem.file->private_data; + struct inode *inode =3D file_inode(slot->gmem.file); + unsigned long start, end; + int r; + + if (WARN_ON_ONCE(slot->gmem.file->f_op !=3D &kvm_gmem_fops)) + return -EIO; + + filemap_invalidate_lock(inode->i_mapping); + + start =3D slot->gmem.pgoff; + end =3D start + slot->npages; + + if (!xa_empty(&f->bindings) && + xa_find(&f->bindings, &start, end - 1, XA_PRESENT)) { + filemap_invalidate_unlock(inode->i_mapping); + return -EEXIST; + } + + r =3D xa_err(xa_store_range(&f->bindings, start, end - 1, slot, GFP_KERNE= L)); + if (r) + xa_store_range(&f->bindings, start, end - 1, NULL, GFP_KERNEL); + + filemap_invalidate_unlock(inode->i_mapping); + return r; } =20 diff --git a/virt/kvm/guest_memfd.h b/virt/kvm/guest_memfd.h index 0f9c6f840838..01bd359d27e3 100644 --- a/virt/kvm/guest_memfd.h +++ b/virt/kvm/guest_memfd.h @@ -8,8 +8,9 @@ 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, uoff_t offset); +int kvm_gmem_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot= *slot, + unsigned int fd, uoff_t offset); +int kvm_gmem_commit_memory_region(struct kvm *kvm, struct kvm_memory_slot = *slot); void kvm_gmem_unbind(struct kvm_memory_slot *slot); #else static inline int kvm_gmem_init(struct module *module) @@ -17,9 +18,17 @@ 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, uoff_t offset) + +static inline int kvm_gmem_prepare_memory_region(struct kvm *kvm, + struct kvm_memory_slot *slot, + unsigned int fd, uoff_t offset) +{ + WARN_ON_ONCE(1); + return -EIO; +} + +static inline int kvm_gmem_commit_memory_region(struct kvm *kvm, + struct kvm_memory_slot *slot) { WARN_ON_ONCE(1); return -EIO; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ccfd5f5102a5..45b509f4e54b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2117,7 +2117,23 @@ static int kvm_set_memory_region(struct kvm *kvm, new->flags =3D mem->flags; new->userspace_addr =3D mem->userspace_addr; if (change =3D=3D KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD)) { - r =3D kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset); + r =3D kvm_gmem_prepare_memory_region(kvm, new, mem->guest_memfd, + mem->guest_memfd_offset); + if (r) + goto out; + + r =3D kvm_gmem_commit_memory_region(kvm, new); + + /* + * Drop the reference to the file, even on success. The file + * pins KVM, not the other way 'round. Active bindings are + * invalidated if the file is closed before memslots are + * destroyed. + */ +#ifdef CONFIG_KVM_GUEST_MEMFD + fput(new->gmem.file); +#endif + if (r) goto out; } --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 18:41:44 2026 Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) (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 79965284B37 for ; Tue, 22 Sep 2026 00:13:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.70 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036026; cv=none; b=kWnnrLDP2xM+Lf5YEYsBjRAPwDAsUOCCxtIrPnpdeIJXPxC8CipOJzTwD4J8cMp8m+xlFKu3qF9Lir7ZBeKALUx1oH/G8B6NqLXz5Rz/wCvZGzPRf5IvGug/RZ0J59c2yFVnB/0f23NtSWWXTO5ZBU1RNGb+otISnQb3H5lNvVw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036026; c=relaxed/simple; bh=dSa48txFhFArAMj+mUXjAGNyOy5nkRzHhuhWszJbK70=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ks60BjO2eOH51tV04BiBH36cBNTE3hNaNLDDpxpKBtt3T1OTnlo8u0msksCec/LDJK49sJl1/VIS+2umOaXtUQcbkC3nciE/dqFj/zKW8K1laGGBuFqMLO1PkEqwNtFHquWjo/rudbLZva3PGth0may+QZhxQJDQmwp9xAch3dg= 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=Vu9hgjf0; arc=none smtp.client-ip=209.85.216.70 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="Vu9hgjf0" Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-38ecc48b3c2so8537395a91.1 for ; Mon, 21 Sep 2026 17:13:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790036021; x=1790640821; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:reply-to:from:to:cc:subject:date:message-id :reply-to:content-type; bh=iXwUYaOTNYfdxenNnRc/ZPPCIfOwpvTRjEy50CfCbAo=; b=Vu9hgjf0ZJb+bh4SuqN7QzmiYPsqhvPrliOYeBRB7QoW/kxwcZcorTw/tiWUK0I7tl oOl1qEu9K8sIPohc2Drey47vpAtfoXowe8a8jfopsvfqlWvS7u5gUVAjVqo23y0EVQfq MMVP1flUU1Ybfn2I0wshb9z5wZD9Rt1/opQ6Q79sksb4CqFm4hcahLvtg+mt6Fbr0kmy tE58ebzs+c76yZfDqhAiJYgLVcdKLIzGOWFeldiTtdaE14+cvFCtiAiScr9TrAj3ta+1 Pu1CleQDyit88xEKlJ3cJ0qp3TnNkcaJp8IWJVDhb2fqh6eXiFb3GMhzZxLjkHb9Y2kf E7SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790036021; x=1790640821; h=content-type: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:content-type; bh=iXwUYaOTNYfdxenNnRc/ZPPCIfOwpvTRjEy50CfCbAo=; b=feD9wF7SBhm4/bl/mWfsZIRw+sqTM6cniJUU+JEFZCJKu6AS9e8cWCsTHWoUCKI6Yc gjfrU92Za35kq9e8z0deuWwTNrv4zkZins0YKWPeWT64mAcA8304/rPbzI5Xw3AUFq1Y hrL/rfhB08M6PPJ1rJLt7e8GMOtK3HpkUtcgH/GnWshZcDSfpm5qC5PYfsbImobLUmJh rsjDjEwi8fCoj/kSz/yMlow5qD1wxmm4K98WQ8t/HaQ2s52BNdNqT8KsKu3oewBqc9OD 9pmTtxFU3Dr3gjX2bbeQqcFqp6/dSNxhXTqolsUTlUw/JPihXvJJEMSaX8L0IhNPxpi6 /CYg== X-Forwarded-Encrypted: i=1; AKwUvBwumOsjm1JdxA0/h4jTCNCh8wvaJTHXTqb9nm/nYzrFVuu8C+kR6c0yBfDsqgMqZGA2inaEvgclGRPjsUQ=@vger.kernel.org X-Gm-Message-State: AFuF++mgHu9XiByIciGxTGIOjo8gzUMWBJqDBnaau7X9LV8y2lB1tu4B mJzxjhpcOjj2Q9XpD35zmYsMt8PiyDFF4svw5S3O+hg4yCPjRoZCbvdlhgN2qiOH9Rt7jSIAycu UB8M5kQ== X-Received: from pjbms19.prod.google.com ([2002:a17:90b:2353:b0:3a0:6e6d:1b8]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2681:b0:39e:6c6a:657d with SMTP id 98e67ed59e1d1-39e6c6a67c0mr11900031a91.64.1790036020417; Mon, 21 Sep 2026 17:13:40 -0700 (PDT) Reply-To: Sean Christopherson Date: Mon, 21 Sep 2026 17:13:31 -0700 In-Reply-To: <20260922001332.1121266-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: <20260922001332.1121266-1-seanjc@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260922001332.1121266-6-seanjc@google.com> Subject: [PATCH v5 5/6] KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: David Hildenbrand , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Teodorescu , Dennis Tighe , Sashiko Bot , Ackerley Tng , Yan Zhao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Wait to bind a memslot to a guest_memfd instance until *after* the memslot is fully prepared, as creating the binding in guest_memfd will effectively expose the memslot to readers. As pointed out by Sashiko, binding the memslot before it's ready to be exposed to the rest of the world can break various memslot assumption and rules. E.g. x86 could observe a NULL rmap pointer if a PUNCH_HOLE hit the guest_memfd after the binding was created, but before KVM made it through kvm_prepare_memory_region(). Fixes: a7800aa80ea4 ("KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-spe= cific backing memory") Cc: stable@vger.kernel.org Reported-by: Sashiko Bot Closes: https://lore.kernel.org/all/20260826170551.BEF801F000E9@smtp.kernel= .org Signed-off-by: Sean Christopherson Reviewed-by: Ackerley Tng --- virt/kvm/kvm_main.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 45b509f4e54b..90461880ff85 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1944,6 +1944,15 @@ static int kvm_set_memslot(struct kvm *kvm, if (r) goto err; =20 + if (change =3D=3D KVM_MR_CREATE && (new->flags & KVM_MEM_GUEST_MEMFD)) { + r =3D kvm_gmem_commit_memory_region(kvm, new); + if (r) { + kvm_arch_free_memslot(kvm, new); + kvm_destroy_dirty_bitmap(new); + goto err; + } + } + /* * For DELETE and MOVE, the working slot is now active as the INVALID * version of the old slot. MOVE is particularly special as it reuses @@ -2121,32 +2130,25 @@ static int kvm_set_memory_region(struct kvm *kvm, mem->guest_memfd_offset); if (r) goto out; - - r =3D kvm_gmem_commit_memory_region(kvm, new); - - /* - * Drop the reference to the file, even on success. The file - * pins KVM, not the other way 'round. Active bindings are - * invalidated if the file is closed before memslots are - * destroyed. - */ -#ifdef CONFIG_KVM_GUEST_MEMFD - fput(new->gmem.file); -#endif - - if (r) - goto out; } =20 r =3D kvm_set_memslot(kvm, old, new, change); - if (r) - goto out_unbind; =20 - return 0; - -out_unbind: + /* + * Drop the reference to the gmem file, even on success. The file pins + * KVM, not the other way 'round. Active bindings are invalidated if + * the file is closed before memslots are destroyed. + */ +#ifdef CONFIG_KVM_GUEST_MEMFD if (change =3D=3D KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD)) - kvm_gmem_unbind(new); + fput(new->gmem.file); +#endif + + if (r) + goto out; + + return 0; + out: kfree(new); return r; --=20 2.55.0.1082.g2b9226bbc0-goog From nobody Thu Sep 24 18:41:44 2026 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (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 AE65226CE2C for ; Tue, 22 Sep 2026 00:13:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036038; cv=none; b=p6mT3QCiHyKPrEwjy/pjvYWH0cGaJdHRDAvtPEJ3jde+KCByewH8PKUR0XJ9TAlZtE0AeAxQ1IQeZEAhexyctTTbkn4vZ98IiBUKKrmxruyNNvKFt4jbhl4AWWeL0XWiGaEIzZU6t59nR9vrNIFfuhs6hC5/hFB9BT7zOJZomZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790036038; c=relaxed/simple; bh=8hkynfdu3qiULMUVYcyhuzcTSpgySEmn1WUnJFWpxKs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SdZ7XlNmiGfRc6HOOyXAzgfUNWJe7oNGDCmFdzCqCguwf2CklKwhNGGz2gPj3n1L5K4v8aCnYHkPqEZCjbvHny3fVYG9bRXJwGNR2YQL11aJ+6h0xijPoWFwZhqypfa+bup+8AfpTk0GkpV97hl1BCOeNGd/chR2kIEzzVGBI4Q= 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=g8uyAqky; arc=none smtp.client-ip=209.85.210.198 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="g8uyAqky" Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-877ef1457aeso2766176b3a.1 for ; Mon, 21 Sep 2026 17:13:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790036022; x=1790640822; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:reply-to:from:to:cc:subject:date:message-id :reply-to:content-type; bh=1abdFyW8+E6I798OukP3jAN+Bgv2ctuNheDkfba7TQA=; b=g8uyAqkyWWiQJgFx4Rns0exupjnv4x0BzODcp08OS9B3FJEGuOYZQTLDYWUYX5VP3C KYcPH5Uyx/uxsPu3z7Ncex8VrYqhkYm59fmFhGFL7w8aNbAUo/w/7cjHpa+Xm+IS1nNG lNuATo2v1zpbfwgqJYJI+iaLxJLh0ViVAFJLiIgh9PqM7d6OnteEkDD1cQIQbxNxZ/ku 7lKHoxHetSC5nAaLtRYq+RemwmwpPKbvVRHv0wFuqRFkdNtuDxtI95wYa854BH/+LO7J B080GjKcALqpBAxLIEldnuOycpgWGE7JKDGJZff2oDwUjf0v6hL9YDc0JNHZBF0iXb9z NVEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790036022; x=1790640822; h=content-type: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:content-type; bh=1abdFyW8+E6I798OukP3jAN+Bgv2ctuNheDkfba7TQA=; b=zbEmyPi5hgFSRyI/euUHdWYlXzvRKS925Xxr5yNqA5+qG5H3zaLp/bhDJ+21SJ0eax yrLN+qVOHapPuQmNG2+W/jQf9FukeQsmtt+nffl+tRUL/WZhOWp5VPA48AMePDFpRmBu IhH4Mn3cablLhTxp7742xuaM02BtWEAVloeXlkqqwyd4TeO0h2ruD/B4u8fI8LdYNcog tB9+CbPGmX/wfucunetRmFtsRlhofopNrl6/5Gk48oIO0/tHD/U+fHq/Az3FTuIxH16D a0U1s0394/q9GYZPVMPYzjJytk5Vi4GJO4giTg98PjH6Anw8XJ8RgJAfJXtiyH2umkCg 0MrQ== X-Forwarded-Encrypted: i=1; AKwUvBy5iyAzn6XU12XMqxCzZhcS6NvRvbGUi7Un7sbh5mALmMtO0CA7Sa1A7dn/7dY8vAn3Y+iSE88R3AZL8pA=@vger.kernel.org X-Gm-Message-State: AFuF++nLB/k/mWD2Zf7U0X3/nu1cWZxVuHveCeHpU2wmVE9vP9z8aTrX nhjbpW2cyCMUGHtUgH7UC//eeQMHiqprh0AhnRU2Y4V4GhvNWVTPNY0e1T9TbtJ05H2HRay1ziI Y3FKYFw== X-Received: from pfbdl2.prod.google.com ([2002:a05:6a00:4902:b0:870:7bb4:8565]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:288a:b0:87b:784b:455c with SMTP id d2e1a72fcca58-87b784b5205mr2503863b3a.56.1790036021541; Mon, 21 Sep 2026 17:13:41 -0700 (PDT) Reply-To: Sean Christopherson Date: Mon, 21 Sep 2026 17:13:32 -0700 In-Reply-To: <20260922001332.1121266-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: <20260922001332.1121266-1-seanjc@google.com> X-Mailer: git-send-email 2.55.0.1082.g2b9226bbc0-goog Message-ID: <20260922001332.1121266-7-seanjc@google.com> Subject: [PATCH v5 6/6] KVM: guest_memfd: Drop superfluous WRITE_ONCE() when binding a memslot From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: David Hildenbrand , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Teodorescu , Dennis Tighe , Sashiko Bot , Ackerley Tng , Yan Zhao Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Drop the superfluous WRITE_ONCE() when setting a memslot's guest_memfd file during initial binding, as the memslot *must* be inactive and unreachable. The superfluous WRITE_ONCE() was added by commit 67b43038ce14 ("KVM: guest_memfd: Remove RCU-protected attribute from slot->gmem.file") to maintain rough "parity" with the existing rcu_assign_pointer(), not realizing that the only reason rcu_assign_pointer() was used was to make sparse and other checkers happy. Cc: Yan Zhao Reviewed-by: David Hildenbrand (Arm) Reviewed-by: Ackerley Tng Signed-off-by: Sean Christopherson Reviewed-by: Yan Zhao --- virt/kvm/guest_memfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 80932f4ec4a3..826d26036926 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -677,7 +677,7 @@ int kvm_gmem_prepare_memory_region(struct kvm *kvm, str= uct kvm_memory_slot *slot * kvm_gmem_bind() must occur on a new memslot. Because the memslot * is not visible yet, kvm_gmem_get_pfn() is guaranteed to see the file. */ - WRITE_ONCE(slot->gmem.file, file); + slot->gmem.file =3D file; slot->gmem.pgoff =3D offset >> PAGE_SHIFT; if (kvm_gmem_supports_mmap(inode)) slot->flags |=3D KVM_MEMSLOT_GMEM_ONLY; --=20 2.55.0.1082.g2b9226bbc0-goog