Commit 49f8b459 authored by Juergen Gross's avatar Juergen Gross
Browse files

xen: switch gnttab_end_foreign_access() to take a struct page pointer



Instead of a virtual kernel address use a pointer of the associated
struct page as second parameter of gnttab_end_foreign_access().

Most users have that pointer available already and are creating the
virtual address from it, risking problems in case the memory is
located in highmem.

gnttab_end_foreign_access() itself won't need to get the struct page
from the address again.

Suggested-by: default avatarJan Beulich <jbeulich@suse.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarJan Beulich <jbeulich@suse.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent 5b335394
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1221,7 +1221,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
			list_del(&persistent_gnt->node);
			if (persistent_gnt->gref != INVALID_GRANT_REF) {
				gnttab_end_foreign_access(persistent_gnt->gref,
							  0UL);
							  NULL);
				rinfo->persistent_gnts_c--;
			}
			if (info->feature_persistent)
@@ -1244,7 +1244,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)
		       rinfo->shadow[i].req.u.rw.nr_segments;
		for (j = 0; j < segs; j++) {
			persistent_gnt = rinfo->shadow[i].grants_used[j];
			gnttab_end_foreign_access(persistent_gnt->gref, 0UL);
			gnttab_end_foreign_access(persistent_gnt->gref, NULL);
			if (info->feature_persistent)
				__free_page(persistent_gnt->page);
			kfree(persistent_gnt);
@@ -1259,7 +1259,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo)

		for (j = 0; j < INDIRECT_GREFS(segs); j++) {
			persistent_gnt = rinfo->shadow[i].indirect_grants[j];
			gnttab_end_foreign_access(persistent_gnt->gref, 0UL);
			gnttab_end_foreign_access(persistent_gnt->gref, NULL);
			__free_page(persistent_gnt->page);
			kfree(persistent_gnt);
		}
+2 −2
Original line number Diff line number Diff line
@@ -481,7 +481,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
 error_evtchan:
	xenbus_free_evtchn(dev, evtchn);
 error_grant:
	gnttab_end_foreign_access(info->gref, 0UL);
	gnttab_end_foreign_access(info->gref, NULL);
	info->gref = -1;
	return ret;
}
@@ -492,7 +492,7 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *info)
		unbind_from_irqhandler(info->irq, info);
	info->irq = -1;
	if (info->gref >= 0)
		gnttab_end_foreign_access(info->gref, 0UL);
		gnttab_end_foreign_access(info->gref, NULL);
	info->gref = -1;
}

+3 −4
Original line number Diff line number Diff line
@@ -1386,7 +1386,7 @@ static void xennet_release_tx_bufs(struct netfront_queue *queue)
		queue->tx_skbs[i] = NULL;
		get_page(queue->grant_tx_page[i]);
		gnttab_end_foreign_access(queue->grant_tx_ref[i],
					  (unsigned long)page_address(queue->grant_tx_page[i]));
					  queue->grant_tx_page[i]);
		queue->grant_tx_page[i] = NULL;
		queue->grant_tx_ref[i] = INVALID_GRANT_REF;
		add_id_to_list(&queue->tx_skb_freelist, queue->tx_link, i);
@@ -1418,8 +1418,7 @@ static void xennet_release_rx_bufs(struct netfront_queue *queue)
		 * foreign access is ended (which may be deferred).
		 */
		get_page(page);
		gnttab_end_foreign_access(ref,
					  (unsigned long)page_address(page));
		gnttab_end_foreign_access(ref, page);
		queue->grant_rx_ref[id] = INVALID_GRANT_REF;

		kfree_skb(skb);
@@ -1760,7 +1759,7 @@ static void xennet_end_access(int ref, void *page)
{
	/* This frees the page as a side-effect */
	if (ref != INVALID_GRANT_REF)
		gnttab_end_foreign_access(ref, (unsigned long)page);
		gnttab_end_foreign_access(ref, virt_to_page(page));
}

static void xennet_disconnect_backend(struct netfront_info *info)
+3 −6
Original line number Diff line number Diff line
@@ -175,8 +175,6 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,

static void __del_gref(struct gntalloc_gref *gref)
{
	unsigned long addr;

	if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) {
		uint8_t *tmp = kmap_local_page(gref->page);
		tmp[gref->notify.pgoff] = 0;
@@ -190,10 +188,9 @@ static void __del_gref(struct gntalloc_gref *gref)
	gref->notify.flags = 0;

	if (gref->gref_id) {
		if (gref->page) {
			addr = (unsigned long)page_to_virt(gref->page);
			gnttab_end_foreign_access(gref->gref_id, addr);
		} else
		if (gref->page)
			gnttab_end_foreign_access(gref->gref_id, gref->page);
		else
			gnttab_free_grant_reference(gref->gref_id);
	}

+1 −1
Original line number Diff line number Diff line
@@ -524,7 +524,7 @@ static void dmabuf_imp_end_foreign_access(u32 *refs, int count)

	for (i = 0; i < count; i++)
		if (refs[i] != INVALID_GRANT_REF)
			gnttab_end_foreign_access(refs[i], 0UL);
			gnttab_end_foreign_access(refs[i], NULL);
}

static void dmabuf_imp_free_storage(struct gntdev_dmabuf *gntdev_dmabuf)
Loading