• Home
  • Raw
  • Download

Lines Matching +full:grant +full:- +full:dma

6  * Copyright (c) 2005-2006, Christopher Clark
7 * Copyright (c) 2004-2005, K A Fraser
49 #include <linux/dma-mapping.h>
57 #include <xen/hvc-console.h>
58 #include <xen/swiotlb-xen.h>
63 #include <xen/mem-reservation.h>
69 /* External tools reserve first few grant table entries. */
88 /*This is a structure of function pointers for grant table*/
91 * Version of the grant interface.
95 * Grant refs per grant frame.
99 * Mapping a list of frames for storing grant entries. Frames parameter
100 * is used to store grant table address when grant table being setup,
101 * nr_gframes is the number of frames to map grant table. Returning
106 * Release a list of frames which are mapped in map_frames for grant
111 * Introducing a valid entry into the grant table, granting the frame of
112 * this grant entry to domain for accessing or transfering. Ref
113 * parameter is reference of this introduced grant entry, domid is id of
115 * status of the grant entry to be updated.
120 * Stop granting a grant entry to domain for accessing. Ref parameter is
121 * reference of a grant entry whose grant access will be stopped,
122 * readonly is not in use in this function. If the grant entry is
124 * directly and don't tear down the grant access. Otherwise, stop grant
129 * Stop granting a grant entry to domain for transfer. Ref parameter is
130 * reference of a grant entry whose grant transfer will be stopped. If
131 * tranfer has not started, just reclaim the grant entry and return
137 * Read the frame number related to a given grant reference.
149 /* This reflects status of grant entries, so act as a global value. */
163 /* This can be used as an l-value */
175 ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) { in get_free_entries()
181 gnttab_free_count -= count; in get_free_entries()
182 while (count-- > 1) in get_free_entries()
200 next = callback->next; in do_free_callbacks()
201 if (gnttab_free_count >= callback->count) { in do_free_callbacks()
202 callback->next = NULL; in do_free_callbacks()
203 callback->fn(callback->arg); in do_free_callbacks()
205 callback->next = gnttab_free_callback_list; in do_free_callbacks()
231 * Introducing a valid entry into the grant table:
232 * 1. Write ent->domid.
233 * 2. Write ent->frame:
235 * GTF_accept_transfer: Pseudo-phys frame slot being filled by new
238 * 4. Write ent->flags, inc. valid type.
259 * Public grant-issuing interface functions
264 gnttab_interface->update_entry(ref, domid, frame, in gnttab_grant_foreign_access_ref()
276 return -ENOSPC; in gnttab_grant_foreign_access()
325 return gnttab_interface->end_foreign_access_ref(ref, readonly); in _gnttab_end_foreign_access_ref()
365 while (nr--) { in gnttab_handle_deferred()
372 list_del(&entry->list); in gnttab_handle_deferred()
374 if (_gnttab_end_foreign_access_ref(entry->ref, entry->ro)) { in gnttab_handle_deferred()
375 put_free_entry(entry->ref); in gnttab_handle_deferred()
377 entry->ref, page_to_pfn(entry->page)); in gnttab_handle_deferred()
378 put_page(entry->page); in gnttab_handle_deferred()
382 if (!--entry->warn_delay) in gnttab_handle_deferred()
383 pr_info("g.e. %#x still pending\n", entry->ref); in gnttab_handle_deferred()
389 list_add_tail(&entry->list, &deferred_list); in gnttab_handle_deferred()
409 unsigned long gfn = gnttab_interface->read_frame(ref); in gnttab_add_deferred()
418 entry->ref = ref; in gnttab_add_deferred()
419 entry->ro = readonly; in gnttab_add_deferred()
420 entry->page = page; in gnttab_add_deferred()
421 entry->warn_delay = 60; in gnttab_add_deferred()
423 list_add_tail(&entry->list, &deferred_list); in gnttab_add_deferred()
432 what, ref, page ? page_to_pfn(page) : -1); in gnttab_add_deferred()
464 return -ENOSPC; in gnttab_grant_foreign_transfer()
474 gnttab_interface->update_entry(ref, domid, pfn, GTF_accept_transfer); in gnttab_grant_foreign_transfer_ref()
487 * If a transfer is not even yet started, try to reclaim the grant in gnttab_end_foreign_transfer_ref_v1()
518 * If a transfer is not even yet started, try to reclaim the grant in gnttab_end_foreign_transfer_ref_v2()
542 return gnttab_interface->end_foreign_transfer_ref(ref); in gnttab_end_foreign_transfer_ref()
586 return -ENOSPC; in gnttab_alloc_grant_references()
604 return -ENOSPC; in gnttab_claim_grant_reference()
631 cb = cb->next; in gnttab_request_free_callback()
634 callback->fn = fn; in gnttab_request_free_callback()
635 callback->arg = arg; in gnttab_request_free_callback()
636 callback->count = count; in gnttab_request_free_callback()
637 callback->next = gnttab_free_callback_list; in gnttab_request_free_callback()
651 for (pcb = &gnttab_free_callback_list; *pcb; pcb = &(*pcb)->next) { in gnttab_cancel_free_callback()
653 *pcb = callback->next; in gnttab_cancel_free_callback()
663 return (frames * gnttab_interface->grefs_per_grant_frame + align - 1) / in gnttab_frames()
673 grefs_per_frame = gnttab_interface->grefs_per_grant_frame; in grow_gnttab_list()
688 i < grefs_per_frame * new_nr_grant_frames - 1; i++) in grow_gnttab_list()
702 while (i-- > nr_glist_frames) in grow_gnttab_list()
704 return -ENOMEM; in grow_gnttab_list()
744 return -EINVAL; in gnttab_setup_auto_xlat_frames()
750 return -ENOMEM; in gnttab_setup_auto_xlat_frames()
755 return -ENOMEM; in gnttab_setup_auto_xlat_frames()
791 return -ENOMEM; in gnttab_pages_set_private()
803 * gnttab_alloc_pages - alloc pages suitable for grant mapping into
826 cache->pages = NULL; in cache_init()
831 return !cache->pages; in cache_empty()
838 page = cache->pages; in cache_deq()
839 cache->pages = page->zone_device_data; in cache_deq()
846 page->zone_device_data = cache->pages; in cache_enq()
847 cache->pages = page; in cache_enq()
852 INIT_LIST_HEAD(&cache->pages); in cache_init()
857 return list_empty(&cache->pages); in cache_empty()
864 page = list_first_entry(&cache->pages, struct page, lru); in cache_deq()
865 list_del(&page->lru); in cache_deq()
872 list_add(&page->lru, &cache->pages); in cache_enq()
878 spin_lock_init(&cache->lock); in gnttab_page_cache_init()
880 cache->num_pages = 0; in gnttab_page_cache_init()
888 spin_lock_irqsave(&cache->lock, flags); in gnttab_page_cache_get()
891 spin_unlock_irqrestore(&cache->lock, flags); in gnttab_page_cache_get()
896 cache->num_pages--; in gnttab_page_cache_get()
898 spin_unlock_irqrestore(&cache->lock, flags); in gnttab_page_cache_get()
910 spin_lock_irqsave(&cache->lock, flags); in gnttab_page_cache_put()
914 cache->num_pages += num; in gnttab_page_cache_put()
916 spin_unlock_irqrestore(&cache->lock, flags); in gnttab_page_cache_put()
926 spin_lock_irqsave(&cache->lock, flags); in gnttab_page_cache_shrink()
928 while (cache->num_pages > num) { in gnttab_page_cache_shrink()
930 cache->num_pages--; in gnttab_page_cache_shrink()
932 spin_unlock_irqrestore(&cache->lock, flags); in gnttab_page_cache_shrink()
935 spin_lock_irqsave(&cache->lock, flags); in gnttab_page_cache_shrink()
939 spin_unlock_irqrestore(&cache->lock, flags); in gnttab_page_cache_shrink()
962 * gnttab_free_pages - free pages allocated by gnttab_alloc_pages()
975 * gnttab_dma_alloc_pages - alloc DMAable pages suitable for grant mapping into
984 if (args->nr_pages < 0 || args->nr_pages > (INT_MAX >> PAGE_SHIFT)) in gnttab_dma_alloc_pages()
985 return -ENOMEM; in gnttab_dma_alloc_pages()
987 size = args->nr_pages << PAGE_SHIFT; in gnttab_dma_alloc_pages()
988 if (args->coherent) in gnttab_dma_alloc_pages()
989 args->vaddr = dma_alloc_coherent(args->dev, size, in gnttab_dma_alloc_pages()
990 &args->dev_bus_addr, in gnttab_dma_alloc_pages()
993 args->vaddr = dma_alloc_wc(args->dev, size, in gnttab_dma_alloc_pages()
994 &args->dev_bus_addr, in gnttab_dma_alloc_pages()
996 if (!args->vaddr) { in gnttab_dma_alloc_pages()
997 pr_debug("Failed to allocate DMA buffer of size %zu\n", size); in gnttab_dma_alloc_pages()
998 return -ENOMEM; in gnttab_dma_alloc_pages()
1001 start_pfn = __phys_to_pfn(args->dev_bus_addr); in gnttab_dma_alloc_pages()
1002 for (pfn = start_pfn, i = 0; pfn < start_pfn + args->nr_pages; in gnttab_dma_alloc_pages()
1006 args->pages[i] = page; in gnttab_dma_alloc_pages()
1007 args->frames[i] = xen_page_to_gfn(page); in gnttab_dma_alloc_pages()
1011 xenmem_reservation_va_mapping_reset(args->nr_pages, args->pages); in gnttab_dma_alloc_pages()
1013 ret = xenmem_reservation_decrease(args->nr_pages, args->frames); in gnttab_dma_alloc_pages()
1014 if (ret != args->nr_pages) { in gnttab_dma_alloc_pages()
1015 pr_debug("Failed to decrease reservation for DMA buffer\n"); in gnttab_dma_alloc_pages()
1016 ret = -EFAULT; in gnttab_dma_alloc_pages()
1020 ret = gnttab_pages_set_private(args->nr_pages, args->pages); in gnttab_dma_alloc_pages()
1033 * gnttab_dma_free_pages - free DMAable pages
1041 gnttab_pages_clear_private(args->nr_pages, args->pages); in gnttab_dma_free_pages()
1043 for (i = 0; i < args->nr_pages; i++) in gnttab_dma_free_pages()
1044 args->frames[i] = page_to_xen_pfn(args->pages[i]); in gnttab_dma_free_pages()
1046 ret = xenmem_reservation_increase(args->nr_pages, args->frames); in gnttab_dma_free_pages()
1047 if (ret != args->nr_pages) { in gnttab_dma_free_pages()
1048 pr_debug("Failed to increase reservation for DMA buffer\n"); in gnttab_dma_free_pages()
1049 ret = -EFAULT; in gnttab_dma_free_pages()
1054 xenmem_reservation_va_mapping_update(args->nr_pages, args->pages, in gnttab_dma_free_pages()
1055 args->frames); in gnttab_dma_free_pages()
1057 size = args->nr_pages << PAGE_SHIFT; in gnttab_dma_free_pages()
1058 if (args->coherent) in gnttab_dma_free_pages()
1059 dma_free_coherent(args->dev, size, in gnttab_dma_free_pages()
1060 args->vaddr, args->dev_bus_addr); in gnttab_dma_free_pages()
1062 dma_free_wc(args->dev, size, in gnttab_dma_free_pages()
1063 args->vaddr, args->dev_bus_addr); in gnttab_dma_free_pages()
1069 /* Handling of paged out grant targets (GNTST_eagain) */
1084 pr_err("%s: %s eagain grant\n", func, current->comm); in gnttab_retry_eagain_gop()
1096 if (op->status == GNTST_eagain) in gnttab_batch_map()
1098 &op->status, __func__); in gnttab_batch_map()
1109 if (op->status == GNTST_eagain) in gnttab_batch_copy()
1111 &op->status, __func__); in gnttab_batch_copy()
1125 len = min_t(unsigned int, PAGE_SIZE - offset, len); in gnttab_foreach_grant_in_range()
1131 glen = min_t(unsigned int, XEN_PAGE_SIZE - goffset, len); in gnttab_foreach_grant_in_range()
1136 len -= glen; in gnttab_foreach_grant_in_range()
1181 foreign->domid = map_ops[i].dom; in gnttab_map_refs()
1182 foreign->gref = map_ops[i].ref; in gnttab_map_refs()
1196 i--; in gnttab_map_refs()
1236 if (unmap_data->age != UINT_MAX) in gnttab_unmap_work()
1237 unmap_data->age++; in gnttab_unmap_work()
1246 for (pc = 0; pc < item->count; pc++) { in __gnttab_unmap_refs_async()
1247 if (page_count(item->pages[pc]) > 1) { in __gnttab_unmap_refs_async()
1248 unsigned long delay = GNTTAB_UNMAP_REFS_DELAY * (item->age + 1); in __gnttab_unmap_refs_async()
1249 schedule_delayed_work(&item->gnttab_work, in __gnttab_unmap_refs_async()
1255 ret = gnttab_unmap_refs(item->unmap_ops, item->kunmap_ops, in __gnttab_unmap_refs_async()
1256 item->pages, item->count); in __gnttab_unmap_refs_async()
1257 item->done(ret, item); in __gnttab_unmap_refs_async()
1262 INIT_DELAYED_WORK(&item->gnttab_work, gnttab_unmap_work); in gnttab_unmap_refs_async()
1263 item->age = 0; in gnttab_unmap_refs_async()
1272 struct unmap_refs_callback_data *d = data->data; in unmap_refs_callback()
1274 d->result = result; in unmap_refs_callback()
1275 complete(&d->completion); in unmap_refs_callback()
1283 item->data = &data; in gnttab_unmap_refs_sync()
1284 item->done = &unmap_refs_callback; in gnttab_unmap_refs_sync()
1328 return -ENOMEM; in gnttab_map_frames_v2()
1336 if (rc == -ENOSYS) { in gnttab_map_frames_v2()
1338 return -ENOSYS; in gnttab_map_frames_v2()
1386 pr_warn("grant table add_to_physmap failed, err=%d\n", in gnttab_map()
1390 } while (i-- > start_idx); in gnttab_map()
1400 return -ENOMEM; in gnttab_map()
1407 if (rc == -ENOSYS) { in gnttab_map()
1409 return -ENOSYS; in gnttab_map()
1414 rc = gnttab_interface->map_frames(frames, nr_gframes); in gnttab_map()
1481 pr_info("Grant tables using version %d layout\n", in gnttab_request_version()
1482 gnttab_interface->version); in gnttab_request_version()
1491 return -ENOSYS; in gnttab_setup()
1497 return -ENOMEM; in gnttab_setup()
1500 return gnttab_map(0, nr_grant_frames - 1); in gnttab_setup()
1512 gnttab_interface->unmap_frames(); in gnttab_suspend()
1522 extra = ((req_entries + gnttab_interface->grefs_per_grant_frame - 1) / in gnttab_expand()
1523 gnttab_interface->grefs_per_grant_frame); in gnttab_expand()
1525 pr_warn_ratelimited("xen/grant-table: max_grant_frames reached" in gnttab_expand()
1530 return -ENOSPC; in gnttab_expand()
1533 rc = gnttab_map(cur, cur + extra - 1); in gnttab_expand()
1553 * grant reference free list on the current hypervisor. in gnttab_init()
1556 gnttab_interface->grefs_per_grant_frame / RPP); in gnttab_init()
1562 return -ENOMEM; in gnttab_init()
1568 ret = -ENOMEM; in gnttab_init()
1579 ret = -ENODEV; in gnttab_init()
1584 gnttab_interface->grefs_per_grant_frame; in gnttab_init()
1586 for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) in gnttab_init()
1589 gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; in gnttab_init()
1590 gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES; in gnttab_init()
1593 printk("Grant table initialized\n"); in gnttab_init()
1597 for (i--; i >= 0; i--) in gnttab_init()
1607 return -ENODEV; in __gnttab_init()
1609 /* Delay grant-table initialization in the PV on HVM case */ in __gnttab_init()