aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/xen
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/xen')
-rw-r--r--sys/dev/xen/blkback/blkback.c21
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;