*      (equal SECTION_SIZE_BITS - PAGE_SHIFT), and the
  *      worst combination is powerpc with 256k pages,
  *      which results in PFN_SECTION_SHIFT equal 6.
- * To sum it up, at least 6 bits are available.
+ * To sum it up, at least 6 bits are available on all architectures.
+ * However, we can exceed 6 bits on some other architectures except
+ * powerpc (e.g. 15 bits are available on x86_64, 13 bits are available
+ * with the worst case of 64K pages on arm64) if we make sure the
+ * exceeded bit is not applicable to powerpc.
  */
-#define SECTION_MARKED_PRESENT         (1UL<<0)
-#define SECTION_HAS_MEM_MAP            (1UL<<1)
-#define SECTION_IS_ONLINE              (1UL<<2)
-#define SECTION_IS_EARLY               (1UL<<3)
-#define SECTION_TAINT_ZONE_DEVICE      (1UL<<4)
-#define SECTION_MAP_LAST_BIT           (1UL<<5)
-#define SECTION_MAP_MASK               (~(SECTION_MAP_LAST_BIT-1))
-#define SECTION_NID_SHIFT              6
+enum {
+       SECTION_MARKED_PRESENT_BIT,
+       SECTION_HAS_MEM_MAP_BIT,
+       SECTION_IS_ONLINE_BIT,
+       SECTION_IS_EARLY_BIT,
+#ifdef CONFIG_ZONE_DEVICE
+       SECTION_TAINT_ZONE_DEVICE_BIT,
+#endif
+       SECTION_MAP_LAST_BIT,
+};
+
+#define SECTION_MARKED_PRESENT         BIT(SECTION_MARKED_PRESENT_BIT)
+#define SECTION_HAS_MEM_MAP            BIT(SECTION_HAS_MEM_MAP_BIT)
+#define SECTION_IS_ONLINE              BIT(SECTION_IS_ONLINE_BIT)
+#define SECTION_IS_EARLY               BIT(SECTION_IS_EARLY_BIT)
+#ifdef CONFIG_ZONE_DEVICE
+#define SECTION_TAINT_ZONE_DEVICE      BIT(SECTION_TAINT_ZONE_DEVICE_BIT)
+#endif
+#define SECTION_MAP_MASK               (~(BIT(SECTION_MAP_LAST_BIT) - 1))
+#define SECTION_NID_SHIFT              SECTION_MAP_LAST_BIT
 
 static inline struct page *__section_mem_map_addr(struct mem_section *section)
 {
        return (section && (section->section_mem_map & SECTION_IS_ONLINE));
 }
 
+#ifdef CONFIG_ZONE_DEVICE
 static inline int online_device_section(struct mem_section *section)
 {
        unsigned long flags = SECTION_IS_ONLINE | SECTION_TAINT_ZONE_DEVICE;
 
        return section && ((section->section_mem_map & flags) == flags);
 }
+#else
+static inline int online_device_section(struct mem_section *section)
+{
+       return 0;
+}
+#endif
 
 static inline int online_section_nr(unsigned long nr)
 {