linux/arch/powerpc/mm
Ryan Roberts be0ce3f6ff mm: fix race between __split_huge_pmd_locked() and GUP-fast
commit 3a5a8d343e upstream.

__split_huge_pmd_locked() can be called for a present THP, devmap or
(non-present) migration entry.  It calls pmdp_invalidate() unconditionally
on the pmdp and only determines if it is present or not based on the
returned old pmd.  This is a problem for the migration entry case because
pmd_mkinvalid(), called by pmdp_invalidate() must only be called for a
present pmd.

On arm64 at least, pmd_mkinvalid() will mark the pmd such that any future
call to pmd_present() will return true.  And therefore any lockless
pgtable walker could see the migration entry pmd in this state and start
interpretting the fields as if it were present, leading to BadThings (TM).
GUP-fast appears to be one such lockless pgtable walker.

x86 does not suffer the above problem, but instead pmd_mkinvalid() will
corrupt the offset field of the swap entry within the swap pte.  See link
below for discussion of that problem.

Fix all of this by only calling pmdp_invalidate() for a present pmd.  And
for good measure let's add a warning to all implementations of
pmdp_invalidate[_ad]().  I've manually reviewed all other
pmdp_invalidate[_ad]() call sites and believe all others to be conformant.

This is a theoretical bug found during code review.  I don't have any test
case to trigger it in practice.

Link: https://lkml.kernel.org/r/20240501143310.1381675-1-ryan.roberts@arm.com
Link: https://lore.kernel.org/all/0dd7827a-6334-439a-8fd0-43c98e6af22b@arm.com/
Fixes: 84c3fc4e9c ("mm: thp: check pmd migration entry in common path")
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Cc: Borislav Petkov (AMD) <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2024-06-16 13:47:40 +02:00
..
book3s32 powerpc: replace #include <asm/export.h> with #include <linux/export.h> 2023-08-16 23:54:48 +10:00
book3s64 mm: fix race between __split_huge_pmd_locked() and GUP-fast 2024-06-16 13:47:40 +02:00
kasan powerpc/kasan: Fix addr error caused by page alignment 2024-02-23 09:24:58 +01:00
nohash mm: hugetlb: add huge page size param to set_huge_pte_at() 2023-09-29 17:20:47 -07:00
ptdump powerpc: Remove CONFIG_PPC_BOOK3E_MMU 2022-09-26 23:00:14 +10:00
cacheflush.c powerpc: implement the new page table range API 2023-08-24 16:20:23 -07:00
copro_fault.c powerpc/mm: convert coprocessor fault to lock_mm_and_find_vma() 2023-06-24 14:12:58 -07:00
dma-noncoherent.c dma-mapping: merge <linux/dma-noncoherent.h> into <linux/dma-map-ops.h> 2020-10-06 07:07:06 +02:00
drmem.c powerpc: Add missing headers 2022-05-08 22:15:40 +10:00
fault.c mm: drop per-VMA lock when returning VM_FAULT_RETRY or VM_FAULT_COMPLETED 2023-08-24 16:20:17 -07:00
hugetlbpage.c powerpc/hugetlb: pte_alloc_huge() 2023-06-19 16:19:08 -07:00
init-common.c powerpc/mm: Fix null-pointer dereference in pgtable_cache_add 2024-02-05 20:14:13 +00:00
init_32.c powerpc/kuap: Use MMU_FTR_KUAP on all and refactor disabling kuap 2023-08-02 22:22:18 +10:00
init_64.c powerpc updates for 6.6 2023-08-31 12:43:10 -07:00
ioremap.c powerpc: mm: convert to GENERIC_IOREMAP 2023-08-18 10:12:35 -07:00
ioremap_32.c powerpc: mm: convert to GENERIC_IOREMAP 2023-08-18 10:12:35 -07:00
ioremap_64.c powerpc: mm: convert to GENERIC_IOREMAP 2023-08-18 10:12:35 -07:00
maccess.c powerpc/inst: Optimise copy_inst_from_kernel_nofault() 2021-12-09 22:41:21 +11:00
Makefile powerpc/mm: Convert to default topdown mmap layout 2022-05-05 22:11:58 +10:00
mem.c powerpc/mm: Fix boot crash with FLATMEM 2023-10-23 22:50:15 +11:00
mmu_context.c powerpc: Add mm_cpumask warning when context switching 2023-08-02 22:22:19 +10:00
mmu_decl.h powerpc/64s: Fix CONFIG_NUMA=n build due to create_section_mapping() 2024-02-05 20:14:14 +00:00
numa.c powerpc/pseries: Move VPHN constants into vphn.h 2023-08-24 22:33:16 +10:00
pageattr.c powerpc: align address to page boundary in change_page_attr() 2022-05-08 22:15:41 +10:00
pgtable-frag.c powerpc: convert various functions to use ptdescs 2023-08-21 13:37:54 -07:00
pgtable.c powerpc fixes for 6.6 #6 2023-10-27 05:40:42 -10:00
pgtable_32.c powerpc: move __end_rodata to cover arch read-only sections 2022-09-26 20:58:16 +10:00
pgtable_64.c powerpc: Remove asm/prom.h from all files that don't need it 2022-05-08 22:15:04 +10:00