Skip to content

Commit bf3d3cc

Browse files
Ard Biesheuvelwildea01
authored andcommitted
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>
1 parent 31ade3b commit bf3d3cc

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

include/linux/memblock.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ enum {
2525
MEMBLOCK_NONE = 0x0, /* No special request */
2626
MEMBLOCK_HOTPLUG = 0x1, /* hotpluggable region */
2727
MEMBLOCK_MIRROR = 0x2, /* mirrored region */
28+
MEMBLOCK_NOMAP = 0x4, /* don't add to kernel direct mapping */
2829
};
2930

3031
struct memblock_region {
@@ -82,6 +83,7 @@ bool memblock_overlaps_region(struct memblock_type *type,
8283
int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
8384
int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
8485
int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
86+
int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
8587
ulong choose_memblock_flags(void);
8688

8789
/* Low level functions */
@@ -184,6 +186,11 @@ static inline bool memblock_is_mirror(struct memblock_region *m)
184186
return m->flags & MEMBLOCK_MIRROR;
185187
}
186188

189+
static inline bool memblock_is_nomap(struct memblock_region *m)
190+
{
191+
return m->flags & MEMBLOCK_NOMAP;
192+
}
193+
187194
#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
188195
int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,
189196
unsigned long *end_pfn);
@@ -319,6 +326,7 @@ phys_addr_t memblock_start_of_DRAM(void);
319326
phys_addr_t memblock_end_of_DRAM(void);
320327
void memblock_enforce_memory_limit(phys_addr_t memory_limit);
321328
int memblock_is_memory(phys_addr_t addr);
329+
int memblock_is_map_memory(phys_addr_t addr);
322330
int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
323331
int memblock_is_reserved(phys_addr_t addr);
324332
bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);

mm/memblock.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,17 @@ int __init_memblock memblock_mark_mirror(phys_addr_t base, phys_addr_t size)
822822
return memblock_setclr_flag(base, size, 1, MEMBLOCK_MIRROR);
823823
}
824824

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+
}
825836

826837
/**
827838
* __next_reserved_mem_region - next function for for_each_reserved_region()
@@ -913,6 +924,10 @@ void __init_memblock __next_mem_range(u64 *idx, int nid, ulong flags,
913924
if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))
914925
continue;
915926

927+
/* skip nomap memory unless we were asked for it explicitly */
928+
if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))
929+
continue;
930+
916931
if (!type_b) {
917932
if (out_start)
918933
*out_start = m_start;
@@ -1022,6 +1037,10 @@ void __init_memblock __next_mem_range_rev(u64 *idx, int nid, ulong flags,
10221037
if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))
10231038
continue;
10241039

1040+
/* skip nomap memory unless we were asked for it explicitly */
1041+
if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))
1042+
continue;
1043+
10251044
if (!type_b) {
10261045
if (out_start)
10271046
*out_start = m_start;
@@ -1519,6 +1538,15 @@ int __init_memblock memblock_is_memory(phys_addr_t addr)
15191538
return memblock_search(&memblock.memory, addr) != -1;
15201539
}
15211540

1541+
int __init_memblock memblock_is_map_memory(phys_addr_t addr)
1542+
{
1543+
int i = memblock_search(&memblock.memory, addr);
1544+
1545+
if (i == -1)
1546+
return false;
1547+
return !memblock_is_nomap(&memblock.memory.regions[i]);
1548+
}
1549+
15221550
#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
15231551
int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
15241552
unsigned long *start_pfn, unsigned long *end_pfn)

0 commit comments

Comments
 (0)