Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 282072
b: refs/heads/master
c: 0cc678f
h: refs/heads/master
v: v3
  • Loading branch information
Daniel De Graaf authored and Konrad Rzeszutek Wilk committed Nov 21, 2011
1 parent 82a36a0 commit 7902edd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8ca19a8937ad91703cfefccf13bd8017b39510cd
refs/heads/master: 0cc678f850f2cba0cedbd133fcbbf175554cd6c6
21 changes: 20 additions & 1 deletion trunk/drivers/xen/gntalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,10 @@ static void __del_gref(struct gntalloc_gref *gref)
tmp[gref->notify.pgoff] = 0;
kunmap(gref->page);
}
if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
notify_remote_via_evtchn(gref->notify.event);
evtchn_put(gref->notify.event);
}

gref->notify.flags = 0;

Expand Down Expand Up @@ -396,6 +398,23 @@ static long gntalloc_ioctl_unmap_notify(struct gntalloc_file_private_data *priv,
goto unlock_out;
}

/* We need to grab a reference to the event channel we are going to use
* to send the notify before releasing the reference we may already have
* (if someone has called this ioctl twice). This is required so that
* it is possible to change the clear_byte part of the notification
* without disturbing the event channel part, which may now be the last
* reference to that event channel.
*/
if (op.action & UNMAP_NOTIFY_SEND_EVENT) {
if (evtchn_get(op.event_channel_port)) {
rc = -EINVAL;
goto unlock_out;
}
}

if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
evtchn_put(gref->notify.event);

gref->notify.flags = op.action;
gref->notify.pgoff = pgoff;
gref->notify.event = op.event_channel_port;
Expand Down
31 changes: 30 additions & 1 deletion trunk/drivers/xen/gntdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,10 @@ static void gntdev_put_map(struct grant_map *map)

atomic_sub(map->count, &pages_mapped);

if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT)
if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
notify_remote_via_evtchn(map->notify.event);
evtchn_put(map->notify.event);
}

if (map->pages) {
if (!use_ptemod)
Expand Down Expand Up @@ -599,13 +601,30 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
struct ioctl_gntdev_unmap_notify op;
struct grant_map *map;
int rc;
int out_flags;
unsigned int out_event;

if (copy_from_user(&op, u, sizeof(op)))
return -EFAULT;

if (op.action & ~(UNMAP_NOTIFY_CLEAR_BYTE|UNMAP_NOTIFY_SEND_EVENT))
return -EINVAL;

/* We need to grab a reference to the event channel we are going to use
* to send the notify before releasing the reference we may already have
* (if someone has called this ioctl twice). This is required so that
* it is possible to change the clear_byte part of the notification
* without disturbing the event channel part, which may now be the last
* reference to that event channel.
*/
if (op.action & UNMAP_NOTIFY_SEND_EVENT) {
if (evtchn_get(op.event_channel_port))
return -EINVAL;
}

out_flags = op.action;
out_event = op.event_channel_port;

spin_lock(&priv->lock);

list_for_each_entry(map, &priv->maps, next) {
Expand All @@ -624,12 +643,22 @@ static long gntdev_ioctl_notify(struct gntdev_priv *priv, void __user *u)
goto unlock_out;
}

out_flags = map->notify.flags;
out_event = map->notify.event;

map->notify.flags = op.action;
map->notify.addr = op.index - (map->index << PAGE_SHIFT);
map->notify.event = op.event_channel_port;

rc = 0;

unlock_out:
spin_unlock(&priv->lock);

/* Drop the reference to the event channel we did not save in the map */
if (out_flags & UNMAP_NOTIFY_SEND_EVENT)
evtchn_put(out_event);

return rc;
}

Expand Down

0 comments on commit 7902edd

Please sign in to comment.