diff mbox

[v4,01/13] mm/memblock: add MEMBLOCK_NOMAP attribute to memblock memory table

Message ID 1448886507-3216-2-git-send-email-ard.biesheuvel@linaro.org
State Accepted
Commit bf3d3cc580f9960883ebf9ea05868f336d9491c2
Headers show

Commit Message

Ard Biesheuvel Nov. 30, 2015, 12:28 p.m. UTC
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>

---
 include/linux/memblock.h |  8 ++++++
 mm/memblock.c            | 28 ++++++++++++++++++++
 2 files changed, 36 insertions(+)

-- 
1.9.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Comments

Ard Biesheuvel Dec. 3, 2015, 10:55 a.m. UTC | #1
On 30 November 2015 at 13:28, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> 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>

> ---

>  include/linux/memblock.h |  8 ++++++

>  mm/memblock.c            | 28 ++++++++++++++++++++

>  2 files changed, 36 insertions(+)

>

> diff --git a/include/linux/memblock.h b/include/linux/memblock.h

> index 24daf8fc4d7c..fec66f86eeff 100644

> --- a/include/linux/memblock.h

> +++ b/include/linux/memblock.h

> @@ -25,6 +25,7 @@ enum {

>         MEMBLOCK_NONE           = 0x0,  /* No special request */

>         MEMBLOCK_HOTPLUG        = 0x1,  /* hotpluggable region */

>         MEMBLOCK_MIRROR         = 0x2,  /* mirrored region */

> +       MEMBLOCK_NOMAP          = 0x4,  /* don't add to kernel direct mapping */

>  };

>

>  struct memblock_region {

> @@ -82,6 +83,7 @@ bool memblock_overlaps_region(struct memblock_type *type,

>  int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);

>  int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);

>  int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);

> +int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);

>  ulong choose_memblock_flags(void);

>

>  /* Low level functions */

> @@ -184,6 +186,11 @@ static inline bool memblock_is_mirror(struct memblock_region *m)

>         return m->flags & MEMBLOCK_MIRROR;

>  }

>

> +static inline bool memblock_is_nomap(struct memblock_region *m)

> +{

> +       return m->flags & MEMBLOCK_NOMAP;

> +}

> +

>  #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP

>  int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,

>                             unsigned long  *end_pfn);

> @@ -319,6 +326,7 @@ phys_addr_t memblock_start_of_DRAM(void);

>  phys_addr_t memblock_end_of_DRAM(void);

>  void memblock_enforce_memory_limit(phys_addr_t memory_limit);

>  int memblock_is_memory(phys_addr_t addr);

> +int memblock_is_map_memory(phys_addr_t addr);

>  int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);

>  int memblock_is_reserved(phys_addr_t addr);

>  bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);

> diff --git a/mm/memblock.c b/mm/memblock.c

> index d300f1329814..07ff069fef25 100644

> --- a/mm/memblock.c

> +++ b/mm/memblock.c

> @@ -822,6 +822,17 @@ int __init_memblock memblock_mark_mirror(phys_addr_t base, phys_addr_t size)

>         return memblock_setclr_flag(base, size, 1, MEMBLOCK_MIRROR);

>  }

>

> +/**

> + * memblock_mark_nomap - Mark a memory region with flag MEMBLOCK_NOMAP.

> + * @base: the base phys addr of the region

> + * @size: the size of the region

> + *

> + * Return 0 on success, -errno on failure.

> + */

> +int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)

> +{

> +       return memblock_setclr_flag(base, size, 1, MEMBLOCK_NOMAP);

> +}

>

>  /**

>   * __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,

>                 if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))

>                         continue;

>

> +               /* skip nomap memory unless we were asked for it explicitly */

> +               if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))

> +                       continue;

> +

>                 if (!type_b) {

>                         if (out_start)

>                                 *out_start = m_start;

> @@ -1022,6 +1037,10 @@ void __init_memblock __next_mem_range_rev(u64 *idx, int nid, ulong flags,

>                 if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))

>                         continue;

>

> +               /* skip nomap memory unless we were asked for it explicitly */

> +               if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))

> +                       continue;

> +

>                 if (!type_b) {

>                         if (out_start)

>                                 *out_start = m_start;

> @@ -1519,6 +1538,15 @@ int __init_memblock memblock_is_memory(phys_addr_t addr)

>         return memblock_search(&memblock.memory, addr) != -1;

>  }

>

> +int __init_memblock memblock_is_map_memory(phys_addr_t addr)

> +{

> +       int i = memblock_search(&memblock.memory, addr);

> +

> +       if (i == -1)

> +               return false;

> +       return !memblock_is_nomap(&memblock.memory.regions[i]);

> +}

> +

>  #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP

>  int __init_memblock memblock_search_pfn_nid(unsigned long pfn,

>                          unsigned long *start_pfn, unsigned long *end_pfn)


May I kindly ask team-mm/Andrew/Alexander to chime in here, and
indicate whether you are ok with this patch going in for 4.5? If so,
could you please provide your ack so the patch can be kept together
with the rest of the series, which depends on it?

I should note that this change should not affect any memblock users
that never set the MEMBLOCK_NOMAP flag, but please, if you see any
issues beyond 'this may conflict with other stuff we have queued for
4.5', please do let me know.

Thanks,
Ard.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon Dec. 8, 2015, 12:07 p.m. UTC | #2
Hi Ard,

