unsigned long attrs)
 {
        struct xen_grant_dma_data *data;
-       unsigned int i, n_pages = PFN_UP(offset + size);
+       unsigned long dma_offset = offset_in_page(offset),
+                       pfn_offset = PFN_DOWN(offset);
+       unsigned int i, n_pages = PFN_UP(dma_offset + size);
        grant_ref_t grant;
        dma_addr_t dma_handle;
 
 
        for (i = 0; i < n_pages; i++) {
                gnttab_grant_foreign_access_ref(grant + i, data->backend_domid,
-                               xen_page_to_gfn(page) + i, dir == DMA_TO_DEVICE);
+                               pfn_to_gfn(page_to_xen_pfn(page) + i + pfn_offset),
+                               dir == DMA_TO_DEVICE);
        }
 
-       dma_handle = grant_to_dma(grant) + offset;
+       dma_handle = grant_to_dma(grant) + dma_offset;
 
        return dma_handle;
 }