.. | .. |
---|
169 | 169 | __del_gref(gref); |
---|
170 | 170 | } |
---|
171 | 171 | |
---|
172 | | - /* It's possible for the target domain to map the just-allocated grant |
---|
173 | | - * references by blindly guessing their IDs; if this is done, then |
---|
174 | | - * __del_gref will leave them in the queue_gref list. They need to be |
---|
175 | | - * added to the global list so that we can free them when they are no |
---|
176 | | - * longer referenced. |
---|
177 | | - */ |
---|
178 | | - if (unlikely(!list_empty(&queue_gref))) |
---|
179 | | - list_splice_tail(&queue_gref, &gref_list); |
---|
180 | 172 | mutex_unlock(&gref_mutex); |
---|
181 | 173 | return rc; |
---|
182 | 174 | } |
---|
183 | 175 | |
---|
184 | 176 | static void __del_gref(struct gntalloc_gref *gref) |
---|
185 | 177 | { |
---|
| 178 | + unsigned long addr; |
---|
| 179 | + |
---|
186 | 180 | if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { |
---|
187 | 181 | uint8_t *tmp = kmap(gref->page); |
---|
188 | 182 | tmp[gref->notify.pgoff] = 0; |
---|
.. | .. |
---|
196 | 190 | gref->notify.flags = 0; |
---|
197 | 191 | |
---|
198 | 192 | if (gref->gref_id) { |
---|
199 | | - if (gnttab_query_foreign_access(gref->gref_id)) |
---|
200 | | - return; |
---|
201 | | - |
---|
202 | | - if (!gnttab_end_foreign_access_ref(gref->gref_id, 0)) |
---|
203 | | - return; |
---|
204 | | - |
---|
205 | | - gnttab_free_grant_reference(gref->gref_id); |
---|
| 193 | + if (gref->page) { |
---|
| 194 | + addr = (unsigned long)page_to_virt(gref->page); |
---|
| 195 | + gnttab_end_foreign_access(gref->gref_id, 0, addr); |
---|
| 196 | + } else |
---|
| 197 | + gnttab_free_grant_reference(gref->gref_id); |
---|
206 | 198 | } |
---|
207 | 199 | |
---|
208 | 200 | gref_size--; |
---|
209 | 201 | list_del(&gref->next_gref); |
---|
210 | | - |
---|
211 | | - if (gref->page) |
---|
212 | | - __free_page(gref->page); |
---|
213 | 202 | |
---|
214 | 203 | kfree(gref); |
---|
215 | 204 | } |
---|