From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.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 9248E33F5B2 for ; Sun, 26 Jul 2026 22:23:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.72 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785104603; cv=none; b=Fmu0USQhq7d3cbaKmJrtfp/qHxZ62fIVOdvwf9AondhJ0Q8Q33SyMXADtKQ7zd2dzRm7kZSMBb+UQKQG7v91nihhjxJeJLIIU9cWzn9W3Bj8GYTwRsmM/eekFJuhlu1X1EK/d8oYw4R7w3dRE8A4A1Pwed9xePMrChrKliQ+3Sg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785104603; c=relaxed/simple; bh=G0G1cB2Av495vT1j00Ag6utIJ7aDJcy+GEqeTmmewws=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=quEiBKSlrQj0YYxQ8mbFE0sDjElfnjUcZhdvtxrlB3Fy66D1+M1cQ+DbajngOIBBIgQBkXvdK2EqQ0UJSk7smbRe+DejFrP3x+ru9yaKZOu8J6KVWKWpJBrwEIRXZ8vRkxpgMNvF9O9zBKOzkAbXDqg0xIPAqyhb72F6FrqUSME= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jackmanb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=i8vctpzB; arc=none smtp.client-ip=209.85.221.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--jackmanb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="i8vctpzB" Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-47f835ac1aeso1303853f8f.3 for ; Sun, 26 Jul 2026 15:23:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785104600; x=1785709400; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Xln7DlQ/Erzs4SFfLWkI0/3SV9SUpyYGCbY4YNaEuz4=; b=i8vctpzBJCCQtqLEToul7WEm+A0YQPvjGR9VFNHH4CVnasqfQy/gu4Qbd7gNksFDNT QFtppzuF600lTBv/K2m0aSrQVRQn6lXlXisqt4tgmwHCz+NG7zObP8KBXPxB7D0L+oKN +mfZdzm3jSKjsMZke+OTrKszhFnvS92OigtXvVAiCj99zYA5FVewW2J9vjWx3fwSOys+ kVd+pKWiSwmCGIbly7dqS682W01d4Hk+sCo0CUKiPxD/maQW92G8cEw3i7kUvNgwE2vI byC7uerb/lFWZipobSa3/ErQPsnIF8IcnQ0a2f6Tj8hgUtFazo8sVoduAtHjzx3PndHx mOZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785104600; x=1785709400; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Xln7DlQ/Erzs4SFfLWkI0/3SV9SUpyYGCbY4YNaEuz4=; b=Xvnd8SoR2xle2s9cT0uE6btW3jWqBFMtFrCrICL791JtxIE6M1iBgI6EssfvkmW+gU +NXp6fuKjZJZdlWIQh8kp8bVLYUwS1HQQd6wZ5Uduc5wZcz9V7HUK3qfO2A37Eg7HabM 84M0XoouCA0aMoSJ+yL5uxI7KBPdnJc9Jmc/lZjyJypc3YrGND9tbfcQIWzj4lAWNH5T v0g/PGgtJUVyywX7bCFpBWBSTYrzF0VOrdw52e82WgRpMf2ppEB4reyo2FE1+CGEXtoc WrkndkS1Ez37ZH9r9v8Hte8793z2cLy78UaSTpphOQbzYeM3IYoX59LrKCDXr3ac2otc lOXQ== X-Forwarded-Encrypted: i=1; AHgh+RrYxgWVCoD0/kq7DFEuYxNYq8ZHXWkoATKCiJh8fDcv12flU8SdMzkxGjLfTZNdMdr2NdYXafMv9Danayg=@vger.kernel.org X-Gm-Message-State: AOJu0YzHxXUiCYnBscwDdOP/VovCbu28wt/jAwX75A1IrFkHfkHYBBLv Y1+r6mXulW+evrPYuNN8B84kNbwlVFUstM79dwepyTvA93/owLfN5MD+InfkEopBHNryg0oRG3z fRu7Df3TCAj+Apw== X-Received: from wmbju21.prod.google.com ([2002:a05:600c:56d5:b0:493:c2c9:129b]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b20:b0:495:4a34:16e3 with SMTP id 5b1f17b1804b1-496b56f0fc4mr100656295e9.1.1785104599743; Sun, 26 Jul 2026 15:23:19 -0700 (PDT) Date: Sun, 26 Jul 2026 22:22:34 +0000 In-Reply-To: <20260726-page_alloc-unmapped-v3-0-6f5729aa9832@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260726-page_alloc-unmapped-v3-0-6f5729aa9832@google.com> X-Mailer: b4 0.16-dev Message-ID: <20260726-page_alloc-unmapped-v3-1-6f5729aa9832@google.com> Subject: [PATCH v3 01/26] set_memory: add folio_{zap,restore}_direct_map helpers From: Brendan Jackman To: Borislav Petkov , Dave Hansen , Peter Zijlstra , Andrew Morton , David Hildenbrand , Vlastimil Babka , Mike Rapoport , Wei Xu , Johannes Weiner , Zi Yan , Lorenzo Stoakes Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, x86@kernel.org, rppt@kernel.org, Sumit Garg , Will Deacon , rientjes@google.com, "Kalyazin, Nikita" , patrick.roy@linux.dev, "Itazuri, Takahiro" , Andy Lutomirski , David Kaplan , Thomas Gleixner , Yosry Ahmed , Patrick Bellasi , Reiji Watanabe , Sean Christopherson , Brendan Jackman , Nikita Kalyazin Content-Type: text/plain; charset="utf-8" From: Nikita Kalyazin Let's provide folio_{zap,restore}_direct_map helpers as preparation for supporting removal of the direct map for guest_memfd folios. In folio_zap_direct_map(), flush TLB to make sure the data is not accessible. On some architectures, there may be a double TLB flush issued because set_direct_map_valid_noflush already performs a flush internally. The new helpers need to be accessible to KVM on architectures that support guest_memfd (x86 and arm64). Direct map removal gives guest_memfd the same protection that memfd_secret does, such as hardening against Spectre-like attacks through in-kernel gadgets. Acked-by: David Hildenbrand (Arm) Signed-off-by: Nikita Kalyazin [Added comment, dropped modified set_direct_map API, added highmem check] Signed-off-by: Brendan Jackman --- include/linux/set_memory.h | 13 +++++++++++++ mm/memory.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h index 3030d9245f5ac..1bf2a15bca118 100644 --- a/include/linux/set_memory.h +++ b/include/linux/set_memory.h @@ -40,6 +40,15 @@ static inline int set_direct_map_valid_noflush(struct page *page, return 0; } +static inline int folio_zap_direct_map(struct folio *folio) +{ + return 0; +} + +static inline void folio_restore_direct_map(struct folio *folio) +{ +} + static inline bool kernel_page_present(struct page *page) { return true; @@ -56,6 +65,10 @@ static inline bool can_set_direct_map(void) } #define can_set_direct_map can_set_direct_map #endif + +int folio_zap_direct_map(struct folio *folio); +void folio_restore_direct_map(struct folio *folio); + #endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */ #ifdef CONFIG_X86_64 diff --git a/mm/memory.c b/mm/memory.c index a73af1fccb3d0..789c65a6d6a0e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -78,6 +78,7 @@ #include #include #include +#include #include @@ -7758,3 +7759,48 @@ void vma_pgtable_walk_end(struct vm_area_struct *vma) if (is_vm_hugetlb_page(vma)) hugetlb_vma_unlock_read(vma); } + +#ifdef CONFIG_ARCH_HAS_SET_DIRECT_MAP +/** + * folio_zap_direct_map - remove a folio from the kernel direct map + * @folio: folio to remove from the direct map + * + * Removes the folio from the kernel direct map and flushes the TLB. This may + * require splitting huge pages in the direct map, which can fail due to memory + * allocation. So far, only order-0 folios are supported; this guarantees + * the unmap is either a complete success or a total failure. + * + * Return: 0 on success, or a negative error code on failure. + */ +int folio_zap_direct_map(struct folio *folio) +{ + struct page *page = folio_page(folio, 0); + unsigned long addr = (unsigned long)page_address(page); + int ret; + + if (folio_test_large(folio) || folio_test_highmem(folio)) + return -EINVAL; + + ret = set_direct_map_valid_noflush(page, 1, false); + flush_tlb_kernel_range(addr, addr + folio_size(folio)); + + return ret; +} +EXPORT_SYMBOL_FOR_MODULES(folio_zap_direct_map, "kvm"); + +/** + * folio_restore_direct_map - restore the kernel direct map entry for a folio + * @folio: folio whose direct map entry is to be restored + * + * This may only be called after a prior successful folio_zap_direct_map() on + * the same folio. Because the zap will have already split any huge pages in + * the direct map, restoration here only updates protection bits and cannot + * fail. + */ +void folio_restore_direct_map(struct folio *folio) +{ + WARN_ON_ONCE(set_direct_map_valid_noflush(folio_page(folio, 0), + folio_nr_pages(folio), true)); +} +EXPORT_SYMBOL_FOR_MODULES(folio_restore_direct_map, "kvm"); +#endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */ -- 2.54.0