};
 
 #define for_each_dump_mem_range(i, nid, p_start, p_end, p_nid)         \
-       for (i = 0, __next_mem_range(&i, nid, &memblock.physmem,        \
+       for (i = 0, __next_mem_range(&i, nid, MEMBLOCK_NONE,            \
+                                    &memblock.physmem,                 \
                                     &oldmem_type, p_start,             \
                                     p_end, p_nid);                     \
             i != (u64)ULLONG_MAX;                                      \
-            __next_mem_range(&i, nid, &memblock.physmem,               \
+            __next_mem_range(&i, nid, MEMBLOCK_NONE, &memblock.physmem,\
                              &oldmem_type,                             \
                              p_start, p_end, p_nid))
 
 
        phys_addr_t pa_start, pa_end;
        u64 i;
 
-       for_each_free_mem_range(i, NUMA_NO_NODE, &pa_start, &pa_end, NULL)
+       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &pa_start,
+                               &pa_end, NULL)
                available = available + (pa_end  - pa_start);
 
        return available;
        if (limit_ram >= avail_ram)
                return;
 
-       for_each_free_mem_range(i, NUMA_NO_NODE, &pa_start, &pa_end, NULL) {
+       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &pa_start,
+                               &pa_end, NULL) {
                phys_addr_t region_size = pa_end - pa_start;
                phys_addr_t clip_start = pa_start;
 
 
 
        corruption_check_size = round_up(corruption_check_size, PAGE_SIZE);
 
-       for_each_free_mem_range(i, NUMA_NO_NODE, &start, &end, NULL) {
+       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
+                               NULL) {
                start = clamp_t(phys_addr_t, round_up(start, PAGE_SIZE),
                                PAGE_SIZE, corruption_check_size);
                end = clamp_t(phys_addr_t, round_down(end, PAGE_SIZE),
 
                nr_pages += end_pfn - start_pfn;
        }
 
-       for_each_free_mem_range(u, NUMA_NO_NODE, &start, &end, NULL) {
+       for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
+                               NULL) {
                start_pfn = min_t(unsigned long, PFN_UP(start), MAX_DMA_PFN);
                end_pfn = min_t(unsigned long, PFN_DOWN(end), MAX_DMA_PFN);
                if (start_pfn < end_pfn)
 
        phys_addr_t start, end;
        u64 i;
 
-       for_each_free_mem_range(i, nid, &start, &end, NULL) {
+       for_each_free_mem_range(i, nid, MEMBLOCK_NONE, &start, &end, NULL) {
                unsigned long pfn = clamp_t(unsigned long, PFN_UP(start),
                                            start_pfn, end_pfn);
                unsigned long e_pfn = clamp_t(unsigned long, PFN_DOWN(end),
 
 #define INIT_PHYSMEM_REGIONS   4
 
 /* Definition of memblock flags. */
-#define MEMBLOCK_HOTPLUG       0x1     /* hotpluggable region */
+enum {
+       MEMBLOCK_NONE           = 0x0,  /* No special request */
+       MEMBLOCK_HOTPLUG        = 0x1,  /* hotpluggable region */
+};
 
 struct memblock_region {
        phys_addr_t base;
 
 phys_addr_t memblock_find_in_range_node(phys_addr_t size, phys_addr_t align,
                                            phys_addr_t start, phys_addr_t end,
-                                           int nid);
+                                           int nid, ulong flags);
 phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
                                   phys_addr_t size, phys_addr_t align);
 phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
                          phys_addr_t base,
                          phys_addr_t size);
 
-void __next_mem_range(u64 *idx, int nid, struct memblock_type *type_a,
+void __next_mem_range(u64 *idx, int nid, ulong flags,
+                     struct memblock_type *type_a,
                      struct memblock_type *type_b, phys_addr_t *out_start,
                      phys_addr_t *out_end, int *out_nid);
 
-void __next_mem_range_rev(u64 *idx, int nid, struct memblock_type *type_a,
+void __next_mem_range_rev(u64 *idx, int nid, ulong flags,
+                         struct memblock_type *type_a,
                          struct memblock_type *type_b, phys_addr_t *out_start,
                          phys_addr_t *out_end, int *out_nid);
 
  * @type_a: ptr to memblock_type to iterate
  * @type_b: ptr to memblock_type which excludes from the iteration
  * @nid: node selector, %NUMA_NO_NODE for all nodes
+ * @flags: pick from blocks based on memory attributes
  * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
  * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
  * @p_nid: ptr to int for nid of the range, can be %NULL
  */
-#define for_each_mem_range(i, type_a, type_b, nid,                     \
+#define for_each_mem_range(i, type_a, type_b, nid, flags,              \
                           p_start, p_end, p_nid)                       \
-       for (i = 0, __next_mem_range(&i, nid, type_a, type_b,           \
+       for (i = 0, __next_mem_range(&i, nid, flags, type_a, type_b,    \
                                     p_start, p_end, p_nid);            \
             i != (u64)ULLONG_MAX;                                      \
-            __next_mem_range(&i, nid, type_a, type_b,                  \
+            __next_mem_range(&i, nid, flags, type_a, type_b,           \
                              p_start, p_end, p_nid))
 
 /**
  * @type_a: ptr to memblock_type to iterate
  * @type_b: ptr to memblock_type which excludes from the iteration
  * @nid: node selector, %NUMA_NO_NODE for all nodes
+ * @flags: pick from blocks based on memory attributes
  * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
  * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
  * @p_nid: ptr to int for nid of the range, can be %NULL
  */
-#define for_each_mem_range_rev(i, type_a, type_b, nid,                 \
+#define for_each_mem_range_rev(i, type_a, type_b, nid, flags,          \
                               p_start, p_end, p_nid)                   \
        for (i = (u64)ULLONG_MAX,                                       \
-                    __next_mem_range_rev(&i, nid, type_a, type_b,      \
+                    __next_mem_range_rev(&i, nid, flags, type_a, type_b,\
                                         p_start, p_end, p_nid);        \
             i != (u64)ULLONG_MAX;                                      \
-            __next_mem_range_rev(&i, nid, type_a, type_b,              \
+            __next_mem_range_rev(&i, nid, flags, type_a, type_b,       \
                                  p_start, p_end, p_nid))
 
 #ifdef CONFIG_MOVABLE_NODE
  * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
  * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
  * @p_nid: ptr to int for nid of the range, can be %NULL
+ * @flags: pick from blocks based on memory attributes
  *
  * Walks over free (memory && !reserved) areas of memblock.  Available as
  * soon as memblock is initialized.
  */
-#define for_each_free_mem_range(i, nid, p_start, p_end, p_nid)         \
+#define for_each_free_mem_range(i, nid, flags, p_start, p_end, p_nid)  \
        for_each_mem_range(i, &memblock.memory, &memblock.reserved,     \
-                          nid, p_start, p_end, p_nid)
+                          nid, flags, p_start, p_end, p_nid)
 
 /**
  * for_each_free_mem_range_reverse - rev-iterate through free memblock areas
  * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
  * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
  * @p_nid: ptr to int for nid of the range, can be %NULL
+ * @flags: pick from blocks based on memory attributes
  *
  * Walks over free (memory && !reserved) areas of memblock in reverse
  * order.  Available as soon as memblock is initialized.
  */
-#define for_each_free_mem_range_reverse(i, nid, p_start, p_end, p_nid) \
+#define for_each_free_mem_range_reverse(i, nid, flags, p_start, p_end, \
+                                       p_nid)                          \
        for_each_mem_range_rev(i, &memblock.memory, &memblock.reserved, \
-                              nid, p_start, p_end, p_nid)
+                              nid, flags, p_start, p_end, p_nid)
 
 static inline void memblock_set_region_flags(struct memblock_region *r,
                                             unsigned long flags)
 #define MEMBLOCK_ALLOC_ACCESSIBLE      0
 
 phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
-                                       phys_addr_t start, phys_addr_t end);
+                                       phys_addr_t start, phys_addr_t end,
+                                       ulong flags);
 phys_addr_t memblock_alloc_base(phys_addr_t size, phys_addr_t align,
                                phys_addr_t max_addr);
 phys_addr_t __memblock_alloc_base(phys_addr_t size, phys_addr_t align,
 
                 */
                if (base < highmem_start && limit > highmem_start) {
                        addr = memblock_alloc_range(size, alignment,
-                                                   highmem_start, limit);
+                                                   highmem_start, limit,
+                                                   MEMBLOCK_NONE);
                        limit = highmem_start;
                }
 
                if (!addr) {
                        addr = memblock_alloc_range(size, alignment, base,
-                                                   limit);
+                                                   limit,
+                                                   MEMBLOCK_NONE);
                        if (!addr) {
                                ret = -ENOMEM;
                                goto err;
 
  * @size: size of free area to find
  * @align: alignment of free area to find
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
+ * @flags: pick from blocks based on memory attributes
  *
  * Utility called from memblock_find_in_range_node(), find free area bottom-up.
  *
  */
 static phys_addr_t __init_memblock
 __memblock_find_range_bottom_up(phys_addr_t start, phys_addr_t end,
-                               phys_addr_t size, phys_addr_t align, int nid)
+                               phys_addr_t size, phys_addr_t align, int nid,
+                               ulong flags)
 {
        phys_addr_t this_start, this_end, cand;
        u64 i;
 
-       for_each_free_mem_range(i, nid, &this_start, &this_end, NULL) {
+       for_each_free_mem_range(i, nid, flags, &this_start, &this_end, NULL) {
                this_start = clamp(this_start, start, end);
                this_end = clamp(this_end, start, end);
 
  * @size: size of free area to find
  * @align: alignment of free area to find
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
+ * @flags: pick from blocks based on memory attributes
  *
  * Utility called from memblock_find_in_range_node(), find free area top-down.
  *
  */
 static phys_addr_t __init_memblock
 __memblock_find_range_top_down(phys_addr_t start, phys_addr_t end,
-                              phys_addr_t size, phys_addr_t align, int nid)
+                              phys_addr_t size, phys_addr_t align, int nid,
+                              ulong flags)
 {
        phys_addr_t this_start, this_end, cand;
        u64 i;
 
-       for_each_free_mem_range_reverse(i, nid, &this_start, &this_end, NULL) {
+       for_each_free_mem_range_reverse(i, nid, flags, &this_start, &this_end,
+                                       NULL) {
                this_start = clamp(this_start, start, end);
                this_end = clamp(this_end, start, end);
 
  * @start: start of candidate range
  * @end: end of candidate range, can be %MEMBLOCK_ALLOC_{ANYWHERE|ACCESSIBLE}
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
+ * @flags: pick from blocks based on memory attributes
  *
  * Find @size free area aligned to @align in the specified range and node.
  *
  */
 phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
                                        phys_addr_t align, phys_addr_t start,
-                                       phys_addr_t end, int nid)
+                                       phys_addr_t end, int nid, ulong flags)
 {
        phys_addr_t kernel_end, ret;
 
 
                /* ok, try bottom-up allocation first */
                ret = __memblock_find_range_bottom_up(bottom_up_start, end,
-                                                     size, align, nid);
+                                                     size, align, nid, flags);
                if (ret)
                        return ret;
 
                             "memory hotunplug may be affected\n");
        }
 
-       return __memblock_find_range_top_down(start, end, size, align, nid);
+       return __memblock_find_range_top_down(start, end, size, align, nid,
+                                             flags);
 }
 
 /**
                                        phys_addr_t align)
 {
        return memblock_find_in_range_node(size, align, start, end,
-                                           NUMA_NO_NODE);
+                                           NUMA_NO_NODE, MEMBLOCK_NONE);
 }
 
 static void __init_memblock memblock_remove_region(struct memblock_type *type, unsigned long r)
  * __next__mem_range - next function for for_each_free_mem_range() etc.
  * @idx: pointer to u64 loop variable
  * @nid: node selector, %NUMA_NO_NODE for all nodes
+ * @flags: pick from blocks based on memory attributes
  * @type_a: pointer to memblock_type from where the range is taken
  * @type_b: pointer to memblock_type which excludes memory from being taken
  * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL
  * As both region arrays are sorted, the function advances the two indices
  * in lockstep and returns each intersection.
  */
-void __init_memblock __next_mem_range(u64 *idx, int nid,
+void __init_memblock __next_mem_range(u64 *idx, int nid, ulong flags,
                                      struct memblock_type *type_a,
                                      struct memblock_type *type_b,
                                      phys_addr_t *out_start,
  *
  * @idx: pointer to u64 loop variable
  * @nid: nid: node selector, %NUMA_NO_NODE for all nodes
+ * @flags: pick from blocks based on memory attributes
  * @type_a: pointer to memblock_type from where the range is taken
  * @type_b: pointer to memblock_type which excludes memory from being taken
  * @out_start: ptr to phys_addr_t for start address of the range, can be %NULL
  *
  * Reverse of __next_mem_range().
  */
-void __init_memblock __next_mem_range_rev(u64 *idx, int nid,
+void __init_memblock __next_mem_range_rev(u64 *idx, int nid, ulong flags,
                                          struct memblock_type *type_a,
                                          struct memblock_type *type_b,
                                          phys_addr_t *out_start,
 
 static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
                                        phys_addr_t align, phys_addr_t start,
-                                       phys_addr_t end, int nid)
+                                       phys_addr_t end, int nid, ulong flags)
 {
        phys_addr_t found;
 
        if (!align)
                align = SMP_CACHE_BYTES;
 
-       found = memblock_find_in_range_node(size, align, start, end, nid);
+       found = memblock_find_in_range_node(size, align, start, end, nid,
+                                           flags);
        if (found && !memblock_reserve(found, size)) {
                /*
                 * The min_count is set to 0 so that memblock allocations are
 }
 
 phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
-                                       phys_addr_t start, phys_addr_t end)
+                                       phys_addr_t start, phys_addr_t end,
+                                       ulong flags)
 {
-       return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE);
+       return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE,
+                                       flags);
 }
 
 static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
                                        phys_addr_t align, phys_addr_t max_addr,
-                                       int nid)
+                                       int nid, ulong flags)
 {
-       return memblock_alloc_range_nid(size, align, 0, max_addr, nid);
+       return memblock_alloc_range_nid(size, align, 0, max_addr, nid, flags);
 }
 
 phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid)
 {
-       return memblock_alloc_base_nid(size, align, MEMBLOCK_ALLOC_ACCESSIBLE, nid);
+       return memblock_alloc_base_nid(size, align, MEMBLOCK_ALLOC_ACCESSIBLE,
+                                      nid, MEMBLOCK_NONE);
 }
 
 phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
 {
-       return memblock_alloc_base_nid(size, align, max_addr, NUMA_NO_NODE);
+       return memblock_alloc_base_nid(size, align, max_addr, NUMA_NO_NODE,
+                                      MEMBLOCK_NONE);
 }
 
 phys_addr_t __init memblock_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
 
 again:
        alloc = memblock_find_in_range_node(size, align, min_addr, max_addr,
-                                           nid);
+                                           nid, MEMBLOCK_NONE);
        if (alloc)
                goto done;
 
        if (nid != NUMA_NO_NODE) {
                alloc = memblock_find_in_range_node(size, align, min_addr,
-                                                   max_addr,  NUMA_NO_NODE);
+                                                   max_addr, NUMA_NO_NODE,
+                                                   MEMBLOCK_NONE);
                if (alloc)
                        goto done;
        }
 
        u64 i;
        phys_addr_t this_start, this_end;
 
-       for_each_free_mem_range(i, NUMA_NO_NODE, &this_start, &this_end, NULL) {
+       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &this_start,
+                               &this_end, NULL) {
                this_start = clamp(this_start, start, end);
                this_end = clamp(this_end, start, end);
                if (this_start < this_end) {
 
        if (limit > memblock.current_limit)
                limit = memblock.current_limit;
 
-       addr = memblock_find_in_range_node(size, align, goal, limit, nid);
+       addr = memblock_find_in_range_node(size, align, goal, limit, nid,
+                                          MEMBLOCK_NONE);
        if (!addr)
                return NULL;
 
 
        memblock_clear_hotplug(0, -1);
 
-       for_each_free_mem_range(i, NUMA_NO_NODE, &start, &end, NULL)
+       for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
+                               NULL)
                count += __free_memory_core(start, end);
 
 #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK