-
struct remap_data {
xen_pfn_t *fgmfn; /* foreign domain's gmfn */
+ xen_pfn_t *efgmfn; /* pointer to the end of the fgmfn array */
+static int unmap_gfn(struct page *page, unsigned long pfn, void *data)
+{
+ int *nr = data;
+ struct xen_remove_from_physmap xrp;
+
+ /* The Linux Page may not have been fully mapped to Xen */
+ if (!*nr)
+ return 0;
+
+ xrp.domid = DOMID_SELF;
+ xrp.gpfn = pfn;
+ (void)HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
+
+ (*nr)--;
+
+ return 0;
+}
+
int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
int nr, struct page **pages)
{
int i;
+ int nr_page = round_up(nr, XEN_PFN_PER_PAGE);
- for (i = 0; i < nr; i++) {
- struct xen_remove_from_physmap xrp;
- unsigned long pfn;
+ for (i = 0; i < nr_page; i++) {
+ /* unmap_gfn guarantees ret == 0 */
+ BUG_ON(xen_apply_to_page(pages[i], unmap_gfn, &nr));