#endif /* CONFIG_CRASH_DUMP */
 
 /*
- * Return the maximum physical address for a zone with a given address size
- * limit. It currently assumes that for memory starting above 4G, 32-bit
- * devices will use a DMA offset.
+ * Return the maximum physical address for a zone accessible by the given bits
+ * limit. If DRAM starts above 32-bit, expand the zone to the maximum
+ * available memory, otherwise cap it at 32-bit.
  */
 static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
 {
-       phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
-       return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
+       phys_addr_t zone_mask = DMA_BIT_MASK(zone_bits);
+       phys_addr_t phys_start = memblock_start_of_DRAM();
+
+       if (phys_start > U32_MAX)
+               zone_mask = PHYS_ADDR_MAX;
+       else if (phys_start > zone_mask)
+               zone_mask = U32_MAX;
+
+       return min(zone_mask, memblock_end_of_DRAM() - 1) + 1;
 }
 
 static void __init zone_sizes_init(unsigned long min, unsigned long max)