aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen/gntdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen/gntdev.c')
-rw-r--r--drivers/xen/gntdev.c38
1 files changed, 5 insertions, 33 deletions
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index d96d311b858e..017ce600fbc6 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -36,6 +36,7 @@
36 36
37#include <xen/xen.h> 37#include <xen/xen.h>
38#include <xen/grant_table.h> 38#include <xen/grant_table.h>
39#include <xen/balloon.h>
39#include <xen/gntdev.h> 40#include <xen/gntdev.h>
40#include <xen/events.h> 41#include <xen/events.h>
41#include <asm/xen/hypervisor.h> 42#include <asm/xen/hypervisor.h>
@@ -122,10 +123,10 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
122 NULL == add->pages) 123 NULL == add->pages)
123 goto err; 124 goto err;
124 125
126 if (alloc_xenballooned_pages(count, add->pages))
127 goto err;
128
125 for (i = 0; i < count; i++) { 129 for (i = 0; i < count; i++) {
126 add->pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
127 if (add->pages[i] == NULL)
128 goto err;
129 add->map_ops[i].handle = -1; 130 add->map_ops[i].handle = -1;
130 add->unmap_ops[i].handle = -1; 131 add->unmap_ops[i].handle = -1;
131 } 132 }
@@ -137,11 +138,6 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
137 return add; 138 return add;
138 139
139err: 140err:
140 if (add->pages)
141 for (i = 0; i < count; i++) {
142 if (add->pages[i])
143 __free_page(add->pages[i]);
144 }
145 kfree(add->pages); 141 kfree(add->pages);
146 kfree(add->grants); 142 kfree(add->grants);
147 kfree(add->map_ops); 143 kfree(add->map_ops);
@@ -184,8 +180,6 @@ static struct grant_map *gntdev_find_map_index(struct gntdev_priv *priv,
184 180
185static void gntdev_put_map(struct grant_map *map) 181static void gntdev_put_map(struct grant_map *map)
186{ 182{
187 int i;
188
189 if (!map) 183 if (!map)
190 return; 184 return;
191 185
@@ -202,29 +196,7 @@ static void gntdev_put_map(struct grant_map *map)
202 if (!use_ptemod) 196 if (!use_ptemod)
203 unmap_grant_pages(map, 0, map->count); 197 unmap_grant_pages(map, 0, map->count);
204 198
205 for (i = 0; i < map->count; i++) { 199 free_xenballooned_pages(map->count, map->pages);
206 uint32_t check, *tmp;
207 if (!map->pages[i])
208 continue;
209 /* XXX When unmapping in an HVM domain, Xen will
210 * sometimes end up mapping the GFN to an invalid MFN.
211 * In this case, writes will be discarded and reads will
212 * return all 0xFF bytes. Leak these unusable GFNs
213 * until Xen supports fixing their p2m mapping.
214 *
215 * Confirmed present in Xen 4.1-RC3 with HVM source
216 */
217 tmp = kmap(map->pages[i]);
218 *tmp = 0xdeaddead;
219 mb();
220 check = *tmp;
221 kunmap(map->pages[i]);
222 if (check == 0xdeaddead)
223 __free_page(map->pages[i]);
224 else
225 pr_debug("Discard page %d=%ld\n", i,
226 page_to_pfn(map->pages[i]));
227 }
228 } 200 }
229 kfree(map->pages); 201 kfree(map->pages);
230 kfree(map->grants); 202 kfree(map->grants);