Commit 51efd086 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'x86_mm_for_7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 mm updates from Dave Hansen:

 - Convert x86 code to use generic "pagetable" APIs and ptdescs

   This aligns some the set_memory*() code better with the new page
   table APIs, especially using ptdescs as opposed to 'struct page'
   directly.

* tag 'x86_mm_for_7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm/pat: Convert split_large_page() to use ptdescs
  x86/mm/pat: Convert populate_pgd() to use page table apis
  x86/mm/pat: Convert pmd code to use page table apis
  x86/mm/pat: Convert pte code to use page table apis
parents 9f2bb6c7 e751303e
Loading
Loading
Loading
Loading
+25 −12
Original line number Diff line number Diff line
@@ -1119,9 +1119,10 @@ static void split_set_pte(struct cpa_data *cpa, pte_t *pte, unsigned long pfn,

static int
__split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
		   struct page *base)
		   struct ptdesc *ptdesc)
{
	unsigned long lpaddr, lpinc, ref_pfn, pfn, pfninc = 1;
	struct page *base = ptdesc_page(ptdesc);
	pte_t *pbase = (pte_t *)page_address(base);
	unsigned int i, level;
	pgprot_t ref_prot;
@@ -1226,18 +1227,18 @@ __split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
static int split_large_page(struct cpa_data *cpa, pte_t *kpte,
			    unsigned long address)
{
	struct page *base;
	struct ptdesc *ptdesc;

	if (!debug_pagealloc_enabled())
		spin_unlock(&cpa_lock);
	base = alloc_pages(GFP_KERNEL, 0);
	ptdesc = pagetable_alloc(GFP_KERNEL, 0);
	if (!debug_pagealloc_enabled())
		spin_lock(&cpa_lock);
	if (!base)
	if (!ptdesc)
		return -ENOMEM;

	if (__split_large_page(cpa, kpte, address, base))
		__free_page(base);
	if (__split_large_page(cpa, kpte, address, ptdesc))
		pagetable_free(ptdesc);

	return 0;
}
@@ -1408,7 +1409,7 @@ static bool try_to_free_pte_page(pte_t *pte)
		if (!pte_none(pte[i]))
			return false;

	free_page((unsigned long)pte);
	pte_free_kernel(&init_mm, pte);
	return true;
}

@@ -1420,7 +1421,7 @@ static bool try_to_free_pmd_page(pmd_t *pmd)
		if (!pmd_none(pmd[i]))
			return false;

	free_page((unsigned long)pmd);
	pmd_free(&init_mm, pmd);
	return true;
}

@@ -1539,7 +1540,7 @@ static void unmap_pud_range(p4d_t *p4d, unsigned long start, unsigned long end)

static int alloc_pte_page(pmd_t *pmd)
{
	pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL);
	pte_t *pte = pte_alloc_one_kernel(&init_mm);
	if (!pte)
		return -1;

@@ -1549,7 +1550,11 @@ static int alloc_pte_page(pmd_t *pmd)

static int alloc_pmd_page(pud_t *pud)
{
	pmd_t *pmd = (pmd_t *)get_zeroed_page(GFP_KERNEL);
	/*
	 * Pass 0 as a placeholder for the second argument, since the
	 * generic implementation of pmd_alloc_one() does not use it.
	 */
	pmd_t *pmd = pmd_alloc_one(&init_mm, 0);
	if (!pmd)
		return -1;

@@ -1743,7 +1748,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
	pgd_entry = cpa->pgd + pgd_index(addr);

	if (pgd_none(*pgd_entry)) {
		p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL);
		/*
		 * Pass 0 as a placeholder for the second argument, since the
		 * generic implementation of p4d_alloc_one() does not use it.
		 */
		p4d = p4d_alloc_one(&init_mm, 0);
		if (!p4d)
			return -1;

@@ -1755,7 +1764,11 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
	 */
	p4d = p4d_offset(pgd_entry, addr);
	if (p4d_none(*p4d)) {
		pud = (pud_t *)get_zeroed_page(GFP_KERNEL);
		/*
		 * Pass 0 as a placeholder for the second argument, since the
		 * generic implementation of pud_alloc_one() does not use it.
		 */
		pud = pud_alloc_one(&init_mm, 0);
		if (!pud)
			return -1;