Skip to content

Commit 0e38268

Browse files
jbeulichgregkh
authored andcommitted
Xen/gntdev: correct dev_bus_addr handling in gntdev_map_grant_pages()
commit dbe5283 upstream. We may not skip setting the field in the unmap structure when GNTMAP_device_map is in use - such an unmap would fail to release the respective resources (a page ref in the hypervisor). Otoh the field doesn't need setting at all when GNTMAP_device_map is not in use. To record the value for unmapping, we also better don't use our local p2m: In particular after a subsequent change it may not have got updated for all the batch elements. Instead it can simply be taken from the respective map's results. We can additionally avoid playing this game altogether for the kernel part of the mappings in (x86) PV mode. This is part of XSA-361. Signed-off-by: Jan Beulich <jbeulich@suse.com> Cc: stable@vger.kernel.org Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Juergen Gross <jgross@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent da92e41 commit 0e38268

1 file changed

Lines changed: 13 additions & 11 deletions

File tree

drivers/xen/gntdev.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -319,18 +319,25 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
319319
* to the kernel linear addresses of the struct pages.
320320
* These ptes are completely different from the user ptes dealt
321321
* with find_grant_ptes.
322+
* Note that GNTMAP_device_map isn't needed here: The
323+
* dev_bus_addr output field gets consumed only from ->map_ops,
324+
* and by not requesting it when mapping we also avoid needing
325+
* to mirror dev_bus_addr into ->unmap_ops (and holding an extra
326+
* reference to the page in the hypervisor).
322327
*/
328+
unsigned int flags = (map->flags & ~GNTMAP_device_map) |
329+
GNTMAP_host_map;
330+
323331
for (i = 0; i < map->count; i++) {
324332
unsigned long address = (unsigned long)
325333
pfn_to_kaddr(page_to_pfn(map->pages[i]));
326334
BUG_ON(PageHighMem(map->pages[i]));
327335

328-
gnttab_set_map_op(&map->kmap_ops[i], address,
329-
map->flags | GNTMAP_host_map,
336+
gnttab_set_map_op(&map->kmap_ops[i], address, flags,
330337
map->grants[i].ref,
331338
map->grants[i].domid);
332339
gnttab_set_unmap_op(&map->kunmap_ops[i], address,
333-
map->flags | GNTMAP_host_map, -1);
340+
flags, -1);
334341
}
335342
}
336343

@@ -346,17 +353,12 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
346353
continue;
347354
}
348355

356+
if (map->flags & GNTMAP_device_map)
357+
map->unmap_ops[i].dev_bus_addr = map->map_ops[i].dev_bus_addr;
358+
349359
map->unmap_ops[i].handle = map->map_ops[i].handle;
350360
if (use_ptemod)
351361
map->kunmap_ops[i].handle = map->kmap_ops[i].handle;
352-
#ifdef CONFIG_XEN_GRANT_DMA_ALLOC
353-
else if (map->dma_vaddr) {
354-
unsigned long bfn;
355-
356-
bfn = pfn_to_bfn(page_to_pfn(map->pages[i]));
357-
map->unmap_ops[i].dev_bus_addr = __pfn_to_phys(bfn);
358-
}
359-
#endif
360362
}
361363
return err;
362364
}

0 commit comments

Comments
 (0)