Message ID | 20181210094454.21144-5-jasowang@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix various issue of vhost | expand |
Hi Jason, I love your patch! Perhaps something to improve: [auto build test WARNING on net/master] url: https://github.com/0day-ci/linux/commits/Jason-Wang/Fix-various-issue-of-vhost/20181210-223236 config: i386-randconfig-x072-201849 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): drivers//vhost/vhost.c: In function 'log_used': >> drivers//vhost/vhost.c:1771:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] ret = translate_desc(vq, (u64)vq->used + used_offset, len, iov, 64, ^ drivers//vhost/vhost.c:1776:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] ret = log_write_hva(vq, (u64)iov[i].iov_base, iov[i].iov_len); ^ drivers//vhost/vhost.c: In function 'vhost_log_write': drivers//vhost/vhost.c:1788:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] r = log_write_hva(vq, (u64)iov[i].iov_base, ^ Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size Cyclomatic Complexity 1 arch/x86/include/asm/barrier.h:array_index_mask_nospec Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_read Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_write Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:set_bit Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:clear_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_set_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32 Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD Cyclomatic Complexity 1 include/linux/list.h:__list_del Cyclomatic Complexity 1 include/linux/list.h:list_empty Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current Cyclomatic Complexity 3 include/linux/string.h:memset Cyclomatic Complexity 5 include/linux/string.h:memcpy Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_dec_and_test Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_dec_and_test Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR Cyclomatic Complexity 1 include/linux/thread_info.h:set_ti_thread_flag Cyclomatic Complexity 1 include/linux/thread_info.h:check_object_size Cyclomatic Complexity 5 include/linux/thread_info.h:check_copy_size Cyclomatic Complexity 1 arch/x86/include/asm/preempt.h:preempt_count Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock Cyclomatic Complexity 1 include/linux/wait.h:init_waitqueue_func_entry Cyclomatic Complexity 1 include/linux/llist.h:init_llist_head Cyclomatic Complexity 1 include/linux/llist.h:llist_empty Cyclomatic Complexity 1 include/linux/llist.h:llist_del_all Cyclomatic Complexity 1 include/linux/rbtree.h:rb_link_node Cyclomatic Complexity 3 include/linux/overflow.h:__ab_c_size Cyclomatic Complexity 1 include/linux/page_ref.h:page_ref_dec_and_test Cyclomatic Complexity 1 include/linux/sched.h:task_thread_info Cyclomatic Complexity 1 include/linux/sched.h:need_resched Cyclomatic Complexity 1 include/linux/mm.h:put_page_testzero Cyclomatic Complexity 1 include/linux/mm.h:put_devmap_managed_page Cyclomatic Complexity 1 include/uapi/linux/virtio_ring.h:vring_need_event Cyclomatic Complexity 1 include/linux/virtio_byteorder.h:virtio_legacy_is_little_endian Cyclomatic Complexity 2 include/linux/uio.h:copy_to_iter Cyclomatic Complexity 2 include/linux/uio.h:copy_from_iter Cyclomatic Complexity 2 include/linux/uio.h:copy_from_iter_full Cyclomatic Complexity 1 include/linux/uio.h:iov_iter_count Cyclomatic Complexity 1 include/linux/slab.h:kmalloc_type Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large Cyclomatic Complexity 4 include/linux/slab.h:kmalloc Cyclomatic Complexity 1 arch/x86/include/asm/smap.h:clac Cyclomatic Complexity 1 arch/x86/include/asm/smap.h:stac Cyclomatic Complexity 1 arch/x86/include/asm/uaccess.h:set_fs Cyclomatic Complexity 1 arch/x86/include/asm/uaccess_32.h:raw_copy_to_user Cyclomatic Complexity 5 arch/x86/include/asm/uaccess_32.h:raw_copy_from_user Cyclomatic Complexity 1 include/linux/uaccess.h:__copy_from_user Cyclomatic Complexity 1 include/linux/uaccess.h:__copy_to_user Cyclomatic Complexity 2 include/linux/uaccess.h:copy_from_user Cyclomatic Complexity 2 include/linux/uaccess.h:copy_to_user Cyclomatic Complexity 4 include/linux/poll.h:poll_wait Cyclomatic Complexity 1 include/linux/poll.h:init_poll_funcptr Cyclomatic Complexity 1 include/linux/rbtree_augmented.h:rb_set_parent Cyclomatic Complexity 1 include/linux/rbtree_augmented.h:rb_set_parent_color Cyclomatic Complexity 3 include/linux/rbtree_augmented.h:__rb_change_child Cyclomatic Complexity 11 include/linux/rbtree_augmented.h:__rb_erase_augmented Cyclomatic Complexity 2 include/linux/rbtree_augmented.h:rb_erase_augmented_cached Cyclomatic Complexity 1 drivers//vhost/vhost.h:vhost_has_feature Cyclomatic Complexity 1 drivers//vhost/vhost.h:vhost_backend_has_feature Cyclomatic Complexity 1 drivers//vhost/vhost.h:vhost_is_little_endian Cyclomatic Complexity 5 drivers//vhost/vhost.c:vhost_umem_interval_tree_compute_subtree_last Cyclomatic Complexity 3 drivers//vhost/vhost.c:vhost_umem_interval_tree_augment_propagate Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_umem_interval_tree_augment_copy Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_umem_interval_tree_augment_rotate Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_umem_interval_tree_remove Cyclomatic Complexity 7 drivers//vhost/vhost.c:vhost_umem_interval_tree_subtree_search Cyclomatic Complexity 4 drivers//vhost/vhost.c:vhost_umem_interval_tree_iter_first Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_disable_cross_endian Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_enable_cross_endian_big Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_enable_cross_endian_little Cyclomatic Complexity 5 drivers//vhost/vhost.c:vhost_set_vring_endian Cyclomatic Complexity 2 drivers//vhost/vhost.c:vhost_get_vring_endian Cyclomatic Complexity 3 drivers//vhost/vhost.c:vhost_init_is_le Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_reset_is_le Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_work_init Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_poll_init Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_has_work Cyclomatic Complexity 2 drivers//vhost/vhost.c:__vhost_vq_meta_reset Cyclomatic Complexity 2 drivers//vhost/vhost.c:vhost_vq_meta_reset Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_vq_reset Cyclomatic Complexity 2 drivers//vhost/vhost.c:vhost_dev_check_owner Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_dev_has_owner vim +1771 drivers//vhost/vhost.c 1760 1761 static void log_used(struct vhost_virtqueue *vq, u64 used_offset, u64 len) 1762 { 1763 struct iovec iov[64]; 1764 int i, ret; 1765 1766 if (!vq->iotlb) { 1767 log_write(vq->log_base, vq->log_addr + used_offset, len); 1768 return; 1769 } 1770 > 1771 ret = translate_desc(vq, (u64)vq->used + used_offset, len, iov, 64, 1772 VHOST_ACCESS_WO); 1773 WARN_ON(ret < 0); 1774 1775 for (i = 0; i < ret; i++) { 1776 ret = log_write_hva(vq, (u64)iov[i].iov_base, iov[i].iov_len); 1777 WARN_ON(ret); 1778 } 1779 } 1780 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Mon, Dec 10, 2018 at 11:14:41PM +0800, kbuild test robot wrote: > Hi Jason, > > I love your patch! Perhaps something to improve: > > [auto build test WARNING on net/master] > > url: https://github.com/0day-ci/linux/commits/Jason-Wang/Fix-various-issue-of-vhost/20181210-223236 > config: i386-randconfig-x072-201849 (attached as .config) > compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > All warnings (new ones prefixed by >>): > > drivers//vhost/vhost.c: In function 'log_used': > >> drivers//vhost/vhost.c:1771:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > ret = translate_desc(vq, (u64)vq->used + used_offset, len, iov, 64, > ^ > drivers//vhost/vhost.c:1776:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > ret = log_write_hva(vq, (u64)iov[i].iov_base, iov[i].iov_len); > ^ > drivers//vhost/vhost.c: In function 'vhost_log_write': > drivers//vhost/vhost.c:1788:26: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > r = log_write_hva(vq, (u64)iov[i].iov_base, > ^ It's a technicality, cast to unsigned long and the warning will go away. Donnu why does gcc bother with these warnings. Nothing is wrong unless size of pointer is > size of int. > Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size > Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size > Cyclomatic Complexity 1 arch/x86/include/asm/barrier.h:array_index_mask_nospec > Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_read > Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_write > Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:set_bit > Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:clear_bit > Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_set_bit > Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit > Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit > Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls > Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32 > Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD > Cyclomatic Complexity 1 include/linux/list.h:__list_del > Cyclomatic Complexity 1 include/linux/list.h:list_empty > Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current > Cyclomatic Complexity 3 include/linux/string.h:memset > Cyclomatic Complexity 5 include/linux/string.h:memcpy > Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order > Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_dec_and_test > Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_dec_and_test > Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR > Cyclomatic Complexity 1 include/linux/thread_info.h:set_ti_thread_flag > Cyclomatic Complexity 1 include/linux/thread_info.h:check_object_size > Cyclomatic Complexity 5 include/linux/thread_info.h:check_copy_size > Cyclomatic Complexity 1 arch/x86/include/asm/preempt.h:preempt_count > Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check > Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock > Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock > Cyclomatic Complexity 1 include/linux/wait.h:init_waitqueue_func_entry > Cyclomatic Complexity 1 include/linux/llist.h:init_llist_head > Cyclomatic Complexity 1 include/linux/llist.h:llist_empty > Cyclomatic Complexity 1 include/linux/llist.h:llist_del_all > Cyclomatic Complexity 1 include/linux/rbtree.h:rb_link_node > Cyclomatic Complexity 3 include/linux/overflow.h:__ab_c_size > Cyclomatic Complexity 1 include/linux/page_ref.h:page_ref_dec_and_test > Cyclomatic Complexity 1 include/linux/sched.h:task_thread_info > Cyclomatic Complexity 1 include/linux/sched.h:need_resched > Cyclomatic Complexity 1 include/linux/mm.h:put_page_testzero > Cyclomatic Complexity 1 include/linux/mm.h:put_devmap_managed_page > Cyclomatic Complexity 1 include/uapi/linux/virtio_ring.h:vring_need_event > Cyclomatic Complexity 1 include/linux/virtio_byteorder.h:virtio_legacy_is_little_endian > Cyclomatic Complexity 2 include/linux/uio.h:copy_to_iter > Cyclomatic Complexity 2 include/linux/uio.h:copy_from_iter > Cyclomatic Complexity 2 include/linux/uio.h:copy_from_iter_full > Cyclomatic Complexity 1 include/linux/uio.h:iov_iter_count > Cyclomatic Complexity 1 include/linux/slab.h:kmalloc_type > Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index > Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large > Cyclomatic Complexity 4 include/linux/slab.h:kmalloc > Cyclomatic Complexity 1 arch/x86/include/asm/smap.h:clac > Cyclomatic Complexity 1 arch/x86/include/asm/smap.h:stac > Cyclomatic Complexity 1 arch/x86/include/asm/uaccess.h:set_fs > Cyclomatic Complexity 1 arch/x86/include/asm/uaccess_32.h:raw_copy_to_user > Cyclomatic Complexity 5 arch/x86/include/asm/uaccess_32.h:raw_copy_from_user > Cyclomatic Complexity 1 include/linux/uaccess.h:__copy_from_user > Cyclomatic Complexity 1 include/linux/uaccess.h:__copy_to_user > Cyclomatic Complexity 2 include/linux/uaccess.h:copy_from_user > Cyclomatic Complexity 2 include/linux/uaccess.h:copy_to_user > Cyclomatic Complexity 4 include/linux/poll.h:poll_wait > Cyclomatic Complexity 1 include/linux/poll.h:init_poll_funcptr > Cyclomatic Complexity 1 include/linux/rbtree_augmented.h:rb_set_parent > Cyclomatic Complexity 1 include/linux/rbtree_augmented.h:rb_set_parent_color > Cyclomatic Complexity 3 include/linux/rbtree_augmented.h:__rb_change_child > Cyclomatic Complexity 11 include/linux/rbtree_augmented.h:__rb_erase_augmented > Cyclomatic Complexity 2 include/linux/rbtree_augmented.h:rb_erase_augmented_cached > Cyclomatic Complexity 1 drivers//vhost/vhost.h:vhost_has_feature > Cyclomatic Complexity 1 drivers//vhost/vhost.h:vhost_backend_has_feature > Cyclomatic Complexity 1 drivers//vhost/vhost.h:vhost_is_little_endian > Cyclomatic Complexity 5 drivers//vhost/vhost.c:vhost_umem_interval_tree_compute_subtree_last > Cyclomatic Complexity 3 drivers//vhost/vhost.c:vhost_umem_interval_tree_augment_propagate > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_umem_interval_tree_augment_copy > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_umem_interval_tree_augment_rotate > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_umem_interval_tree_remove > Cyclomatic Complexity 7 drivers//vhost/vhost.c:vhost_umem_interval_tree_subtree_search > Cyclomatic Complexity 4 drivers//vhost/vhost.c:vhost_umem_interval_tree_iter_first > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_disable_cross_endian > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_enable_cross_endian_big > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_enable_cross_endian_little > Cyclomatic Complexity 5 drivers//vhost/vhost.c:vhost_set_vring_endian > Cyclomatic Complexity 2 drivers//vhost/vhost.c:vhost_get_vring_endian > Cyclomatic Complexity 3 drivers//vhost/vhost.c:vhost_init_is_le > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_reset_is_le > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_work_init > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_poll_init > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_has_work > Cyclomatic Complexity 2 drivers//vhost/vhost.c:__vhost_vq_meta_reset > Cyclomatic Complexity 2 drivers//vhost/vhost.c:vhost_vq_meta_reset > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_vq_reset > Cyclomatic Complexity 2 drivers//vhost/vhost.c:vhost_dev_check_owner > Cyclomatic Complexity 1 drivers//vhost/vhost.c:vhost_dev_has_owner > > vim +1771 drivers//vhost/vhost.c > > 1760 > 1761 static void log_used(struct vhost_virtqueue *vq, u64 used_offset, u64 len) > 1762 { > 1763 struct iovec iov[64]; > 1764 int i, ret; > 1765 > 1766 if (!vq->iotlb) { > 1767 log_write(vq->log_base, vq->log_addr + used_offset, len); > 1768 return; > 1769 } > 1770 > > 1771 ret = translate_desc(vq, (u64)vq->used + used_offset, len, iov, 64, > 1772 VHOST_ACCESS_WO); > 1773 WARN_ON(ret < 0); > 1774 > 1775 for (i = 0; i < ret; i++) { > 1776 ret = log_write_hva(vq, (u64)iov[i].iov_base, iov[i].iov_len); > 1777 WARN_ON(ret); > 1778 } > 1779 } > 1780 > > --- > 0-DAY kernel test infrastructure Open Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 5f272ab4d5b4..754ca22efb43 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -1196,7 +1196,8 @@ static void handle_rx(struct vhost_net *net) if (nvq->done_idx > VHOST_NET_BATCH) vhost_net_signal_used(nvq); if (unlikely(vq_log)) - vhost_log_write(vq, vq_log, log, vhost_len); + vhost_log_write(vq, vq_log, log, vhost_len, + vq->iov, in); total_len += vhost_len; if (unlikely(vhost_exceeds_weight(++recv_pkts, total_len))) { vhost_poll_queue(&vq->poll); diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 55e5aa662ad5..8ab279720a2b 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1733,11 +1733,66 @@ static int log_write(void __user *log_base, return r; } +static int log_write_hva(struct vhost_virtqueue *vq, u64 hva, u64 len) +{ + struct vhost_umem *umem = vq->umem; + struct vhost_umem_node *u; + u64 gpa; + int r; + bool hit = false; + + list_for_each_entry(u, &umem->umem_list, link) { + if (u->userspace_addr < hva && + u->userspace_addr + u->size >= + hva + len) { + gpa = u->start + hva - u->userspace_addr; + r = log_write(vq->log_base, gpa, len); + if (r < 0) + return r; + hit = true; + } + } + + /* No reverse mapping, should be a bug */ + WARN_ON(!hit); + return 0; +} + +static void log_used(struct vhost_virtqueue *vq, u64 used_offset, u64 len) +{ + struct iovec iov[64]; + int i, ret; + + if (!vq->iotlb) { + log_write(vq->log_base, vq->log_addr + used_offset, len); + return; + } + + ret = translate_desc(vq, (u64)vq->used + used_offset, len, iov, 64, + VHOST_ACCESS_WO); + WARN_ON(ret < 0); + + for (i = 0; i < ret; i++) { + ret = log_write_hva(vq, (u64)iov[i].iov_base, iov[i].iov_len); + WARN_ON(ret); + } +} + int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, - unsigned int log_num, u64 len) + unsigned int log_num, u64 len, struct iovec *iov, int count) { int i, r; + if (vq->iotlb) { + for (i = 0; i < count; i++) { + r = log_write_hva(vq, (u64)iov[i].iov_base, + iov[i].iov_len); + if (r < 0) + return r; + } + return 0; + } + /* Make sure data written is seen before log. */ smp_wmb(); for (i = 0; i < log_num; ++i) { @@ -1769,9 +1824,8 @@ static int vhost_update_used_flags(struct vhost_virtqueue *vq) smp_wmb(); /* Log used flag write. */ used = &vq->used->flags; - log_write(vq->log_base, vq->log_addr + - (used - (void __user *)vq->used), - sizeof vq->used->flags); + log_used(vq, (used - (void __user *)vq->used), + sizeof vq->used->flags); if (vq->log_ctx) eventfd_signal(vq->log_ctx, 1); } @@ -1789,9 +1843,8 @@ static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event) smp_wmb(); /* Log avail event write */ used = vhost_avail_event(vq); - log_write(vq->log_base, vq->log_addr + - (used - (void __user *)vq->used), - sizeof *vhost_avail_event(vq)); + log_used(vq, (used - (void __user *)vq->used), + sizeof *vhost_avail_event(vq)); if (vq->log_ctx) eventfd_signal(vq->log_ctx, 1); } @@ -2191,10 +2244,8 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, /* Make sure data is seen before log. */ smp_wmb(); /* Log used ring entry write. */ - log_write(vq->log_base, - vq->log_addr + - ((void __user *)used - (void __user *)vq->used), - count * sizeof *used); + log_used(vq, ((void __user *)used - (void __user *)vq->used), + count * sizeof *used); } old = vq->last_used_idx; new = (vq->last_used_idx += count); @@ -2236,9 +2287,8 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, /* Make sure used idx is seen before log. */ smp_wmb(); /* Log used index update. */ - log_write(vq->log_base, - vq->log_addr + offsetof(struct vring_used, idx), - sizeof vq->used->idx); + log_used(vq, offsetof(struct vring_used, idx), + sizeof vq->used->idx); if (vq->log_ctx) eventfd_signal(vq->log_ctx, 1); } diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index 466ef7542291..1b675dad5e05 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -205,7 +205,8 @@ bool vhost_vq_avail_empty(struct vhost_dev *, struct vhost_virtqueue *); bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, - unsigned int log_num, u64 len); + unsigned int log_num, u64 len, + struct iovec *iov, int count); int vq_iotlb_prefetch(struct vhost_virtqueue *vq); struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type);
Vhost dirty page logging API is designed to sync through GPA. But we try to log GIOVA when device IOTLB is enabled. This is wrong and may lead to missing data after migration. To solve this issue, when logging with device IOTLB enabled, we will: 1) reuse the device IOTLB translation result of GIOVA->HVA mapping to get HVA, for writable descriptor, get HVA through iovec. For used ring update, translate its GIOVA to HVA 2) traverse the GPA->HVA mapping to get the possible GPA and log through GPA. Pay attention this reverse mapping is not guaranteed to be unique, so we should log each possible GPA in this case. This fix the failure of scp to guest during migration. In -next, we will probably support passing GIOVA->GPA instead of GIOVA->HVA. Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API") Reported-by: Jintack Lim <jintack@cs.columbia.edu> Cc: Jintack Lim <jintack@cs.columbia.edu> Signed-off-by: Jason Wang <jasowang@redhat.com> --- drivers/vhost/net.c | 3 +- drivers/vhost/vhost.c | 78 +++++++++++++++++++++++++++++++++++-------- drivers/vhost/vhost.h | 3 +- 3 files changed, 68 insertions(+), 16 deletions(-)