aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/gntalloc.c
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-10-27 17:58:49 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-11-21 17:14:48 -0500
commit0cc678f850f2cba0cedbd133fcbbf175554cd6c6 (patch)
tree3289a7f4681c16c89b26612625b2f3f065f3186f /drivers/xen/gntalloc.c
parent8ca19a8937ad91703cfefccf13bd8017b39510cd (diff)
xen/gnt{dev,alloc}: reserve event channels for notify
When using the unmap notify ioctl, the event channel used for notification needs to be reserved to avoid it being deallocated prior to sending the notification. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen/gntalloc.c')
-rw-r--r--drivers/xen/gntalloc.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index 439352d094db..c95181f43a6a 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -178,8 +178,10 @@ static void __del_gref(struct gntalloc_gref *gref)
178 tmp[gref->notify.pgoff] = 0; 178 tmp[gref->notify.pgoff] = 0;
179 kunmap(gref->page); 179 kunmap(gref->page);
180 } 180 }
181 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) 181 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
182 notify_remote_via_evtchn(gref->notify.event); 182 notify_remote_via_evtchn(gref->notify.event);
183 evtchn_put(gref->notify.event);
184 }
183 185
184 gref->notify.flags = 0; 186 gref->notify.flags = 0;
185 187
@@ -396,6 +398,23 @@ static long gntalloc_ioctl_unmap_notify(struct gntalloc_file_private_data *priv,
396 goto unlock_out; 398 goto unlock_out;
397 } 399 }
398 400
401 /* We need to grab a reference to the event channel we are going to use
402 * to send the notify before releasing the reference we may already have
403 * (if someone has called this ioctl twice). This is required so that
404 * it is possible to change the clear_byte part of the notification
405 * without disturbing the event channel part, which may now be the last
406 * reference to that event channel.
407 */
408 if (op.action & UNMAP_NOTIFY_SEND_EVENT) {
409 if (evtchn_get(op.event_channel_port)) {
410 rc = -EINVAL;
411 goto unlock_out;
412 }
413 }
414
415 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
416 evtchn_put(gref->notify.event);
417
399 gref->notify.flags = op.action; 418 gref->notify.flags = op.action;
400 gref->notify.pgoff = pgoff; 419 gref->notify.pgoff = pgoff;
401 gref->notify.event = op.event_channel_port; 420 gref->notify.event = op.event_channel_port;