summaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2008-09-15 16:44:55 -0400
committerNicolas Pitre <nico@cam.org>2009-03-15 21:01:20 -0400
commitd73cd42893f4cdc06e6829fea2347bb92cb789d1 (patch)
treefddff067f2b09aa13741bc9d05956429616e986a /arch/arm/include
parent5f0fbf9ecaf354fa4bbf266fffdea2ea3d14a0ed (diff)
[ARM] kmap support
The kmap virtual area borrows a 2MB range at the top of the 16MB area below PAGE_OFFSET currently reserved for kernel modules and/or the XIP kernel. This 2MB corresponds to the range covered by 2 consecutive second-level page tables, or a single pmd entry as seen by the Linux page table abstraction. Because XIP kernels are unlikely to be seen on systems needing highmem support, there shouldn't be any shortage of VM space for modules (14 MB for modules is still way more than twice the typical usage). Because the virtual mapping of highmem pages can go away at any moment after kunmap() is called on them, we need to bypass the delayed cache flushing provided by flush_dcache_page() in that case. The atomic kmap versions are based on fixmaps, and __cpuc_flush_dcache_page() is used directly in that case. Signed-off-by: Nicolas Pitre <nico@marvell.com>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/highmem.h28
-rw-r--r--arch/arm/include/asm/memory.h13
2 files changed, 38 insertions, 3 deletions
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
new file mode 100644
index 00000000000..023d5b37454
--- /dev/null
+++ b/arch/arm/include/asm/highmem.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#include <asm/kmap_types.h>
+
+#define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE)
+#define LAST_PKMAP PTRS_PER_PTE
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define kmap_prot PAGE_KERNEL
+
+#define flush_cache_kmaps() flush_cache_all()
+
+extern pte_t *pkmap_page_table;
+
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *kmap_atomic(struct page *page, enum km_type type);
+extern void kunmap_atomic(void *kvaddr, enum km_type type);
+extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+extern struct page *kmap_atomic_to_page(const void *ptr);
+
+#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 0202a7c20e6..ae472bc376d 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -44,14 +44,21 @@
* The module space lives between the addresses given by TASK_SIZE
* and PAGE_OFFSET - it must be within 32MB of the kernel text.
*/
-#define MODULES_END (PAGE_OFFSET)
-#define MODULES_VADDR (MODULES_END - 16*1048576)
-
+#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024)
#if TASK_SIZE > MODULES_VADDR
#error Top of user space clashes with start of module space
#endif
/*
+ * The highmem pkmap virtual space shares the end of the module area.
+ */
+#ifdef CONFIG_HIGHMEM
+#define MODULES_END (PAGE_OFFSET - PMD_SIZE)
+#else
+#define MODULES_END (PAGE_OFFSET)
+#endif
+
+/*
* The XIP kernel gets mapped at the bottom of the module vm area.
* Since we use sections to map it, this macro replaces the physical address
* with its virtual address while keeping offset from the base section.