Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm/memblock: add MEMBLOCK_NOMAP attribute to memblock memory table

This introduces the MEMBLOCK_NOMAP attribute and the required plumbing
to make it usable as an indicator that some parts of normal memory
should not be covered by the kernel direct mapping. It is up to the
arch to actually honor the attribute when laying out this mapping,
but the memblock code itself is modified to disregard these regions
for allocations and other general use.

Cc: linux-mm@kvack.org
Cc: Alexander Kuleshov <kuleshovmail@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>

authored by

Ard Biesheuvel and committed by
Will Deacon
bf3d3cc5 31ade3b8

+36
+8
include/linux/memblock.h
··· 25 25 MEMBLOCK_NONE = 0x0, /* No special request */ 26 26 MEMBLOCK_HOTPLUG = 0x1, /* hotpluggable region */ 27 27 MEMBLOCK_MIRROR = 0x2, /* mirrored region */ 28 + MEMBLOCK_NOMAP = 0x4, /* don't add to kernel direct mapping */ 28 29 }; 29 30 30 31 struct memblock_region { ··· 83 82 int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); 84 83 int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); 85 84 int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); 85 + int memblock_mark_nomap(phys_addr_t base, phys_addr_t size); 86 86 ulong choose_memblock_flags(void); 87 87 88 88 /* Low level functions */ ··· 184 182 static inline bool memblock_is_mirror(struct memblock_region *m) 185 183 { 186 184 return m->flags & MEMBLOCK_MIRROR; 185 + } 186 + 187 + static inline bool memblock_is_nomap(struct memblock_region *m) 188 + { 189 + return m->flags & MEMBLOCK_NOMAP; 187 190 } 188 191 189 192 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP ··· 326 319 phys_addr_t memblock_end_of_DRAM(void); 327 320 void memblock_enforce_memory_limit(phys_addr_t memory_limit); 328 321 int memblock_is_memory(phys_addr_t addr); 322 + int memblock_is_map_memory(phys_addr_t addr); 329 323 int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); 330 324 int memblock_is_reserved(phys_addr_t addr); 331 325 bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
+28
mm/memblock.c
··· 822 822 return memblock_setclr_flag(base, size, 1, MEMBLOCK_MIRROR); 823 823 } 824 824 825 + /** 826 + * memblock_mark_nomap - Mark a memory region with flag MEMBLOCK_NOMAP. 827 + * @base: the base phys addr of the region 828 + * @size: the size of the region 829 + * 830 + * Return 0 on success, -errno on failure. 831 + */ 832 + int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size) 833 + { 834 + return memblock_setclr_flag(base, size, 1, MEMBLOCK_NOMAP); 835 + } 825 836 826 837 /** 827 838 * __next_reserved_mem_region - next function for for_each_reserved_region() ··· 922 911 923 912 /* if we want mirror memory skip non-mirror memory regions */ 924 913 if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m)) 914 + continue; 915 + 916 + /* skip nomap memory unless we were asked for it explicitly */ 917 + if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m)) 925 918 continue; 926 919 927 920 if (!type_b) { ··· 1035 1020 1036 1021 /* if we want mirror memory skip non-mirror memory regions */ 1037 1022 if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m)) 1023 + continue; 1024 + 1025 + /* skip nomap memory unless we were asked for it explicitly */ 1026 + if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m)) 1038 1027 continue; 1039 1028 1040 1029 if (!type_b) { ··· 1536 1517 int __init_memblock memblock_is_memory(phys_addr_t addr) 1537 1518 { 1538 1519 return memblock_search(&memblock.memory, addr) != -1; 1520 + } 1521 + 1522 + int __init_memblock memblock_is_map_memory(phys_addr_t addr) 1523 + { 1524 + int i = memblock_search(&memblock.memory, addr); 1525 + 1526 + if (i == -1) 1527 + return false; 1528 + return !memblock_is_nomap(&memblock.memory.regions[i]); 1539 1529 } 1540 1530 1541 1531 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP