Hi Jason, First bad commit (maybe != root cause):
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 4da9f3302615f4191814f826054846bf843e24fa commit: 20c384f1ea1a0bc7320bc445c72dd02d2970d594 vhost: refine vhost and vringh kconfig date: 4 months ago config: riscv-randconfig-s032-20200805 (attached as .config) compiler: riscv32-linux-gcc (GCC) 9.3.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.2-117-g8c7aee71-dirty git checkout 20c384f1ea1a0bc7320bc445c72dd02d2970d594 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=riscv If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <[email protected]> sparse warnings: (new ones prefixed by >>) drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * >> drivers/vhost/vhost.c:937:16: sparse: sparse: restricted __virtio16 degrades >> to integer >> drivers/vhost/vhost.c:937:16: sparse: sparse: restricted __virtio16 degrades >> to integer >> drivers/vhost/vhost.c:937:16: sparse: sparse: cast from restricted __virtio16 drivers/vhost/vhost.c:937:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] <asn:1> * @@ drivers/vhost/vhost.c:937:16: sparse: expected void *addr drivers/vhost/vhost.c:937:16: sparse: got restricted __virtio16 [noderef] <asn:1> * >> drivers/vhost/vhost.c:937:16: sparse: sparse: restricted __virtio16 degrades >> to integer >> drivers/vhost/vhost.c:937:16: sparse: sparse: restricted __virtio16 degrades >> to integer >> drivers/vhost/vhost.c:937:16: sparse: sparse: cast from restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:922:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:922:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:922:16: sparse: sparse: cast from restricted __virtio16 drivers/vhost/vhost.c:922:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] [usertype] <asn:1> * @@ drivers/vhost/vhost.c:922:16: sparse: expected void *addr drivers/vhost/vhost.c:922:16: sparse: got restricted __virtio16 [noderef] [usertype] <asn:1> * drivers/vhost/vhost.c:922:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:922:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:922:16: sparse: sparse: cast from restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:1014:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1014:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1014:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:1014:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] <asn:1> * @@ drivers/vhost/vhost.c:1014:16: sparse: expected void *addr drivers/vhost/vhost.c:1014:16: sparse: got restricted __virtio16 [noderef] <asn:1> * drivers/vhost/vhost.c:1014:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1014:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1014:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:989:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:989:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:989:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:989:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] <asn:1> * @@ drivers/vhost/vhost.c:989:16: sparse: expected void *addr drivers/vhost/vhost.c:989:16: sparse: got restricted __virtio16 [noderef] <asn:1> * drivers/vhost/vhost.c:989:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:989:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:989:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:995:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:995:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:995:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:995:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] <asn:1> * @@ drivers/vhost/vhost.c:995:16: sparse: expected void *addr drivers/vhost/vhost.c:995:16: sparse: got restricted __virtio16 [noderef] <asn:1> * drivers/vhost/vhost.c:995:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:995:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:995:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:944:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:944:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:944:16: sparse: sparse: cast from restricted __virtio16 drivers/vhost/vhost.c:944:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] <asn:1> * @@ drivers/vhost/vhost.c:944:16: sparse: expected void *addr drivers/vhost/vhost.c:944:16: sparse: got restricted __virtio16 [noderef] <asn:1> * drivers/vhost/vhost.c:944:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:944:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:944:16: sparse: sparse: cast from restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:1002:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1002:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1002:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:1002:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] <asn:1> * @@ drivers/vhost/vhost.c:1002:16: sparse: expected void *addr drivers/vhost/vhost.c:1002:16: sparse: got restricted __virtio16 [noderef] <asn:1> * drivers/vhost/vhost.c:1002:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1002:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1002:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:900:42: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void [noderef] <asn:1> *addr @@ got void *addr @@ drivers/vhost/vhost.c:900:42: sparse: expected void [noderef] <asn:1> *addr drivers/vhost/vhost.c:900:42: sparse: got void *addr drivers/vhost/vhost.c:753:17: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void [noderef] <asn:1> * @@ got void * @@ drivers/vhost/vhost.c:753:17: sparse: expected void [noderef] <asn:1> * drivers/vhost/vhost.c:753:17: sparse: got void * drivers/vhost/vhost.c:1008:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1008:16: sparse: sparse: restricted __virtio16 degrades to integer drivers/vhost/vhost.c:1008:16: sparse: sparse: cast to restricted __virtio16 drivers/vhost/vhost.c:1008:16: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void *addr @@ got restricted __virtio16 [noderef] [usertype] <asn:1> * @@ vim +937 drivers/vhost/vhost.c 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 743 f889491380582b4 Jason Wang 2017-02-28 744 static inline void __user *vhost_vq_meta_fetch(struct vhost_virtqueue *vq, f889491380582b4 Jason Wang 2017-02-28 745 u64 addr, unsigned int size, f889491380582b4 Jason Wang 2017-02-28 746 int type) f889491380582b4 Jason Wang 2017-02-28 747 { f889491380582b4 Jason Wang 2017-02-28 748 const struct vhost_umem_node *node = vq->meta_iotlb[type]; f889491380582b4 Jason Wang 2017-02-28 749 f889491380582b4 Jason Wang 2017-02-28 750 if (!node) f889491380582b4 Jason Wang 2017-02-28 751 return NULL; f889491380582b4 Jason Wang 2017-02-28 752 f889491380582b4 Jason Wang 2017-02-28 @753 return (void *)(uintptr_t)(node->userspace_addr + addr - node->start); f889491380582b4 Jason Wang 2017-02-28 754 } f889491380582b4 Jason Wang 2017-02-28 755 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 756 /* Can we switch to this memory table? */ 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 757 /* Caller should have device mutex but not vq mutex */ ddd3d4081ffa806 Stefan Hajnoczi 2018-04-11 758 static bool memory_access_ok(struct vhost_dev *d, struct vhost_umem *umem, 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 759 int log_all) 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 760 { 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 761 int i; d47effe1be0c4fc Krishna Kumar 2011-03-01 762 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 763 for (i = 0; i < d->nvqs; ++i) { ddd3d4081ffa806 Stefan Hajnoczi 2018-04-11 764 bool ok; ea16c51433510f7 Michael S. Tsirkin 2014-06-05 765 bool log; ea16c51433510f7 Michael S. Tsirkin 2014-06-05 766 3ab2e420ec1caf4 Asias He 2013-04-27 767 mutex_lock(&d->vqs[i]->mutex); ea16c51433510f7 Michael S. Tsirkin 2014-06-05 768 log = log_all || vhost_has_feature(d->vqs[i], VHOST_F_LOG_ALL); 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 769 /* If ring is inactive, will check when it's enabled. */ 3ab2e420ec1caf4 Asias He 2013-04-27 770 if (d->vqs[i]->private_data) a9709d6874d5513 Jason Wang 2016-06-23 771 ok = vq_memory_access_ok(d->vqs[i]->log_base, a9709d6874d5513 Jason Wang 2016-06-23 772 umem, log); 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 773 else ddd3d4081ffa806 Stefan Hajnoczi 2018-04-11 774 ok = true; 3ab2e420ec1caf4 Asias He 2013-04-27 775 mutex_unlock(&d->vqs[i]->mutex); 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 776 if (!ok) ddd3d4081ffa806 Stefan Hajnoczi 2018-04-11 777 return false; 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 778 } ddd3d4081ffa806 Stefan Hajnoczi 2018-04-11 779 return true; 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 780 } 3a4d5c94e959359 Michael S. Tsirkin 2010-01-14 781 6b1e6cc7855b09a Jason Wang 2016-06-23 782 static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, 6b1e6cc7855b09a Jason Wang 2016-06-23 783 struct iovec iov[], int iov_size, int access); bfe2bc512884d0b Jason Wang 2016-06-23 784 72952cc0614b616 Michael S. Tsirkin 2016-12-06 785 static int vhost_copy_to_user(struct vhost_virtqueue *vq, void __user *to, bfe2bc512884d0b Jason Wang 2016-06-23 786 const void *from, unsigned size) bfe2bc512884d0b Jason Wang 2016-06-23 787 { 6b1e6cc7855b09a Jason Wang 2016-06-23 788 int ret; 6b1e6cc7855b09a Jason Wang 2016-06-23 789 6b1e6cc7855b09a Jason Wang 2016-06-23 790 if (!vq->iotlb) bfe2bc512884d0b Jason Wang 2016-06-23 791 return __copy_to_user(to, from, size); 6b1e6cc7855b09a Jason Wang 2016-06-23 792 else { 6b1e6cc7855b09a Jason Wang 2016-06-23 793 /* This function should be called after iotlb 6b1e6cc7855b09a Jason Wang 2016-06-23 794 * prefetch, which means we're sure that all vq 6b1e6cc7855b09a Jason Wang 2016-06-23 795 * could be access through iotlb. So -EAGAIN should 6b1e6cc7855b09a Jason Wang 2016-06-23 796 * not happen in this case. 6b1e6cc7855b09a Jason Wang 2016-06-23 797 */ 6b1e6cc7855b09a Jason Wang 2016-06-23 798 struct iov_iter t; f889491380582b4 Jason Wang 2017-02-28 799 void __user *uaddr = vhost_vq_meta_fetch(vq, f889491380582b4 Jason Wang 2017-02-28 800 (u64)(uintptr_t)to, size, 7ced6c98c7ab7a1 Eric Auger 2018-04-11 801 VHOST_ADDR_USED); f889491380582b4 Jason Wang 2017-02-28 802 f889491380582b4 Jason Wang 2017-02-28 803 if (uaddr) f889491380582b4 Jason Wang 2017-02-28 804 return __copy_to_user(uaddr, from, size); f889491380582b4 Jason Wang 2017-02-28 805 6b1e6cc7855b09a Jason Wang 2016-06-23 806 ret = translate_desc(vq, (u64)(uintptr_t)to, size, vq->iotlb_iov, 6b1e6cc7855b09a Jason Wang 2016-06-23 807 ARRAY_SIZE(vq->iotlb_iov), 6b1e6cc7855b09a Jason Wang 2016-06-23 808 VHOST_ACCESS_WO); 6b1e6cc7855b09a Jason Wang 2016-06-23 809 if (ret < 0) 6b1e6cc7855b09a Jason Wang 2016-06-23 810 goto out; 6b1e6cc7855b09a Jason Wang 2016-06-23 811 iov_iter_init(&t, WRITE, vq->iotlb_iov, ret, size); 6b1e6cc7855b09a Jason Wang 2016-06-23 812 ret = copy_to_iter(from, size, &t); 6b1e6cc7855b09a Jason Wang 2016-06-23 813 if (ret == size) 6b1e6cc7855b09a Jason Wang 2016-06-23 814 ret = 0; 6b1e6cc7855b09a Jason Wang 2016-06-23 815 } 6b1e6cc7855b09a Jason Wang 2016-06-23 816 out: 6b1e6cc7855b09a Jason Wang 2016-06-23 817 return ret; bfe2bc512884d0b Jason Wang 2016-06-23 818 } bfe2bc512884d0b Jason Wang 2016-06-23 819 bfe2bc512884d0b Jason Wang 2016-06-23 820 static int vhost_copy_from_user(struct vhost_virtqueue *vq, void *to, 72952cc0614b616 Michael S. Tsirkin 2016-12-06 821 void __user *from, unsigned size) bfe2bc512884d0b Jason Wang 2016-06-23 822 { 6b1e6cc7855b09a Jason Wang 2016-06-23 823 int ret; 6b1e6cc7855b09a Jason Wang 2016-06-23 824 6b1e6cc7855b09a Jason Wang 2016-06-23 825 if (!vq->iotlb) bfe2bc512884d0b Jason Wang 2016-06-23 826 return __copy_from_user(to, from, size); 6b1e6cc7855b09a Jason Wang 2016-06-23 827 else { 6b1e6cc7855b09a Jason Wang 2016-06-23 828 /* This function should be called after iotlb 6b1e6cc7855b09a Jason Wang 2016-06-23 829 * prefetch, which means we're sure that vq 6b1e6cc7855b09a Jason Wang 2016-06-23 830 * could be access through iotlb. So -EAGAIN should 6b1e6cc7855b09a Jason Wang 2016-06-23 831 * not happen in this case. 6b1e6cc7855b09a Jason Wang 2016-06-23 832 */ f889491380582b4 Jason Wang 2017-02-28 833 void __user *uaddr = vhost_vq_meta_fetch(vq, f889491380582b4 Jason Wang 2017-02-28 834 (u64)(uintptr_t)from, size, f889491380582b4 Jason Wang 2017-02-28 835 VHOST_ADDR_DESC); 6b1e6cc7855b09a Jason Wang 2016-06-23 836 struct iov_iter f; f889491380582b4 Jason Wang 2017-02-28 837 f889491380582b4 Jason Wang 2017-02-28 838 if (uaddr) f889491380582b4 Jason Wang 2017-02-28 839 return __copy_from_user(to, uaddr, size); f889491380582b4 Jason Wang 2017-02-28 840 6b1e6cc7855b09a Jason Wang 2016-06-23 841 ret = translate_desc(vq, (u64)(uintptr_t)from, size, vq->iotlb_iov, 6b1e6cc7855b09a Jason Wang 2016-06-23 842 ARRAY_SIZE(vq->iotlb_iov), 6b1e6cc7855b09a Jason Wang 2016-06-23 843 VHOST_ACCESS_RO); 6b1e6cc7855b09a Jason Wang 2016-06-23 844 if (ret < 0) { 6b1e6cc7855b09a Jason Wang 2016-06-23 845 vq_err(vq, "IOTLB translation failure: uaddr " 6b1e6cc7855b09a Jason Wang 2016-06-23 846 "%p size 0x%llx\n", from, 6b1e6cc7855b09a Jason Wang 2016-06-23 847 (unsigned long long) size); 6b1e6cc7855b09a Jason Wang 2016-06-23 848 goto out; 6b1e6cc7855b09a Jason Wang 2016-06-23 849 } 6b1e6cc7855b09a Jason Wang 2016-06-23 850 iov_iter_init(&f, READ, vq->iotlb_iov, ret, size); 6b1e6cc7855b09a Jason Wang 2016-06-23 851 ret = copy_from_iter(to, size, &f); 6b1e6cc7855b09a Jason Wang 2016-06-23 852 if (ret == size) 6b1e6cc7855b09a Jason Wang 2016-06-23 853 ret = 0; 6b1e6cc7855b09a Jason Wang 2016-06-23 854 } 6b1e6cc7855b09a Jason Wang 2016-06-23 855 6b1e6cc7855b09a Jason Wang 2016-06-23 856 out: 6b1e6cc7855b09a Jason Wang 2016-06-23 857 return ret; 6b1e6cc7855b09a Jason Wang 2016-06-23 858 } 6b1e6cc7855b09a Jason Wang 2016-06-23 859 f889491380582b4 Jason Wang 2017-02-28 860 static void __user *__vhost_get_user_slow(struct vhost_virtqueue *vq, f889491380582b4 Jason Wang 2017-02-28 861 void __user *addr, unsigned int size, f889491380582b4 Jason Wang 2017-02-28 862 int type) 6b1e6cc7855b09a Jason Wang 2016-06-23 863 { 6b1e6cc7855b09a Jason Wang 2016-06-23 864 int ret; 6b1e6cc7855b09a Jason Wang 2016-06-23 865 6b1e6cc7855b09a Jason Wang 2016-06-23 866 ret = translate_desc(vq, (u64)(uintptr_t)addr, size, vq->iotlb_iov, 6b1e6cc7855b09a Jason Wang 2016-06-23 867 ARRAY_SIZE(vq->iotlb_iov), 6b1e6cc7855b09a Jason Wang 2016-06-23 868 VHOST_ACCESS_RO); 6b1e6cc7855b09a Jason Wang 2016-06-23 869 if (ret < 0) { 6b1e6cc7855b09a Jason Wang 2016-06-23 870 vq_err(vq, "IOTLB translation failure: uaddr " 6b1e6cc7855b09a Jason Wang 2016-06-23 871 "%p size 0x%llx\n", addr, 6b1e6cc7855b09a Jason Wang 2016-06-23 872 (unsigned long long) size); 6b1e6cc7855b09a Jason Wang 2016-06-23 873 return NULL; 6b1e6cc7855b09a Jason Wang 2016-06-23 874 } 6b1e6cc7855b09a Jason Wang 2016-06-23 875 6b1e6cc7855b09a Jason Wang 2016-06-23 876 if (ret != 1 || vq->iotlb_iov[0].iov_len != size) { 6b1e6cc7855b09a Jason Wang 2016-06-23 877 vq_err(vq, "Non atomic userspace memory access: uaddr " 6b1e6cc7855b09a Jason Wang 2016-06-23 878 "%p size 0x%llx\n", addr, 6b1e6cc7855b09a Jason Wang 2016-06-23 879 (unsigned long long) size); 6b1e6cc7855b09a Jason Wang 2016-06-23 880 return NULL; 6b1e6cc7855b09a Jason Wang 2016-06-23 881 } 6b1e6cc7855b09a Jason Wang 2016-06-23 882 6b1e6cc7855b09a Jason Wang 2016-06-23 883 return vq->iotlb_iov[0].iov_base; 6b1e6cc7855b09a Jason Wang 2016-06-23 884 } 6b1e6cc7855b09a Jason Wang 2016-06-23 885 f889491380582b4 Jason Wang 2017-02-28 886 /* This function should be called after iotlb f889491380582b4 Jason Wang 2017-02-28 887 * prefetch, which means we're sure that vq f889491380582b4 Jason Wang 2017-02-28 888 * could be access through iotlb. So -EAGAIN should f889491380582b4 Jason Wang 2017-02-28 889 * not happen in this case. f889491380582b4 Jason Wang 2017-02-28 890 */ f889491380582b4 Jason Wang 2017-02-28 891 static inline void __user *__vhost_get_user(struct vhost_virtqueue *vq, f889491380582b4 Jason Wang 2017-02-28 892 void *addr, unsigned int size, f889491380582b4 Jason Wang 2017-02-28 893 int type) f889491380582b4 Jason Wang 2017-02-28 894 { f889491380582b4 Jason Wang 2017-02-28 895 void __user *uaddr = vhost_vq_meta_fetch(vq, f889491380582b4 Jason Wang 2017-02-28 896 (u64)(uintptr_t)addr, size, type); f889491380582b4 Jason Wang 2017-02-28 897 if (uaddr) f889491380582b4 Jason Wang 2017-02-28 898 return uaddr; f889491380582b4 Jason Wang 2017-02-28 899 f889491380582b4 Jason Wang 2017-02-28 900 return __vhost_get_user_slow(vq, addr, size, type); f889491380582b4 Jason Wang 2017-02-28 901 } f889491380582b4 Jason Wang 2017-02-28 902 6b1e6cc7855b09a Jason Wang 2016-06-23 903 #define vhost_put_user(vq, x, ptr) \ 6b1e6cc7855b09a Jason Wang 2016-06-23 904 ({ \ 6b1e6cc7855b09a Jason Wang 2016-06-23 905 int ret = -EFAULT; \ 6b1e6cc7855b09a Jason Wang 2016-06-23 906 if (!vq->iotlb) { \ 6b1e6cc7855b09a Jason Wang 2016-06-23 907 ret = __put_user(x, ptr); \ 6b1e6cc7855b09a Jason Wang 2016-06-23 908 } else { \ 6b1e6cc7855b09a Jason Wang 2016-06-23 909 __typeof__(ptr) to = \ f889491380582b4 Jason Wang 2017-02-28 910 (__typeof__(ptr)) __vhost_get_user(vq, ptr, \ f889491380582b4 Jason Wang 2017-02-28 911 sizeof(*ptr), VHOST_ADDR_USED); \ 6b1e6cc7855b09a Jason Wang 2016-06-23 912 if (to != NULL) \ 6b1e6cc7855b09a Jason Wang 2016-06-23 913 ret = __put_user(x, to); \ 6b1e6cc7855b09a Jason Wang 2016-06-23 914 else \ 6b1e6cc7855b09a Jason Wang 2016-06-23 915 ret = -EFAULT; \ 6b1e6cc7855b09a Jason Wang 2016-06-23 916 } \ 6b1e6cc7855b09a Jason Wang 2016-06-23 917 ret; \ 6b1e6cc7855b09a Jason Wang 2016-06-23 918 }) 6b1e6cc7855b09a Jason Wang 2016-06-23 919 7b5d753ebc22c5b Jason Wang 2019-05-24 920 static inline int vhost_put_avail_event(struct vhost_virtqueue *vq) 7b5d753ebc22c5b Jason Wang 2019-05-24 921 { 7b5d753ebc22c5b Jason Wang 2019-05-24 922 return vhost_put_user(vq, cpu_to_vhost16(vq, vq->avail_idx), 7b5d753ebc22c5b Jason Wang 2019-05-24 923 vhost_avail_event(vq)); 7b5d753ebc22c5b Jason Wang 2019-05-24 924 } 7b5d753ebc22c5b Jason Wang 2019-05-24 925 7b5d753ebc22c5b Jason Wang 2019-05-24 926 static inline int vhost_put_used(struct vhost_virtqueue *vq, 7b5d753ebc22c5b Jason Wang 2019-05-24 927 struct vring_used_elem *head, int idx, 7b5d753ebc22c5b Jason Wang 2019-05-24 928 int count) 7b5d753ebc22c5b Jason Wang 2019-05-24 929 { 7b5d753ebc22c5b Jason Wang 2019-05-24 930 return vhost_copy_to_user(vq, vq->used->ring + idx, head, 7b5d753ebc22c5b Jason Wang 2019-05-24 931 count * sizeof(*head)); 7b5d753ebc22c5b Jason Wang 2019-05-24 932 } 7b5d753ebc22c5b Jason Wang 2019-05-24 933 7b5d753ebc22c5b Jason Wang 2019-05-24 934 static inline int vhost_put_used_flags(struct vhost_virtqueue *vq) 7b5d753ebc22c5b Jason Wang 2019-05-24 935 7b5d753ebc22c5b Jason Wang 2019-05-24 936 { 7b5d753ebc22c5b Jason Wang 2019-05-24 @937 return vhost_put_user(vq, cpu_to_vhost16(vq, vq->used_flags), 7b5d753ebc22c5b Jason Wang 2019-05-24 938 &vq->used->flags); 7b5d753ebc22c5b Jason Wang 2019-05-24 939 } 7b5d753ebc22c5b Jason Wang 2019-05-24 940 :::::: The code at line 937 was first introduced by commit :::::: 7b5d753ebc22c5b6935a70ce9a857dc6220784f8 vhost: fine grain userspace memory accessors :::::: TO: Jason Wang <[email protected]> :::::: CC: Michael S. Tsirkin <[email protected]> --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/[email protected]
.config.gz
Description: application/gzip

