linux/arch/x86/mm
Andy Lutomirski 530dd8d4b9 x86/mm/cpa: Fix populate_pgd(): Stop trying to deallocate failed PUDs
Valdis Kletnieks bisected a boot failure back to this recent commit:

  360cb4d155 ("x86/mm/cpa: In populate_pgd(), don't set the PGD entry until it's populated")

I broke the case where a PUD table got allocated -- populate_pud()
would wander off a pgd_none entry and get lost.  I'm not sure how
this survived my testing.

Fix the original issue in a much simpler way.  The problem
was that, if we allocated a PUD table, failed to populate it, and
freed it, another CPU could potentially keep using the PGD entry we
installed (either by copying it via vmalloc_fault or by speculatively
caching it).  There's a straightforward fix: simply leave the
top-level entry in place if this happens.  This can't waste any
significant amount of memory -- there are at most 256 entries like
this systemwide and, as a practical matter, if we hit this failure
path repeatedly, we're likely to reuse the same page anyway.

For context, this is a reversion with this hunk added in:

	if (ret < 0) {
+		/*
+		 * Leave the PUD page in place in case some other CPU or thread
+		 * already found it, but remove any useless entries we just
+		 * added to it.
+		 */
-		unmap_pgd_range(cpa->pgd, addr,
+		unmap_pud_range(pgd_entry, addr,
			        addr + (cpa->numpages << PAGE_SHIFT));
		return ret;
	}

This effectively open-codes what the now-deleted unmap_pgd_range()
function used to do except that unmap_pgd_range() used to try to
free the page as well.

Reported-by: Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Luis R. Rodriguez <mcgrof@suse.com>
Cc: Mike Krinkin <krinkin.m.u@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Toshi Kani <toshi.kani@hp.com>
Link: http://lkml.kernel.org/r/21cbc2822aa18aa812c0215f4231dbf5f65afa7f.1469249789.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2016-07-23 21:13:25 +02:00
..
kmemcheck
amdtopology.c
debug_pagetables.c x86/mm/ptdump: Make (debugfs)/kernel_page_tables read-only 2015-12-04 12:55:01 +01:00
dump_pagetables.c x86/mm/ptdump: Remove paravirt_enabled() 2016-02-20 12:25:45 +01:00
extable.c x86/uaccess: Move thread_info::uaccess_err and thread_info::sig_on_uaccess_err to thread_struct 2016-07-15 10:26:28 +02:00
fault.c x86/dumpstack: Rename thread_struct::sig_on_uaccess_error to sig_on_uaccess_err 2016-07-15 10:26:29 +02:00
gup.c Merge branch 'mm-pkeys-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-03-20 19:08:56 -07:00
highmem_32.c
hugetlbpage.c x86: mm: use hugetlb_bad_size() 2016-05-19 19:12:14 -07:00
ident_map.c x86/boot: Add missing file header comments 2016-05-10 10:12:03 +02:00
init_32.c Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-05-16 15:54:01 -07:00
init_64.c x86/mm/hotplug: Don't remove PGD entries in remove_pagetable() 2016-07-15 10:26:24 +02:00
init.c x86/cpufeature: Remove cpu_has_pse 2016-03-31 13:35:10 +02:00
iomap_32.c
ioremap.c x86/cpufeature: Remove cpu_has_pse 2016-03-31 13:35:10 +02:00
kasan_init_64.c x86/kasan: Write protect kasan zero shadow 2016-02-09 13:33:14 +01:00
kmmio.c x86/mm/kmmio: Fix mmiotrace for hugepages 2016-03-05 13:24:41 +01:00
Makefile x86/mm: Build arch/x86/mm/tlb.c even on !SMP 2016-04-28 11:44:19 +02:00
mm_internal.h
mmap.c Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-03-15 10:45:39 -07:00
mmio-mod.c
mpx.c Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2016-03-24 09:47:32 -07:00
numa_32.c
numa_64.c
numa_emulation.c
numa_internal.h
numa.c include/linux/nodemask.h: create next_node_in() helper 2016-05-19 19:12:14 -07:00
pageattr-test.c
pageattr.c x86/mm/cpa: Fix populate_pgd(): Stop trying to deallocate failed PUDs 2016-07-23 21:13:25 +02:00
pat_internal.h
pat_rbtree.c x86/mm/pat: Change free_memtype() to support shrinking case 2016-01-05 11:10:23 +01:00
pat.c x86/mm/pat, /dev/mem: Remove superfluous error message 2016-07-08 11:52:58 +02:00
pf_in.c
pf_in.h
pgtable_32.c x86/mm: Use pte_none() to test for empty PTE 2016-07-13 09:43:25 +02:00
pgtable.c x86: get rid of superfluous __GFP_REPEAT 2016-06-24 17:23:52 -07:00
physaddr.c
physaddr.h
pkeys.c mm/core, x86/mm/pkeys: Add execute-only protection keys support 2016-02-18 19:46:33 +01:00
setup_nx.c Revert "x86/mm/32: Set NX in __supported_pte_mask before enabling paging" 2016-04-26 19:52:57 +02:00
srat.c x86/mm: Introduce max_possible_pfn 2015-12-06 12:46:31 +01:00
testmmiotrace.c
tlb.c x86/mm, sched/core: Turn off IRQs in switch_mm() 2016-04-28 11:44:20 +02:00