Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bd6964c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 mm changes from Ingo Molnar:
 "A cleanup, a fix and ASLR support for hugetlb mappings"

* 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm/numa: Fix 32-bit kernel NUMA boot
  x86/mm: Implement ASLR for hugetlb mappings
  x86/mm: Unify pte_to_pgoff() and pgoff_to_pte() helpers
parents 2bb2c5e2 f3d815cb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ extern bool __virt_addr_valid(unsigned long kaddr);
#include <asm-generic/getorder.h>

#define __HAVE_ARCH_GATE_AREA 1
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA

#endif	/* __KERNEL__ */
#endif /* _ASM_X86_PAGE_H */
+0 −4
Original line number Diff line number Diff line
@@ -5,10 +5,6 @@

#ifndef __ASSEMBLY__

#ifdef CONFIG_HUGETLB_PAGE
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#endif

#define __phys_addr_nodebug(x)	((x) - PAGE_OFFSET)
#ifdef CONFIG_DEBUG_VIRTUAL
extern unsigned long __phys_addr(unsigned long);
+59 −41
Original line number Diff line number Diff line
@@ -55,6 +55,13 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
#define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
#endif

/* Bit manipulation helper on pte/pgoff entry */
static inline unsigned long pte_bitop(unsigned long value, unsigned int rightshift,
				      unsigned long mask, unsigned int leftshift)
{
	return ((value >> rightshift) & mask) << leftshift;
}

#ifdef CONFIG_MEM_SOFT_DIRTY

/*
@@ -71,31 +78,34 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
#define PTE_FILE_BITS2		(PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1)
#define PTE_FILE_BITS3		(PTE_FILE_SHIFT4 - PTE_FILE_SHIFT3 - 1)

#define pte_to_pgoff(pte)						\
	((((pte).pte_low >> (PTE_FILE_SHIFT1))				\
	  & ((1U << PTE_FILE_BITS1) - 1)))				\
	+ ((((pte).pte_low >> (PTE_FILE_SHIFT2))			\
	    & ((1U << PTE_FILE_BITS2) - 1))				\
	   << (PTE_FILE_BITS1))						\
	+ ((((pte).pte_low >> (PTE_FILE_SHIFT3))			\
	    & ((1U << PTE_FILE_BITS3) - 1))				\
	   << (PTE_FILE_BITS1 + PTE_FILE_BITS2))			\
	+ ((((pte).pte_low >> (PTE_FILE_SHIFT4)))			\
	    << (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3))

#define pgoff_to_pte(off)						\
	((pte_t) { .pte_low =						\
	 ((((off)) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)	\
	 + ((((off) >> PTE_FILE_BITS1)					\
	     & ((1U << PTE_FILE_BITS2) - 1))				\
	    << PTE_FILE_SHIFT2)						\
	 + ((((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))		\
	     & ((1U << PTE_FILE_BITS3) - 1))				\
	    << PTE_FILE_SHIFT3)						\
	 + ((((off) >>							\
	      (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)))	\
	    << PTE_FILE_SHIFT4)						\
	 + _PAGE_FILE })
#define PTE_FILE_MASK1		((1U << PTE_FILE_BITS1) - 1)
#define PTE_FILE_MASK2		((1U << PTE_FILE_BITS2) - 1)
#define PTE_FILE_MASK3		((1U << PTE_FILE_BITS3) - 1)

#define PTE_FILE_LSHIFT2	(PTE_FILE_BITS1)
#define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2)
#define PTE_FILE_LSHIFT4	(PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)

static __always_inline pgoff_t pte_to_pgoff(pte_t pte)
{
	return (pgoff_t)
		(pte_bitop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)		    +
		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) +
		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT3, PTE_FILE_MASK3,  PTE_FILE_LSHIFT3) +
		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT4,           -1UL,  PTE_FILE_LSHIFT4));
}

static __always_inline pte_t pgoff_to_pte(pgoff_t off)
{
	return (pte_t){
		.pte_low =
			pte_bitop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) +
			pte_bitop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) +
			pte_bitop(off, PTE_FILE_LSHIFT3, PTE_FILE_MASK3,  PTE_FILE_SHIFT3) +
			pte_bitop(off, PTE_FILE_LSHIFT4,           -1UL,  PTE_FILE_SHIFT4) +
			_PAGE_FILE,
	};
}

#else /* CONFIG_MEM_SOFT_DIRTY */

