goto out;
 
        mmput(mm);
+       kfree(umem->pages);
+       umem->pages = NULL;
+
        xdp_umem_unaccount_pages(umem);
 out:
        kfree(umem);
        u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
        unsigned int chunks, chunks_per_page;
        u64 addr = mr->addr, size = mr->len;
-       int size_chk, err;
+       int size_chk, err, i;
 
        if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
                /* Strictly speaking we could support this, if:
        err = xdp_umem_pin_pages(umem);
        if (err)
                goto out_account;
+
+       umem->pages = kcalloc(umem->npgs, sizeof(*umem->pages), GFP_KERNEL);
+       if (!umem->pages) {
+               err = -ENOMEM;
+               goto out_account;
+       }
+
+       for (i = 0; i < umem->npgs; i++)
+               umem->pages[i].addr = page_address(umem->pgs[i]);
+
        return 0;
 
 out_account:
 
 
 static inline char *xdp_umem_get_data(struct xdp_umem *umem, u64 addr)
 {
-       return page_address(umem->pgs[addr >> PAGE_SHIFT]) +
-               (addr & (PAGE_SIZE - 1));
+       return umem->pages[addr >> PAGE_SHIFT].addr + (addr & (PAGE_SIZE - 1));
 }
 
 bool xdp_umem_validate_queues(struct xdp_umem *umem);