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

Commit 65cec8e3 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

ARM: implement highpte



Add the ARM implementation of highpte, which allows PTE tables to be
placed in highmem.  Unfortunately, we do not offer highpte support
when support for L2 cache is enabled.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 36984265
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1054,6 +1054,11 @@ config HIGHMEM

	  If unsure, say n.

config HIGHPTE
	bool "Allocate 2nd-level pagetables from highmem"
	depends on HIGHMEM
	depends on !OUTER_CACHE

source "mm/Kconfig"

config LEDS
+12 −4
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
#define pgd_alloc(mm)			get_pgd_slow(mm)
#define pgd_free(mm, pgd)		free_pgd_slow(mm, pgd)

#define PGALLOC_GFP	(GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)

/*
 * Allocate one PTE table.
 *
@@ -57,7 +59,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
{
	pte_t *pte;

	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
	pte = (pte_t *)__get_free_page(PGALLOC_GFP);
	if (pte) {
		clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
		pte += PTRS_PER_PTE;
@@ -71,10 +73,16 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
{
	struct page *pte;

	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
#ifdef CONFIG_HIGHPTE
	pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
#else
	pte = alloc_pages(PGALLOC_GFP, 0);
#endif
	if (pte) {
		if (!PageHighMem(pte)) {
			void *page = page_address(pte);
			clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
		}
		pgtable_page_ctor(pte);
	}

+13 −4
Original line number Diff line number Diff line
@@ -262,10 +262,19 @@ extern struct page *empty_zero_page;
#define pte_clear(mm,addr,ptep)	set_pte_ext(ptep, __pte(0), 0)
#define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
#define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
#define pte_offset_map(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
#define pte_offset_map_nested(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
#define pte_unmap(pte)		do { } while (0)
#define pte_unmap_nested(pte)	do { } while (0)

#define pte_offset_map(dir,addr)	(__pte_map(dir, KM_PTE0) + __pte_index(addr))
#define pte_offset_map_nested(dir,addr)	(__pte_map(dir, KM_PTE1) + __pte_index(addr))
#define pte_unmap(pte)			__pte_unmap(pte, KM_PTE0)
#define pte_unmap_nested(pte)		__pte_unmap(pte, KM_PTE1)

#ifndef CONFIG_HIGHPTE
#define __pte_map(dir,km)	pmd_page_vaddr(*(dir))
#define __pte_unmap(pte,km)	do { } while (0)
#else
#define __pte_map(dir,km)	((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
#define __pte_unmap(pte,km)	kunmap_atomic((pte - PTRS_PER_PTE), km)
#endif

#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)

+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/page-flags.h>
#include <linux/highmem.h>

#include <asm/system.h>
#include <asm/pgtable.h>