@@ -115,22 +125,30 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
#define PTE_FILE_BITS1		(PTE_FILE_SHIFT2 - PTE_FILE_SHIFT1 - 1)
#define PTE_FILE_BITS2		(PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1)

#define pte_to_pgoff(pte)						\
	((((pte).pte_low >> PTE_FILE_SHIFT1)				\
	  & ((1U << PTE_FILE_BITS1) - 1))				\
	 + ((((pte).pte_low >> PTE_FILE_SHIFT2)				\
	     & ((1U << PTE_FILE_BITS2) - 1)) << PTE_FILE_BITS1)		\
	 + (((pte).pte_low >> PTE_FILE_SHIFT3)				\
	    << (PTE_FILE_BITS1 + PTE_FILE_BITS2)))

#define pgoff_to_pte(off)						\
	((pte_t) { .pte_low =						\
	 (((off) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)	\
	 + ((((off) >> PTE_FILE_BITS1) & ((1U << PTE_FILE_BITS2) - 1))	\
	    << PTE_FILE_SHIFT2)						\
	 + (((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))		\
	    << PTE_FILE_SHIFT3)						\
	 + _PAGE_FILE })
#define PTE_FILE_MASK1		((1U << PTE_FILE_BITS1) - 1)
#define PTE_FILE_MASK2		((1U << PTE_FILE_BITS2) - 1)

#define PTE_FILE_LSHIFT2	(PTE_FILE_BITS1)
#define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2)

static __always_inline pgoff_t pte_to_pgoff(pte_t pte)
{
	return (pgoff_t)
		(pte_bitop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)		    +
		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) +
		 pte_bitop(pte.pte_low, PTE_FILE_SHIFT3,           -1UL,  PTE_FILE_LSHIFT3));
}

static __always_inline pte_t pgoff_to_pte(pgoff_t off)
{
	return (pte_t){
		.pte_low =
			pte_bitop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) +
			pte_bitop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) +
			pte_bitop(off, PTE_FILE_LSHIFT3,           -1UL,  PTE_FILE_SHIFT3) +
			_PAGE_FILE,
	};
}

#endif /* CONFIG_MEM_SOFT_DIRTY */

+3 −6
Original line number Diff line number Diff line
@@ -87,9 +87,7 @@ int pmd_huge_support(void)
}
#endif

/* x86_64 also uses this file */

#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#ifdef CONFIG_HUGETLB_PAGE
static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
		unsigned long addr, unsigned long len,
		unsigned long pgoff, unsigned long flags)
@@ -99,7 +97,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,

	info.flags = 0;
	info.length = len;
	info.low_limit = TASK_UNMAPPED_BASE;
	info.low_limit = current->mm->mmap_legacy_base;
	info.high_limit = TASK_SIZE;
	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
	info.align_offset = 0;
@@ -172,8 +170,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
		return hugetlb_get_unmapped_area_topdown(file, addr, len,
				pgoff, flags);
}

#endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
#endif /* CONFIG_HUGETLB_PAGE */

#ifdef CONFIG_X86_64
static __init int setup_hugepagesz(char *opt)
+7 −3
Original line number Diff line number Diff line
@@ -210,11 +210,15 @@ static void __init setup_node_data(int nid, u64 start, u64 end)
	 * Never allocate in DMA zone.
	 */
	nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
	if (!nd_pa) {
		nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
					      MEMBLOCK_ALLOC_ACCESSIBLE);
		if (!nd_pa) {
			pr_err("Cannot find %zu bytes in node %d\n",
			       nd_size, nid);
			return;
		}
	}
	nd = __va(nd_pa);

	/* report and initialize */