return false;
        if (xen_domain() && !xen_biovec_phys_mergeable(bv, page))
                return false;
+       if (!zone_device_pages_have_same_pgmap(bv->bv_page, page))
+               return false;
 
        *same_page = ((vec_end_addr & PAGE_MASK) == page_addr);
        if (*same_page)
 
 {
        return page_zonenum(page) == ZONE_DEVICE;
 }
+
+/*
+ * Consecutive zone device pages should not be merged into the same sgl
+ * or bvec segment with other types of pages or if they belong to different
+ * pgmaps. Otherwise getting the pgmap of a given segment is not possible
+ * without scanning the entire segment. This helper returns true either if
+ * both pages are not zone device pages or both pages are zone device pages
+ * with the same pgmap.
+ */
+static inline bool zone_device_pages_have_same_pgmap(const struct page *a,
+                                                    const struct page *b)
+{
+       if (is_zone_device_page(a) != is_zone_device_page(b))
+               return false;
+       if (!is_zone_device_page(a))
+               return true;
+       return a->pgmap == b->pgmap;
+}
+
 extern void memmap_init_zone_device(struct zone *, unsigned long,
                                    unsigned long, struct dev_pagemap *);
 #else
 {
        return false;
 }
+static inline bool zone_device_pages_have_same_pgmap(const struct page *a,
+                                                    const struct page *b)
+{
+       return true;
+}
 #endif
 
 static inline bool folio_is_zone_device(const struct folio *folio)