From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (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 446E433E355 for ; Mon, 22 Jun 2026 23:54:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=209.85.218.50 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782172462; cv=pass; b=NgQKKbIJfI/1QxtD83iUznwQnLGd6hK5Q1mmVZk6bi9FoIimqnF0AjhkzFfpHFyhczRN0AkDgW46tPQfODI6fNOnQSASNZwKo+qMH5rZfP7Opxvp5h74Vl8iuAm2TUgQj8RX7kugXazGFTsfSkKyqe71klBVoXcikQsuv7Upok4= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782172462; c=relaxed/simple; bh=I1YUlMWYpoFKoByVcCt8Rqs1cgeontbmcE6KLy6U/tc=; h=From:In-Reply-To:References:MIME-Version:Date:Message-ID:Subject: To:Cc:Content-Type; b=o+F8v1pf7itIcmEZDzN8zUaQ9VJlbgwcVFjr6AuYuwzONkw/R6ulzN/i/WnabxwS3gJA0plXhNEaLuiBTtj+tWvtcsBcMQ9c9QxuMzyiiOu72jX+ttrNtGxRgnvhd54xteth8amAtFXocXtBoYwevqARtw6SLjKM44eAze79KDU= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=jPsTpHfr; arc=pass smtp.client-ip=209.85.218.50 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=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="jPsTpHfr" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-c07ea058c0cso828418066b.2 for ; Mon, 22 Jun 2026 16:54:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1782172459; cv=none; d=google.com; s=arc-20240605; b=NHS+0IIqkI8mMe8Q5Yw+yUvODLj6a9pTAhcUVby3PqyZ/gEN/CUFjnjGwXeAT+eAdZ xLNihpXC5O5QCw12LgMSEXJ/PGAg2Pw23nOJWOCQBxedprbKlzsuBRYZJqmejjkERRoE 7f7NAm7Mg43FkhkuKotX5sXmgJGNSs1C+f7rIYx/J5f8k66CKqGRm1/vI9BAemLhegaY LPrPdc4Y5iJaRt9jzOeu+VY4EwyfJs0x8NSE4wvBDbBJqveDe79cqO8u6LCQGbpr0Yye GJLG7gIjF4XyfsKDbo6M8YAahzUjsFAJhnGqrPPIZpGJXLvSGcQv40mqXQMt2Q+ZeO5l rg2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:mime-version:references:in-reply-to :from:dkim-signature; bh=mnhxRL5NSWx2qm5cF+jOJULziDkVFS523GcKtm3BW0s=; fh=FgEiYRUlcV7GZZgVCCHqWZItFaIIqDn76U+d6lvC1Y0=; b=WjHN8Ka4SZClTvzcj6StjNhTgyw3ma6YpiqLLWqLrhrqK2pf9qM5Xn82hrofSVxZoZ T0jlu18xjKFzD7ryLYy5PmsToqWZz+ZOKjIVBYvjN/YcHs1D6H1HsAeiwSFbvEd4Hczh p+GfY8bkUyGXWLeP+jADWbvivBfKr8l7kPMeGxRRv4AsCKvGntDVFlXEvn0pqL0OSnnM ZusFFlk0C75LkKuLcyzjOUaLoGMwfOINqKPJEdele/U/tAGv/bkEtJi/L7Moesn1ciMd 6JAskOEkb4l0yPZtU8hHf+xf5khAeHitAZGzb8YEZtaPu1lxDGP0+Nro922irErrBRGD JkLA==; darn=vger.kernel.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1782172459; x=1782777259; darn=vger.kernel.org; h=cc:to:subject:message-id:date:mime-version:references:in-reply-to :from:from:to:cc:subject:date:message-id:reply-to; bh=mnhxRL5NSWx2qm5cF+jOJULziDkVFS523GcKtm3BW0s=; b=jPsTpHfrfh5ppMR+gyIUraMIwJm/OYLJsOd3N6OB9vvTjThH38ksYWY8D2FkYROTyT ZgSscTWoUdDnsJQqcFcC/PUIqjc+4bmZymQRLfc0ygApUzPtlp0kouCgEcRg7wTXtuov ubH5HACVSgpKbL6ZBAosYe5cg3G+ndkWDi0S5sNXeff0DrhdbBd5SnvLvSCP1ix0N8Bp 7v2sUOKQ7v9//5QbDiEfzd8xgU7FGkmplZdLsYMwI7oEvh2uz/O0tI6/btHYt+nyrl38 9Vxnt0A9w3JRt6Yr2k/5pM4l8AqrMV4PPjvsAi7U01/bXYcy4/tk6rrgZfHbYlJV1cQ1 v2Ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782172459; x=1782777259; h=cc:to:subject:message-id:date:mime-version:references:in-reply-to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=mnhxRL5NSWx2qm5cF+jOJULziDkVFS523GcKtm3BW0s=; b=NuLTovSvbhoV2D1g9QvT+VGNh7yMzonB42fblrnE530jK2PKLBt1T9kd+SlMM9Ioy7 8Rr6jbqzqeb0O1KEZvucOu57ShkKpWPYdxmDWi3KE6cN3xTaHPPzhsR9LLk/qSdD9TfC qWe/OW9tiwkItVwMy3+U5f5DUjI+JEC/KKf2mP2aZe0YuSVgwRf1/rgfcAuP6X1YGJf8 2/5FMy3FXaib2cuofiD/IHJAdHQfjA0mUXjdyqTqJp6n2HxILYJ+OavDErvafLeAFdxA AvmPnzKSCbZsAzjJRs0X949IvVMQbxEWLeSKtvA8EGAFhVFK4W2P6bvHVrQSoVlhK0DE tqeA== X-Forwarded-Encrypted: i=1; AFNElJ9oYjmbZ1fVp/7R8aurb6s53tUp9OZASc/4EOKMHrN/jaTFjA4t5VDsClx8fwnYW1Sf0GzCPznycrD18Aw=@vger.kernel.org X-Gm-Message-State: AOJu0YxoedfdmC4sWizN1zPKpKHnD6j3I+SJB+o/RSZFHqNomKSwDz19 903jr17VYV8+TjGiWMUa5nuUgixXU/q+ssvy2YkR2y8FY6liNpnM30g52om/eR49vdN/8tw7czo JGJFy3Q94ObNiPhlJvHg+QTI5hvQBLWjRsJjP8gGQ X-Gm-Gg: AfdE7clZZXTNvsQfP1P7Y33DFNc6IW/Gcn/qh12lFv75SA+rk96nYrPY6OYpgPaPHv9 +lR1sx4WV0DxfCqvsMi0/5BS3MrrkCtsO1/8FLGxO2ly74nhtS9vjtDeM8faISfK8GU1zFORa6M K4Z2MP2EXkl10Skcv3sokoT3cd6Fa8XfAjWKo9SNpwx1u57f/djhfehRjzWcntWOUsFNqMB7aNK 42HBJzU04PM1mK/slneYcsKSYrRTg8IHf1H9lOQ4M6jGR9ZsF4FP7fX5m4620pdlReyzM+0FBPr Yvo16x5e/rNCVHjunAfmbN1yYNDUqbf1Dz1Yp1t+x6mHdEEADjWgXi1z6Go= X-Received: by 2002:a17:907:a394:b0:c10:1041:65a4 with SMTP id a640c23a62f3a-c1080b8e977mr13124066b.42.1782172458193; Mon, 22 Jun 2026 16:54:18 -0700 (PDT) Received: from 176938342045 named unknown by gmailapi.google.com with HTTPREST; Mon, 22 Jun 2026 16:54:15 -0700 Received: from 176938342045 named unknown by gmailapi.google.com with HTTPREST; Mon, 22 Jun 2026 16:54:15 -0700 From: Ackerley Tng In-Reply-To: <48777f4749fa43d5648085dbb2037aa99c144a88.1780676742.git.tarunsahu@google.com> References: <48777f4749fa43d5648085dbb2037aa99c144a88.1780676742.git.tarunsahu@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Mon, 22 Jun 2026 16:54:15 -0700 X-Gm-Features: AVVi8Cc74PEpV2YXCZJIskraOwZy9-czhUt_HBd1DYeN4YnAJwWFzkRCg6GbGig Message-ID: Subject: Re: [RFC PATCH v2 06/10] kvm: guest_memfd: Add support for freezing and unfreezing mappings To: Tarun Sahu , Jonathan Corbet , vannapurve@google.com, fvdl@google.com, Pasha Tatashin , Shuah Khan , sagis@google.com, aneesh.kumar@kernel.org, skhawaja@google.com, vipinsh@google.com, Pratyush Yadav , david@redhat.com, dmatlack@google.com, mark.rutland@arm.com, Paolo Bonzini , Mike Rapoport , Alexander Graf , seanjc@google.com, axelrasmussen@google.com Cc: linux-kselftest@vger.kernel.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, kvm@vger.kernel.org, linux-mm@kvack.org Content-Type: text/plain; charset="UTF-8" Tarun Sahu writes: > This patch introduces the freeze on gmem_inode which prevents Can't find the reference now, but commit messages should take the imperative mood and avoid "this patch" [*] [*] https://lore.kernel.org/all/YKRWNaqzo4GVDxHP@google.com/ > the fallocate call and any new page fault allocation. This will avoid > gmem file modification when it is being preserved > > Used srcu lock to synchronise the freeze call, where write blocks > until all the reads are free. And reads are re-entrant. > > Incase fault fails, It return -EPERM and VM_EXIT to userspace. userspace > must handle this properly as every new fault will fail. > > Signed-off-by: Tarun Sahu > > [...snip...] > > @@ -105,12 +108,20 @@ static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) > if (!IS_ERR(folio)) > return folio; > > + idx = srcu_read_lock(&kvm_gmem_freeze_srcu); > + if (kvm_gmem_is_frozen(inode)) { > + srcu_read_unlock(&kvm_gmem_freeze_srcu, idx); > + return ERR_PTR(-EPERM); > + } > + > policy = mpol_shared_policy_lookup(&GMEM_I(inode)->policy, index); > folio = __filemap_get_folio_mpol(inode->i_mapping, index, > FGP_LOCK | FGP_CREAT, > mapping_gfp_mask(inode->i_mapping), policy); > mpol_cond_put(policy); > > + srcu_read_unlock(&kvm_gmem_freeze_srcu, idx); > + > /* > * External interfaces like kvm_gmem_get_pfn() support dealing > * with hugepages to a degree, but internally, guest_memfd currently > @@ -273,16 +284,30 @@ static long kvm_gmem_allocate(struct inode *inode, loff_t offset, loff_t len) > static long kvm_gmem_fallocate(struct file *file, int mode, loff_t offset, > loff_t len) > { > + struct inode *inode = file_inode(file); > int ret; > + int idx; > > - if (!(mode & FALLOC_FL_KEEP_SIZE)) > - return -EOPNOTSUPP; > + idx = srcu_read_lock(&kvm_gmem_freeze_srcu); > + if (kvm_gmem_is_frozen(inode)) { > + srcu_read_unlock(&kvm_gmem_freeze_srcu, idx); > + return -EPERM; > + } fallocate may eventually go to kvm_gmem_get_folio(), so that would check kvm_gmem_is_frozen() twice. Is this meant to catch the punch hole case? > > - if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) > - return -EOPNOTSUPP; > + if (!(mode & FALLOC_FL_KEEP_SIZE)) { > + ret = -EOPNOTSUPP; > + goto out; > + } > > - if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len)) > - return -EINVAL; > + if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) { > + ret = -EOPNOTSUPP; > + goto out; > + } > + > + if (!PAGE_ALIGNED(offset) || !PAGE_ALIGNED(len)) { > + ret = -EINVAL; > + goto out; > + } There's some reordering here. Why not let the validation happen like before, then check kvm_gmem_is_frozen()? > > if (mode & FALLOC_FL_PUNCH_HOLE) > ret = kvm_gmem_punch_hole(file_inode(file), offset, len); > > [...snip...] > > + > +/** > + * kvm_gmem_freeze - Freeze or unfreeze a guest_memfd inode mapping. > + * @inode: The guest_memfd inode. > + * @freeze: True to freeze, false to unfreeze. > + * > + * This API is used strictly during the live update / preservation transition > + * window to prevent host userspace and guest-side faults from making any > + * mapping modifications (such as fallocate or page fault allocation) > + * to the guest_memfd page cache. > + * > + * Synchronization Strategy (Sleepable RCU): > + * To avoid high-contention VFS locks (like inode_lock or > + * filemap_invalidate_lock) on the vCPU page fault hot paths, this subsystem > + * implements a lightweight, system-wide Sleepable RCU (SRCU) mechanism > + * (`kvm_gmem_freeze_srcu`): > + * > + * Global vs. Per-Inode SRCU > + * ====================== > + * A single system-wide global static `srcu_struct` is used instead of a > + * per-inode SRCU structure to completely prevent unprivileged users from > + * exhausting the host's per-CPU memory allocator. Because > + * `init_srcu_struct()` allocates per-CPU memory via `alloc_percpu()`, which > + * is not accounted by memory cgroups (memcg), > + * a per-inode SRCU structure would allow a tenant to bypass cgroup limits and > + * trigger a system-wide Out-of-Memory (OOM) crash simply by spawning a large > + * number of guest_memfd file descriptors (bounded only by RLIMIT_NOFILE). > + * > + * Flag Modification Note: > + * Since `GUEST_MEMFD_F_MAPPING_FROZEN` is the ONLY flag in > + * `GMEM_I(inode)->flags` that is mutated dynamically at runtime (all other > + * flags are creation-time flags which remain strictly read-only), there is > + * no possibility of concurrent bit-modification races. Therefore, a standard > + * `WRITE_ONCE` is fully safe and does not require complex `cmpxchg` > + * synchronization loops. > + */ > +void kvm_gmem_freeze(struct inode *inode, bool freeze) > +{ > + u64 flags = READ_ONCE(GMEM_I(inode)->flags); > + > + if (freeze) > + flags |= GUEST_MEMFD_F_MAPPING_FROZEN; > + else > + flags &= ~GUEST_MEMFD_F_MAPPING_FROZEN; > + > + WRITE_ONCE(GMEM_I(inode)->flags, flags); > + > + if (freeze) > + synchronize_srcu(&kvm_gmem_freeze_srcu); Why only synchronize on freeze but not unfreeze? > +} > + > > [...snip...] >