diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 32e4845..58a4342 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -93,7 +93,8 @@ __tagtable(ATAG_INITRD2, parse_tag_initrd2);
 static void __init find_limits(unsigned long *min, unsigned long *max_low,
 			       unsigned long *max_high)
 {
-	*max_low = PFN_DOWN(memblock_get_current_limit());
+	memblock_get_current_limit(NULL, max_low);
+	*max_low = PFN_DOWN(*max_low);
 	*min = PFN_UP(memblock_start_of_DRAM());
 	*max_high = PFN_DOWN(memblock_end_of_DRAM());
 }
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f5cc1cc..9025418 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1240,7 +1240,7 @@ void __init adjust_lowmem_bounds(void)
 		}
 	}
 
-	memblock_set_current_limit(memblock_limit);
+	memblock_set_current_limit(0, memblock_limit, false);
 }
 
 static inline void prepare_page_table(void)
@@ -1625,7 +1625,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 
 	prepare_page_table();
 	map_lowmem();
-	memblock_set_current_limit(arm_lowmem_limit);
+	memblock_set_current_limit(0, arm_lowmem_limit, false);
 	dma_contiguous_remap();
 	early_fixmap_shutdown();
 	devicemaps_init(mdesc);
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 7d67c70..721535c 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -138,7 +138,7 @@ void __init adjust_lowmem_bounds(void)
 	adjust_lowmem_bounds_mpu();
 	end = memblock_end_of_DRAM();
 	high_memory = __va(end - 1) + 1;
-	memblock_set_current_limit(end);
+	memblock_set_current_limit(0, end, false);
 }
 
 /*
diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c
index dff8b89..e6f88bf 100644
--- a/arch/csky/kernel/setup.c
+++ b/arch/csky/kernel/setup.c
@@ -100,7 +100,7 @@ static void __init csky_memblock_init(void)
 
 	highend_pfn = max_pfn;
 #endif
-	memblock_set_current_limit(PFN_PHYS(max_low_pfn));
+	memblock_set_current_limit(0, PFN_PHYS(max_low_pfn), false);
 
 	dma_contiguous_reserve(0);
 
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index b17fd8a..cee99da 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -353,7 +353,7 @@ asmlinkage void __init mmu_init(void)
 	/* Shortly after that, the entire linear mapping will be available */
 	/* This will also cause that unflatten device tree will be allocated
 	 * inside 768MB limit */
-	memblock_set_current_limit(memory_start + lowmem_size - 1);
+	memblock_set_current_limit(0, memory_start + lowmem_size - 1, false);
 }
 
 /* This is only called until mem_init is done. */
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8c6c48ed..62dabe1 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -862,7 +862,7 @@ static void __init arch_mem_init(char **cmdline_p)
 	 * with memblock_reserve; memblock_alloc* can be used
 	 * only after this point
 	 */
-	memblock_set_current_limit(PFN_PHYS(max_low_pfn));
+	memblock_set_current_limit(0, PFN_PHYS(max_low_pfn), false);
 
 #ifdef CONFIG_PROC_VMCORE
 	if (setup_elfcorehdr && setup_elfcorehdr_size) {
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 61ac468..427bb56 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -141,7 +141,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
 	 * coverage with normal-sized pages (or other reasons) do not
 	 * attempt to allocate outside the allowed range.
 	 */
-	memblock_set_current_limit(mapped);
+	memblock_set_current_limit(0, mapped, false);
 
 	return mapped;
 }
@@ -155,5 +155,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 	BUG_ON(first_memblock_base != 0);
 
 	/* 40x can only access 16MB at the moment (see head_40x.S) */
-	memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
+	memblock_set_current_limit(0,
+		min_t(u64, first_memblock_size, 0x00800000),
+		false);
 }
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index 12d9251..3cf127d 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -225,7 +225,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 
 	/* 44x has a 256M TLB entry pinned at boot */
 	size = (min_t(u64, first_memblock_size, PPC_PIN_SIZE));
-	memblock_set_current_limit(first_memblock_base + size);
+	memblock_set_current_limit(0, first_memblock_base + size, false);
 }
 
 #ifdef CONFIG_SMP
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
index 01b7f51..c75bca6 100644
--- a/arch/powerpc/mm/8xx_mmu.c
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -135,7 +135,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
 	 * attempt to allocate outside the allowed range.
 	 */
 	if (mapped)
