aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-04-04 17:27:49 -0400
committerKees Cook <keescook@chromium.org>2014-10-16 17:38:52 -0400
commit99b4ac9afce4129323b5b4c7002a942a9489914c (patch)
treee3e5a3a562883eac4999f72e940fa5261c518b46
parent836a24183273e9db1c092246bd8e306b297d9917 (diff)
arm: fixmap: implement __set_fixmap()
This is used from set_fixmap() and clear_fixmap() via asm-generic/fixmap.h. Also makes sure that the fixmap allocation fits into the expected range. Based on patch by Rabin Vincent. Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Rabin Vincent <rabin@rab.in> Acked-by: Nicolas Pitre <nico@linaro.org>
-rw-r--r--arch/arm/include/asm/fixmap.h2
-rw-r--r--arch/arm/mm/mmu.c24
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index d984ca69ce19..714606f70425 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -14,6 +14,8 @@ enum fixed_addresses {
14 __end_of_fixed_addresses 14 __end_of_fixed_addresses
15}; 15};
16 16
17void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
18
17#include <asm-generic/fixmap.h> 19#include <asm-generic/fixmap.h>
18 20
19#endif 21#endif
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7fa0966cd15f..bdf5c94f7c36 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -22,6 +22,7 @@
22#include <asm/cputype.h> 22#include <asm/cputype.h>
23#include <asm/sections.h> 23#include <asm/sections.h>
24#include <asm/cachetype.h> 24#include <asm/cachetype.h>
25#include <asm/fixmap.h>
25#include <asm/sections.h> 26#include <asm/sections.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
27#include <asm/smp_plat.h> 28#include <asm/smp_plat.h>
@@ -393,6 +394,29 @@ SET_MEMORY_FN(x, pte_set_x)
393SET_MEMORY_FN(nx, pte_set_nx) 394SET_MEMORY_FN(nx, pte_set_nx)
394 395
395/* 396/*
397 * To avoid TLB flush broadcasts, this uses local_flush_tlb_kernel_range().
398 * As a result, this can only be called with preemption disabled, as under
399 * stop_machine().
400 */
401void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
402{
403 unsigned long vaddr = __fix_to_virt(idx);
404 pte_t *pte = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
405
406 /* Make sure fixmap region does not exceed available allocation. */
407 BUILD_BUG_ON(FIXADDR_START + (__end_of_fixed_addresses * PAGE_SIZE) >
408 FIXADDR_END);
409 BUG_ON(idx >= __end_of_fixed_addresses);
410
411 if (pgprot_val(prot))
412 set_pte_at(NULL, vaddr, pte,
413 pfn_pte(phys >> PAGE_SHIFT, prot));
414 else
415 pte_clear(NULL, vaddr, pte);
416 local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
417}
418
419/*
396 * Adjust the PMD section entries according to the CPU in use. 420 * Adjust the PMD section entries according to the CPU in use.
397 */ 421 */
398static void __init build_mem_type_table(void) 422static void __init build_mem_type_table(void)