+static void
+pmalloc_update_lookup_table (clib_pmalloc_main_t * pm, u32 first, u32 count)
+{
+ uword seek, va, pa, p;
+ int fd;
+ u32 elts_per_page = 1U << (pm->def_log2_page_sz - pm->lookup_log2_page_sz);
+
+ vec_validate_aligned (pm->lookup_table, vec_len (pm->pages) *
+ elts_per_page - 1, CLIB_CACHE_LINE_BYTES);
+
+ p = first * elts_per_page;
+ if (pm->flags & CLIB_PMALLOC_F_NO_PAGEMAP)
+ {
+ while (p < (uword) elts_per_page * count)
+ {
+ pm->lookup_table[p] = pointer_to_uword (pm->base) +
+ (p << pm->lookup_log2_page_sz);
+ p++;
+ }
+ return;
+ }
+
+ fd = open ((char *) "/proc/self/pagemap", O_RDONLY);
+ while (p < (uword) elts_per_page * count)
+ {
+ va = pointer_to_uword (pm->base) + (p << pm->lookup_log2_page_sz);
+ pa = 0;
+ seek = (va >> pm->sys_log2_page_sz) * sizeof (pa);
+ if (fd != -1 && lseek (fd, seek, SEEK_SET) == seek &&
+ read (fd, &pa, sizeof (pa)) == (sizeof (pa)) &&
+ pa & (1ULL << 63) /* page present bit */ )
+ {
+ pa = (pa & pow2_mask (55)) << pm->sys_log2_page_sz;
+ }
+ pm->lookup_table[p] = va - pa;
+ p++;
+ }
+
+ if (fd != -1)
+ close (fd);
+}
+