-		memblock_set_current_limit(mapped);
+		memblock_set_current_limit(0, mapped, false);
 
 	block_mapped_ram = mapped;
 
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 080d49b..3be24b8 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -252,7 +252,8 @@ void __init adjust_total_lowmem(void)
 	pr_cont("%lu Mb, residual: %dMb\n", tlbcam_sz(tlbcam_index - 1) >> 20,
 	        (unsigned int)((total_lowmem - __max_low_memory) >> 20));
 
-	memblock_set_current_limit(memstart_addr + __max_low_memory);
+	memblock_set_current_limit(0,
+		memstart_addr + __max_low_memory, false);
 }
 
 void setup_initial_memory_limit(phys_addr_t first_memblock_base,
@@ -261,7 +262,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 	phys_addr_t limit = first_memblock_base + first_memblock_size;
 
 	/* 64M mapped initially according to head_fsl_booke.S */
-	memblock_set_current_limit(min_t(u64, limit, 0x04000000));
+	memblock_set_current_limit(0, min_t(u64, limit, 0x04000000), false);
 }
 
 #ifdef CONFIG_RELOCATABLE
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 0cc7fbc..30fba80 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -925,7 +925,7 @@ static void __init htab_initialize(void)
 		BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
 				prot, mmu_linear_psize, mmu_kernel_ssize));
 	}
-	memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
+	memblock_set_current_limit(0, MEMBLOCK_ALLOC_ANYWHERE, false);
 
 	/*
 	 * If we have a memory_limit and we've allocated TCEs then we need to
@@ -1867,7 +1867,7 @@ void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base,
 			ppc64_rma_size = min_t(u64, ppc64_rma_size, 0x40000000);
 
 		/* Finally limit subsequent allocations */
-		memblock_set_current_limit(ppc64_rma_size);
+		memblock_set_current_limit(0, ppc64_rma_size, false);
 	} else {
 		ppc64_rma_size = ULONG_MAX;
 	}
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 3e59e5d..863d710 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -183,5 +183,5 @@ void __init MMU_init(void)
 #endif
 
 	/* Shortly after that, the entire linear mapping will be available */
-	memblock_set_current_limit(lowmem_end_addr);
+	memblock_set_current_limit(0, lowmem_end_addr, false);
 }
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 9311560..8cd5f2d 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -603,7 +603,7 @@ void __init radix__early_init_mmu(void)
 		radix_init_pseries();
 	}
 
-	memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
+	memblock_set_current_limit(0, MEMBLOCK_ALLOC_ANYWHERE, false);
 
 	radix_init_iamr();
 	radix_init_pgtable();
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index f6f575b..80927ad 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -283,7 +283,11 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 
 	/* 601 can only access 16MB at the moment */
 	if (PVR_VER(mfspr(SPRN_PVR)) == 1)
-		memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01000000));
+		memblock_set_current_limit(0,
+			min_t(u64, first_memblock_size, 0x01000000),
+			false);
 	else /* Anything else has 256M mapped */
-		memblock_set_current_limit(min_t(u64, first_memblock_size, 0x10000000));
+		memblock_set_current_limit(0,
+			min_t(u64, first_memblock_size, 0x10000000),
+			false);
 }
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index ae5d568..d074362 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -735,7 +735,7 @@ static void __init early_mmu_set_memory_limit(void)
 		 * reduces the memory available to Linux.  We need to
 		 * do this because highmem is not supported on 64-bit.
 		 */
-		memblock_enforce_memory_limit(linear_map_top);
+		memblock_enforce_memory_limit(0, linear_map_top, false);
 	}
 #endif
 
@@ -792,7 +792,9 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 		ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
 
 	/* Finally limit subsequent allocations */
-	memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
+	memblock_set_current_limit(0,
+			first_memblock_base + ppc64_rma_size,
+			false);
 }
 #else /* ! CONFIG_PPC64 */
 void __init early_init_mmu(void)
