| 983 | } |
| 984 | |
| 985 | static int |
| 986 | add_one_guest_page(struct virtio_net *dev, uint64_t guest_phys_addr, |
| 987 | uint64_t host_iova, uint64_t host_user_addr, uint64_t size) |
| 988 | { |
| 989 | struct guest_page *page, *last_page; |
| 990 | struct guest_page *old_pages; |
| 991 | |
| 992 | if (dev->nr_guest_pages == dev->max_guest_pages) { |
| 993 | dev->max_guest_pages *= 2; |
| 994 | old_pages = dev->guest_pages; |
| 995 | dev->guest_pages = rte_realloc(dev->guest_pages, |
| 996 | dev->max_guest_pages * sizeof(*page), |
| 997 | RTE_CACHE_LINE_SIZE); |
| 998 | if (dev->guest_pages == NULL) { |
| 999 | VHOST_LOG_CONFIG(dev->ifname, ERR, "cannot realloc guest_pages\n"); |
| 1000 | rte_free(old_pages); |
| 1001 | return -1; |
| 1002 | } |
| 1003 | } |
| 1004 | |
| 1005 | if (dev->nr_guest_pages > 0) { |
| 1006 | last_page = &dev->guest_pages[dev->nr_guest_pages - 1]; |
| 1007 | /* merge if the two pages are continuous */ |
| 1008 | if (host_iova == last_page->host_iova + last_page->size && |
| 1009 | guest_phys_addr == last_page->guest_phys_addr + last_page->size && |
| 1010 | host_user_addr == last_page->host_user_addr + last_page->size) { |
| 1011 | last_page->size += size; |
| 1012 | return 0; |
| 1013 | } |
| 1014 | } |
| 1015 | |
| 1016 | page = &dev->guest_pages[dev->nr_guest_pages++]; |
| 1017 | page->guest_phys_addr = guest_phys_addr; |
| 1018 | page->host_iova = host_iova; |
| 1019 | page->host_user_addr = host_user_addr; |
| 1020 | page->size = size; |
| 1021 | |
| 1022 | return 0; |
| 1023 | } |
| 1024 | |
| 1025 | static int |
| 1026 | add_guest_pages(struct virtio_net *dev, struct rte_vhost_mem_region *reg, |
no test coverage detected