Skip to content

Commit 99b4ac9

Browse files
committed
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>
1 parent 836a241 commit 99b4ac9

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

arch/arm/include/asm/fixmap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ enum fixed_addresses {
1414
__end_of_fixed_addresses
1515
};
1616

17+
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
18+
1719
#include <asm-generic/fixmap.h>
1820

1921
#endif

arch/arm/mm/mmu.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <asm/cputype.h>
2323
#include <asm/sections.h>
2424
#include <asm/cachetype.h>
25+
#include <asm/fixmap.h>
2526
#include <asm/sections.h>
2627
#include <asm/setup.h>
2728
#include <asm/smp_plat.h>
@@ -392,6 +393,29 @@ SET_MEMORY_FN(rw, pte_set_rw)
392393
SET_MEMORY_FN(x, pte_set_x)
393394
SET_MEMORY_FN(nx, pte_set_nx)
394395

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+
*/
401+
void __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+
395419
/*
396420
* Adjust the PMD section entries according to the CPU in use.
397421
*/

0 commit comments

Comments
 (0)