On Thu, Dec 03, 2015 at 11:55:53AM +0100, Ard Biesheuvel wrote:
> On 30 November 2015 at 13:28, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > 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>

> > ---

> >  include/linux/memblock.h |  8 ++++++

> >  mm/memblock.c            | 28 ++++++++++++++++++++

> >  2 files changed, 36 insertions(+)


[...]

> May I kindly ask team-mm/Andrew/Alexander to chime in here, and

> indicate whether you are ok with this patch going in for 4.5? If so,

> could you please provide your ack so the patch can be kept together

> with the rest of the series, which depends on it?


I'm keen to queue this in the arm64 tree, since it's a prerequisite for
cleaning up a bunch of our EFI code and sharing it with 32-bit ARM.

> I should note that this change should not affect any memblock users

> that never set the MEMBLOCK_NOMAP flag, but please, if you see any

> issues beyond 'this may conflict with other stuff we have queued for

> 4.5', please do let me know.


Indeed, I can't see that this would cause any issues, but I would really
like an Ack from one of the MM maintainers before taking this.

Please could somebody take a look?

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Will Deacon Dec. 9, 2015, 11:29 a.m. UTC | #3
On Tue, Dec 08, 2015 at 02:23:41PM -0800, Andrew Morton wrote:
> On Tue, 8 Dec 2015 12:07:44 +0000 Will Deacon <will.deacon@arm.com> wrote:

> 

> > > I should note that this change should not affect any memblock users

> > > that never set the MEMBLOCK_NOMAP flag, but please, if you see any

> > > issues beyond 'this may conflict with other stuff we have queued for

> > > 4.5', please do let me know.

> > 

> > Indeed, I can't see that this would cause any issues, but I would really

> > like an Ack from one of the MM maintainers before taking this.

> > 

> > Please could somebody take a look?

> 

> It looks OK to me.  Please go ahead and merge it via an arm tree.


Will do, thanks Andrew.

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff mbox

Patch

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 24daf8fc4d7c..fec66f86eeff 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -25,6 +25,7 @@  enum {
 	MEMBLOCK_NONE		= 0x0,	/* No special request */
 	MEMBLOCK_HOTPLUG	= 0x1,	/* hotpluggable region */
 	MEMBLOCK_MIRROR		= 0x2,	/* mirrored region */
+	MEMBLOCK_NOMAP		= 0x4,	/* don't add to kernel direct mapping */
 };
 
 struct memblock_region {
@@ -82,6 +83,7 @@  bool memblock_overlaps_region(struct memblock_type *type,
 int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
 int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
 int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
+int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
 ulong choose_memblock_flags(void);
 
 /* Low level functions */
@@ -184,6 +186,11 @@  static inline bool memblock_is_mirror(struct memblock_region *m)
 	return m->flags & MEMBLOCK_MIRROR;
 }
 
+static inline bool memblock_is_nomap(struct memblock_region *m)
+{
+	return m->flags & MEMBLOCK_NOMAP;
+}
+
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
 int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn,
 			    unsigned long  *end_pfn);
@@ -319,6 +326,7 @@  phys_addr_t memblock_start_of_DRAM(void);
 phys_addr_t memblock_end_of_DRAM(void);
 void memblock_enforce_memory_limit(phys_addr_t memory_limit);
 int memblock_is_memory(phys_addr_t addr);
+int memblock_is_map_memory(phys_addr_t addr);
 int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
 int memblock_is_reserved(phys_addr_t addr);
 bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index d300f1329814..07ff069fef25 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -822,6 +822,17 @@  int __init_memblock memblock_mark_mirror(phys_addr_t base, phys_addr_t size)
 	return memblock_setclr_flag(base, size, 1, MEMBLOCK_MIRROR);
 }
 
+/**
+ * memblock_mark_nomap - Mark a memory region with flag MEMBLOCK_NOMAP.
+ * @base: the base phys addr of the region
+ * @size: the size of the region
+ *
+ * Return 0 on success, -errno on failure.
+ */
+int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
+{
+	return memblock_setclr_flag(base, size, 1, MEMBLOCK_NOMAP);
+}
 
 /**
  * __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,
 		if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))
 			continue;
 
+		/* skip nomap memory unless we were asked for it explicitly */
+		if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))
+			continue;
+
 		if (!type_b) {
 			if (out_start)
 				*out_start = m_start;
@@ -1022,6 +1037,10 @@  void __init_memblock __next_mem_range_rev(u64 *idx, int nid, ulong flags,
 		if ((flags & MEMBLOCK_MIRROR) && !memblock_is_mirror(m))
 			continue;
 
+		/* skip nomap memory unless we were asked for it explicitly */
+		if (!(flags & MEMBLOCK_NOMAP) && memblock_is_nomap(m))
+			continue;
+
 		if (!type_b) {
 			if (out_start)
 				*out_start = m_start;
@@ -1519,6 +1538,15 @@  int __init_memblock memblock_is_memory(phys_addr_t addr)
 	return memblock_search(&memblock.memory, addr) != -1;
 }
 
+int __init_memblock memblock_is_map_memory(phys_addr_t addr)
+{
+	int i = memblock_search(&memblock.memory, addr);
+
+	if (i == -1)
+		return false;
+	return !memblock_is_nomap(&memblock.memory.regions[i]);
+}
+
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
 int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
 			 unsigned long *start_pfn, unsigned long *end_pfn)