diff --git a/arch/unicore32/mm/mmu.c b/arch/unicore32/mm/mmu.c
index 040a8c2..6d62529 100644
--- a/arch/unicore32/mm/mmu.c
+++ b/arch/unicore32/mm/mmu.c
@@ -286,7 +286,7 @@ static void __init sanity_check_meminfo(void)
 	int i, j;
 
 	lowmem_limit = __pa(vmalloc_min - 1) + 1;
-	memblock_set_current_limit(lowmem_limit);
+	memblock_set_current_limit(0, lowmem_limit, false);
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index dc8fc5d..a0122cd 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1130,7 +1130,7 @@ void __init setup_arch(char **cmdline_p)
 		memblock_set_bottom_up(true);
 #endif
 	init_mem_mapping();
-	memblock_set_current_limit(get_max_mapped());
+	memblock_set_current_limit(0, get_max_mapped(), false);
 
 	idt_setup_early_pf();
 
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 30a48bb..b924387 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -60,7 +60,7 @@ void __init bootmem_init(void)
 	max_pfn = PFN_DOWN(memblock_end_of_DRAM());
 	max_low_pfn = min(max_pfn, MAX_LOW_PFN);
 
-	memblock_set_current_limit(PFN_PHYS(max_low_pfn));
+	memblock_set_current_limit(0, PFN_PHYS(max_low_pfn), false);
 	dma_contiguous_reserve(PFN_PHYS(max_low_pfn));
 
 	memblock_dump_all();
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index aee299a..49676f0 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -88,6 +88,8 @@ struct memblock_type {
  */
 struct memblock {
 	bool bottom_up;  /* is bottom up direction? */
+	bool enforce_checking;
+	phys_addr_t start_limit;
 	phys_addr_t current_limit;
 	struct memblock_type memory;
 	struct memblock_type reserved;
@@ -482,12 +484,14 @@ static inline void memblock_dump_all(void)
  * memblock_set_current_limit - Set the current allocation limit to allow
  *                         limiting allocations to what is currently
  *                         accessible during boot
- * @limit: New limit value (physical address)
+ * [start_limit, end_limit]: New limit value (physical address)
+ * enforcing: whether check against the limit boundary or not
  */
-void memblock_set_current_limit(phys_addr_t limit);
+void memblock_set_current_limit(phys_addr_t start_limit,
+	phys_addr_t end_limit, bool enforcing);
 
 
-phys_addr_t memblock_get_current_limit(void);
+bool memblock_get_current_limit(phys_addr_t *start, phys_addr_t *end);
 
 /*
  * pfn conversion functions
diff --git a/mm/memblock.c b/mm/memblock.c
index 81ae63c..b792be0 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -116,6 +116,8 @@ struct memblock memblock __initdata_memblock = {
 #endif
 
 	.bottom_up		= false,
+	.enforce_checking	= false,
+	.start_limit		= 0,
 	.current_limit		= MEMBLOCK_ALLOC_ANYWHERE,
 };
 
@@ -261,8 +263,11 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
 {
 	phys_addr_t kernel_end, ret;
 
+	if (unlikely(memblock.enforce_checking)) {
+		start = memblock.start_limit;
+		end = memblock.current_limit;
 	/* pump up @end */
-	if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
+	} else if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
 		end = memblock.current_limit;
 
 	/* avoid allocating the first page */
@@ -1826,14 +1831,22 @@ void __init_memblock memblock_trim_memory(phys_addr_t align)
 	}
 }
 
-void __init_memblock memblock_set_current_limit(phys_addr_t limit)
+void __init_memblock memblock_set_current_limit(phys_addr_t start,
+	phys_addr_t end, bool enforcing)
 {
-	memblock.current_limit = limit;
+	memblock.start_limit = start;
+	memblock.current_limit = end;
+	memblock.enforce_checking = enforcing;
 }
 
-phys_addr_t __init_memblock memblock_get_current_limit(void)
+bool __init_memblock memblock_get_current_limit(phys_addr_t *start,
+	phys_addr_t *end)
 {
-	return memblock.current_limit;
+	if (start)
+		*start = memblock.start_limit;
+	if (end)
+		*end = memblock.current_limit;
+	return memblock.enforce_checking;
 }
 
 static void __init_memblock memblock_dump(struct memblock_type *type)
