diff options
Diffstat (limited to 'sys/dev/xen')
-rw-r--r-- | sys/dev/xen/blkback/blkback.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index d935ba965b00..b98ccb6e2595 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -2912,10 +2912,31 @@ xbb_connect_ring(struct xbb_softc *xbb) ring_idx < xbb->ring_config.ring_pages; ring_idx++, gnt++) { if (gnt->status != 0) { + struct gnttab_unmap_grant_ref unmap[XBB_MAX_RING_PAGES]; + unsigned int i, j; + xbb->ring_config.va = 0; xenbus_dev_fatal(xbb->dev, EACCES, "Ring shared page mapping failed. " "Status %d.", gnt->status); + + /* Unmap everything to avoid leaking grant table maps */ + for (i = 0, j = 0; i < xbb->ring_config.ring_pages; + i++) { + if (gnts[i].status != GNTST_okay) + continue; + + unmap[j].host_addr = gnts[i].host_addr; + unmap[j].dev_bus_addr = gnts[i].dev_bus_addr; + unmap[j++].handle = gnts[i].handle; + } + if (j != 0) { + error = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, j); + if (error != 0) + panic("Unable to unmap grants (%d)", + error); + } return (EACCES); } xbb->ring_config.handle[ring_idx] = gnt->handle; |