Hi Zhangfei, Thank you for the patch! Yet something to improve: [auto build test ERROR on cryptodev/master] [also build test ERROR on crypto/master char-misc/char-misc-testing v5.5-rc1 next-20191210] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Zhangfei-Gao/Add-uacce-module-for-Accelerator/20191210-160210 base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master config: sparc64-allmodconfig (attached as .config) compiler: sparc64-linux-gcc (GCC) 7.5.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.5.0 make.cross ARCH=sparc64 If you fix the issue, kindly add following tag Reported-by: kbuild test robot All errors (new ones prefixed by >>): drivers/misc/uacce/uacce.c:112:15: error: variable 'uacce_sva_ops' has initializer but incomplete type static struct iommu_sva_ops uacce_sva_ops = { ^~~~~~~~~~~~~ drivers/misc/uacce/uacce.c:113:3: error: 'struct iommu_sva_ops' has no member named 'mm_exit' .mm_exit = uacce_sva_exit, ^~~~~~~ drivers/misc/uacce/uacce.c:113:13: warning: excess elements in struct initializer .mm_exit = uacce_sva_exit, ^~~~~~~~~~~~~~ drivers/misc/uacce/uacce.c:113:13: note: (near initialization for 'uacce_sva_ops') drivers/misc/uacce/uacce.c: In function 'uacce_mm_get': drivers/misc/uacce/uacce.c:144:12: error: implicit declaration of function 'iommu_sva_bind_device'; did you mean 'bus_find_device'? [-Werror=implicit-function-declaration] handle = iommu_sva_bind_device(uacce->parent, mm, uacce_mm); ^~~~~~~~~~~~~~~~~~~~~ bus_find_device drivers/misc/uacce/uacce.c:144:10: warning: assignment makes pointer from integer without a cast [-Wint-conversion] handle = iommu_sva_bind_device(uacce->parent, mm, uacce_mm); ^ drivers/misc/uacce/uacce.c:148:9: error: implicit declaration of function 'iommu_sva_set_ops'; did you mean 'iommu_setup_dma_ops'? [-Werror=implicit-function-declaration] ret = iommu_sva_set_ops(handle, &uacce_sva_ops); ^~~~~~~~~~~~~~~~~ iommu_setup_dma_ops drivers/misc/uacce/uacce.c:152:21: error: implicit declaration of function 'iommu_sva_get_pasid' [-Werror=implicit-function-declaration] uacce_mm->pasid = iommu_sva_get_pasid(handle); ^~~~~~~~~~~~~~~~~~~ >> drivers/misc/uacce/uacce.c:153:26: error: 'IOMMU_PASID_INVALID' undeclared (first use in this function); did you mean 'HV_MSIVALID_INVALID'? if (uacce_mm->pasid == IOMMU_PASID_INVALID) ^~~~~~~~~~~~~~~~~~~ HV_MSIVALID_INVALID drivers/misc/uacce/uacce.c:153:26: note: each undeclared identifier is reported only once for each function it appears in drivers/misc/uacce/uacce.c:168:3: error: implicit declaration of function 'iommu_sva_unbind_device'; did you mean 'bus_find_device'? [-Werror=implicit-function-declaration] iommu_sva_unbind_device(handle); ^~~~~~~~~~~~~~~~~~~~~~~ bus_find_device drivers/misc/uacce/uacce.c: At top level: >> drivers/misc/uacce/uacce.c:274:21: error: variable 'uacce_vm_ops' has initializer but incomplete type static const struct vm_operations_struct uacce_vm_ops = { ^~~~~~~~~~~~~~~~~~~~ >> drivers/misc/uacce/uacce.c:275:3: error: 'const struct vm_operations_struct' has no member named 'close' .close = uacce_vma_close, ^~~~~ drivers/misc/uacce/uacce.c:275:11: warning: excess elements in struct initializer .close = uacce_vma_close, ^~~~~~~~~~~~~~~ drivers/misc/uacce/uacce.c:275:11: note: (near initialization for 'uacce_vm_ops') drivers/misc/uacce/uacce.c: In function 'uacce_fops_mmap': >> drivers/misc/uacce/uacce.c:295:19: error: 'VM_DONTCOPY' undeclared (first use in this function) vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_WIPEONFORK; ^~~~~~~~~~~ >> drivers/misc/uacce/uacce.c:295:33: error: 'VM_DONTEXPAND' undeclared (first use in this function); did you mean 'VM_DONTCOPY'? vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_WIPEONFORK; ^~~~~~~~~~~~~ VM_DONTCOPY >> drivers/misc/uacce/uacce.c:295:49: error: 'VM_WIPEONFORK' undeclared (first use in this function) vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_WIPEONFORK; ^~~~~~~~~~~~~ drivers/misc/uacce/uacce.c: In function 'uacce_alloc': drivers/misc/uacce/uacce.c:502:9: error: implicit declaration of function 'iommu_dev_enable_feature'; did you mean 'module_enable_ro'? [-Werror=implicit-function-declaration] ret = iommu_dev_enable_feature(parent, IOMMU_DEV_FEAT_SVA); ^~~~~~~~~~~~~~~~~~~~~~~~ module_enable_ro drivers/misc/uacce/uacce.c:502:42: error: 'IOMMU_DEV_FEAT_SVA' undeclared (first use in this function); did you mean 'NOMMU_VMFLAGS'? ret = iommu_dev_enable_feature(parent, IOMMU_DEV_FEAT_SVA); ^~~~~~~~~~~~~~~~~~ NOMMU_VMFLAGS drivers/misc/uacce/uacce.c:530:3: error: implicit declaration of function 'iommu_dev_disable_feature'; did you mean 'module_disable_ro'? [-Werror=implicit-function-declaration] iommu_dev_disable_feature(uacce->parent, IOMMU_DEV_FEAT_SVA); ^~~~~~~~~~~~~~~~~~~~~~~~~ module_disable_ro drivers/misc/uacce/uacce.c: In function 'uacce_remove': drivers/misc/uacce/uacce.c:592:44: error: 'IOMMU_DEV_FEAT_SVA' undeclared (first use in this function); did you mean 'NOMMU_VMFLAGS'? iommu_dev_disable_feature(uacce->parent, IOMMU_DEV_FEAT_SVA); ^~~~~~~~~~~~~~~~~~ NOMMU_VMFLAGS drivers/misc/uacce/uacce.c: At top level: drivers/misc/uacce/uacce.c:112:29: error: storage size of 'uacce_sva_ops' isn't known static struct iommu_sva_ops uacce_sva_ops = { ^~~~~~~~~~~~~ >> drivers/misc/uacce/uacce.c:274:42: error: storage size of 'uacce_vm_ops' isn't known static const struct vm_operations_struct uacce_vm_ops = { ^~~~~~~~~~~~ cc1: some warnings being treated as errors vim +153 drivers/misc/uacce/uacce.c 115 116 static struct uacce_mm *uacce_mm_get(struct uacce_device *uacce, 117 struct uacce_queue *q, 118 struct mm_struct *mm) 119 { 120 struct uacce_mm *uacce_mm = NULL; 121 struct iommu_sva *handle = NULL; 122 int ret; 123 124 lockdep_assert_held(&uacce->mm_lock); 125 126 list_for_each_entry(uacce_mm, &uacce->mm_list, list) { 127 if (uacce_mm->mm == mm) { 128 mutex_lock(&uacce_mm->lock); 129 list_add(&q->list, &uacce_mm->queues); 130 mutex_unlock(&uacce_mm->lock); 131 return uacce_mm; 132 } 133 } 134 135 uacce_mm = kzalloc(sizeof(*uacce_mm), GFP_KERNEL); 136 if (!uacce_mm) 137 return NULL; 138 139 if (uacce->flags & UACCE_DEV_SVA) { 140 /* 141 * Safe to pass an incomplete uacce_mm, since mm_exit cannot 142 * fire while we hold a reference to the mm. 143 */ 144 handle = iommu_sva_bind_device(uacce->parent, mm, uacce_mm); 145 if (IS_ERR(handle)) 146 goto err_free; 147 > 148 ret = iommu_sva_set_ops(handle, &uacce_sva_ops); 149 if (ret) 150 goto err_unbind; 151 152 uacce_mm->pasid = iommu_sva_get_pasid(handle); > 153 if (uacce_mm->pasid == IOMMU_PASID_INVALID) 154 goto err_unbind; 155 } 156 157 uacce_mm->mm = mm; 158 uacce_mm->handle = handle; 159 INIT_LIST_HEAD(&uacce_mm->queues); 160 mutex_init(&uacce_mm->lock); 161 list_add(&q->list, &uacce_mm->queues); 162 list_add(&uacce_mm->list, &uacce->mm_list); 163 164 return uacce_mm; 165 166 err_unbind: 167 if (handle) 168 iommu_sva_unbind_device(handle); 169 err_free: 170 kfree(uacce_mm); 171 return NULL; 172 } 173 174 static void uacce_mm_put(struct uacce_queue *q) 175 { 176 struct uacce_mm *uacce_mm = q->uacce_mm; 177 178 lockdep_assert_held(&q->uacce->mm_lock); 179 180 mutex_lock(&uacce_mm->lock); 181 list_del(&q->list); 182 mutex_unlock(&uacce_mm->lock); 183 184 if (list_empty(&uacce_mm->queues)) { 185 if (uacce_mm->handle) 186 iommu_sva_unbind_device(uacce_mm->handle); 187 list_del(&uacce_mm->list); 188 kfree(uacce_mm); 189 } 190 } 191 192 static int uacce_fops_open(struct inode *inode, struct file *filep) 193 { 194 struct uacce_mm *uacce_mm = NULL; 195 struct uacce_device *uacce; 196 struct uacce_queue *q; 197 int ret = 0; 198 199 uacce = xa_load(&uacce_xa, iminor(inode)); 200 if (!uacce) 201 return -ENODEV; 202 203 if (!try_module_get(uacce->parent->driver->owner)) 204 return -ENODEV; 205 206 q = kzalloc(sizeof(struct uacce_queue), GFP_KERNEL); 207 if (!q) { 208 ret = -ENOMEM; 209 goto out_with_module; 210 } 211 212 mutex_lock(&uacce->mm_lock); 213 uacce_mm = uacce_mm_get(uacce, q, current->mm); 214 mutex_unlock(&uacce->mm_lock); 215 if (!uacce_mm) { 216 ret = -ENOMEM; 217 goto out_with_mem; 218 } 219 220 q->uacce = uacce; 221 q->uacce_mm = uacce_mm; 222 223 if (uacce->ops->get_queue) { 224 ret = uacce->ops->get_queue(uacce, uacce_mm->pasid, q); 225 if (ret < 0) 226 goto out_with_mm; 227 } 228 229 init_waitqueue_head(&q->wait); 230 filep->private_data = q; 231 q->state = UACCE_Q_INIT; 232 233 return 0; 234 235 out_with_mm: 236 mutex_lock(&uacce->mm_lock); 237 uacce_mm_put(q); 238 mutex_unlock(&uacce->mm_lock); 239 out_with_mem: 240 kfree(q); 241 out_with_module: 242 module_put(uacce->parent->driver->owner); 243 return ret; 244 } 245 246 static int uacce_fops_release(struct inode *inode, struct file *filep) 247 { 248 struct uacce_queue *q = filep->private_data; 249 struct uacce_device *uacce = q->uacce; 250 251 uacce_put_queue(q); 252 253 mutex_lock(&uacce->mm_lock); 254 uacce_mm_put(q); 255 mutex_unlock(&uacce->mm_lock); 256 257 kfree(q); 258 module_put(uacce->parent->driver->owner); 259 260 return 0; 261 } 262 263 static void uacce_vma_close(struct vm_area_struct *vma) 264 { 265 struct uacce_queue *q = vma->vm_private_data; 266 struct uacce_qfile_region *qfr = NULL; 267 268 if (vma->vm_pgoff < UACCE_MAX_REGION) 269 qfr = q->qfrs[vma->vm_pgoff]; 270 271 kfree(qfr); 272 } 273 > 274 static const struct vm_operations_struct uacce_vm_ops = { > 275 .close = uacce_vma_close, 276 }; 277 278 static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) 279 { 280 struct uacce_queue *q = filep->private_data; 281 struct uacce_device *uacce = q->uacce; 282 struct uacce_qfile_region *qfr; 283 enum uacce_qfrt type = UACCE_MAX_REGION; 284 int ret = 0; 285 286 if (vma->vm_pgoff < UACCE_MAX_REGION) 287 type = vma->vm_pgoff; 288 else 289 return -EINVAL; 290 291 qfr = kzalloc(sizeof(*qfr), GFP_KERNEL); 292 if (!qfr) 293 return -ENOMEM; 294 > 295 vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_WIPEONFORK; 296 vma->vm_ops = &uacce_vm_ops; 297 vma->vm_private_data = q; 298 qfr->type = type; 299 300 mutex_lock(&uacce_mutex); 301 302 if (q->state != UACCE_Q_INIT && q->state != UACCE_Q_STARTED) { 303 ret = -EINVAL; 304 goto out_with_lock; 305 } 306 307 if (q->qfrs[type]) { 308 ret = -EEXIST; 309 goto out_with_lock; 310 } 311 312 switch (type) { 313 case UACCE_QFRT_MMIO: 314 if (!uacce->ops->mmap) { 315 ret = -EINVAL; 316 goto out_with_lock; 317 } 318 319 ret = uacce->ops->mmap(q, vma, qfr); 320 if (ret) 321 goto out_with_lock; 322 323 break; 324 325 case UACCE_QFRT_DUS: 326 if (uacce->flags & UACCE_DEV_SVA) { 327 if (!uacce->ops->mmap) { 328 ret = -EINVAL; 329 goto out_with_lock; 330 } 331 332 ret = uacce->ops->mmap(q, vma, qfr); 333 if (ret) 334 goto out_with_lock; 335 } 336 break; 337 338 default: 339 ret = -EINVAL; 340 goto out_with_lock; 341 } 342 343 q->qfrs[type] = qfr; 344 mutex_unlock(&uacce_mutex); 345 346 return ret; 347 348 out_with_lock: 349 mutex_unlock(&uacce_mutex); 350 kfree(qfr); 351 return ret; 352 } 353 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation