diff options
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/gntdev.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index aba76d437ea8..1e31cdcdae1e 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -71,6 +71,7 @@ struct grant_map { | |||
71 | struct ioctl_gntdev_grant_ref *grants; | 71 | struct ioctl_gntdev_grant_ref *grants; |
72 | struct gnttab_map_grant_ref *map_ops; | 72 | struct gnttab_map_grant_ref *map_ops; |
73 | struct gnttab_unmap_grant_ref *unmap_ops; | 73 | struct gnttab_unmap_grant_ref *unmap_ops; |
74 | struct page **pages; | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | /* ------------------------------------------------------------------ */ | 77 | /* ------------------------------------------------------------------ */ |
@@ -94,6 +95,7 @@ static void gntdev_print_maps(struct gntdev_priv *priv, | |||
94 | static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | 95 | static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) |
95 | { | 96 | { |
96 | struct grant_map *add; | 97 | struct grant_map *add; |
98 | int i; | ||
97 | 99 | ||
98 | add = kzalloc(sizeof(struct grant_map), GFP_KERNEL); | 100 | add = kzalloc(sizeof(struct grant_map), GFP_KERNEL); |
99 | if (NULL == add) | 101 | if (NULL == add) |
@@ -102,11 +104,19 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | |||
102 | add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL); | 104 | add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL); |
103 | add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL); | 105 | add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL); |
104 | add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); | 106 | add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); |
105 | if (NULL == add->grants || | 107 | add->pages = kzalloc(sizeof(add->pages[0]) * count, GFP_KERNEL); |
106 | NULL == add->map_ops || | 108 | if (NULL == add->grants || |
107 | NULL == add->unmap_ops) | 109 | NULL == add->map_ops || |
110 | NULL == add->unmap_ops || | ||
111 | NULL == add->pages) | ||
108 | goto err; | 112 | goto err; |
109 | 113 | ||
114 | for (i = 0; i < count; i++) { | ||
115 | add->pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); | ||
116 | if (add->pages[i] == NULL) | ||
117 | goto err; | ||
118 | } | ||
119 | |||
110 | add->index = 0; | 120 | add->index = 0; |
111 | add->count = count; | 121 | add->count = count; |
112 | add->priv = priv; | 122 | add->priv = priv; |
@@ -117,6 +127,12 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | |||
117 | return add; | 127 | return add; |
118 | 128 | ||
119 | err: | 129 | err: |
130 | if (add->pages) | ||
131 | for (i = 0; i < count; i++) { | ||
132 | if (add->pages[i]) | ||
133 | __free_page(add->pages[i]); | ||
134 | } | ||
135 | kfree(add->pages); | ||
120 | kfree(add->grants); | 136 | kfree(add->grants); |
121 | kfree(add->map_ops); | 137 | kfree(add->map_ops); |
122 | kfree(add->unmap_ops); | 138 | kfree(add->unmap_ops); |
@@ -191,8 +207,17 @@ static int gntdev_del_map(struct grant_map *map) | |||
191 | 207 | ||
192 | static void gntdev_free_map(struct grant_map *map) | 208 | static void gntdev_free_map(struct grant_map *map) |
193 | { | 209 | { |
210 | int i; | ||
211 | |||
194 | if (!map) | 212 | if (!map) |
195 | return; | 213 | return; |
214 | |||
215 | if (map->pages) | ||
216 | for (i = 0; i < map->count; i++) { | ||
217 | if (map->pages[i]) | ||
218 | __free_page(map->pages[i]); | ||
219 | } | ||
220 | kfree(map->pages); | ||
196 | kfree(map->grants); | 221 | kfree(map->grants); |
197 | kfree(map->map_ops); | 222 | kfree(map->map_ops); |
198 | kfree(map->unmap_ops); | 223 | kfree(map->unmap_ops); |
@@ -226,8 +251,7 @@ static int map_grant_pages(struct grant_map *map) | |||
226 | int i, err = 0; | 251 | int i, err = 0; |
227 | 252 | ||
228 | pr_debug("map %d+%d\n", map->index, map->count); | 253 | pr_debug("map %d+%d\n", map->index, map->count); |
229 | err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, | 254 | err = gnttab_map_refs(map->map_ops, map->pages, map->count); |
230 | map->map_ops, map->count); | ||
231 | if (err) | 255 | if (err) |
232 | return err; | 256 | return err; |
233 | 257 | ||
@@ -244,8 +268,7 @@ static int unmap_grant_pages(struct grant_map *map, int offset, int pages) | |||
244 | int i, err = 0; | 268 | int i, err = 0; |
245 | 269 | ||
246 | pr_debug("map %d+%d [%d+%d]\n", map->index, map->count, offset, pages); | 270 | pr_debug("map %d+%d [%d+%d]\n", map->index, map->count, offset, pages); |
247 | err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, | 271 | err = gnttab_unmap_refs(map->unmap_ops + offset, map->pages, pages); |
248 | map->unmap_ops + offset, pages); | ||
249 | if (err) | 272 | if (err) |
250 | return err; | 273 | return err; |
251 | 274 | ||