Hi Keqian, Thank you for the patch! Yet something to improve: [auto build test ERROR on vfio/next] [also build test ERROR on linux/master linus/master v5.12-rc7 next-20210413] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Keqian-Zhu/vfio-iommu_type1-Implement-dirty-log-tracking-based-on-IOMMU-HWDBM/20210413-171632 base: https://github.com/awilliam/linux-vfio.git next config: arm-randconfig-r015-20210413 (attached as .config) compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/5553c39f302409e175a70157c47679e61297dec5 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Keqian-Zhu/vfio-iommu_type1-Implement-dirty-log-tracking-based-on-IOMMU-HWDBM/20210413-171632 git checkout 5553c39f302409e175a70157c47679e61297dec5 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): drivers/vfio/vfio_iommu_type1.c: In function 'vfio_iommu_dirty_log_clear': >> drivers/vfio/vfio_iommu_type1.c:1215:9: error: implicit declaration of function 'iommu_clear_dirty_log' [-Werror=implicit-function-declaration] 1215 | ret = iommu_clear_dirty_log(d->domain, start_iova, size, | ^~~~~~~~~~~~~~~~~~~~~ drivers/vfio/vfio_iommu_type1.c: In function 'vfio_iommu_dirty_log_sync': >> drivers/vfio/vfio_iommu_type1.c:1234:9: error: implicit declaration of function 'iommu_sync_dirty_log' [-Werror=implicit-function-declaration] 1234 | ret = iommu_sync_dirty_log(d->domain, dma->iova, dma->size, | ^~~~~~~~~~~~~~~~~~~~ In file included from arch/arm/include/asm/bug.h:60, from include/linux/bug.h:5, from include/linux/thread_info.h:12, from include/asm-generic/preempt.h:5, from ./arch/arm/include/generated/asm/preempt.h:1, from include/linux/preempt.h:78, from include/linux/spinlock.h:51, from include/linux/ipc.h:5, from include/uapi/linux/sem.h:5, from include/linux/sem.h:5, from include/linux/compat.h:14, from drivers/vfio/vfio_iommu_type1.c:24: drivers/vfio/vfio_iommu_type1.c: In function 'vfio_dma_dirty_log_switch': >> drivers/vfio/vfio_iommu_type1.c:1373:11: error: implicit declaration of function 'iommu_switch_dirty_log' [-Werror=implicit-function-declaration] 1373 | WARN_ON(iommu_switch_dirty_log(d->domain, enable, dma->iova, | ^~~~~~~~~~~~~~~~~~~~~~ include/asm-generic/bug.h:188:25: note: in definition of macro 'WARN_ON' 188 | int __ret_warn_on = !!(condition); \ | ^~~~~~~~~ drivers/vfio/vfio_iommu_type1.c: In function 'vfio_group_supports_hwdbm': drivers/vfio/vfio_iommu_type1.c:2360:33: error: 'IOMMU_DEV_FEAT_HWDBM' undeclared (first use in this function); did you mean 'IOMMU_DEV_FEAT_SVA'? 2360 | enum iommu_dev_features feat = IOMMU_DEV_FEAT_HWDBM; | ^~~~~~~~~~~~~~~~~~~~ | IOMMU_DEV_FEAT_SVA drivers/vfio/vfio_iommu_type1.c:2360:33: note: each undeclared identifier is reported only once for each function it appears in cc1: some warnings being treated as errors vim +/iommu_clear_dirty_log +1215 drivers/vfio/vfio_iommu_type1.c 1204 1205 static int vfio_iommu_dirty_log_clear(struct vfio_iommu *iommu, 1206 dma_addr_t start_iova, size_t size, 1207 unsigned long *bitmap_buffer, 1208 dma_addr_t base_iova, 1209 unsigned long pgshift) 1210 { 1211 struct vfio_domain *d; 1212 int ret = 0; 1213 1214 list_for_each_entry(d, &iommu->domain_list, next) { > 1215 ret = iommu_clear_dirty_log(d->domain, start_iova, size, 1216 bitmap_buffer, base_iova, pgshift); 1217 if (ret) { 1218 pr_warn("vfio_iommu dirty log clear failed!\n"); 1219 break; 1220 } 1221 } 1222 1223 return ret; 1224 } 1225 1226 static int vfio_iommu_dirty_log_sync(struct vfio_iommu *iommu, 1227 struct vfio_dma *dma, 1228 unsigned long pgshift) 1229 { 1230 struct vfio_domain *d; 1231 int ret = 0; 1232 1233 list_for_each_entry(d, &iommu->domain_list, next) { > 1234 ret = iommu_sync_dirty_log(d->domain, dma->iova, dma->size, 1235 dma->bitmap, dma->iova, pgshift); 1236 if (ret) { 1237 pr_warn("vfio_iommu dirty log sync failed!\n"); 1238 break; 1239 } 1240 } 1241 1242 return ret; 1243 } 1244 1245 static int update_user_bitmap(u64 __user *bitmap, struct vfio_iommu *iommu, 1246 struct vfio_dma *dma, dma_addr_t base_iova, 1247 size_t pgsize) 1248 { 1249 unsigned long pgshift = __ffs(pgsize); 1250 unsigned long nbits = dma->size >> pgshift; 1251 unsigned long bit_offset = (dma->iova - base_iova) >> pgshift; 1252 unsigned long copy_offset = bit_offset / BITS_PER_LONG; 1253 unsigned long shift = bit_offset % BITS_PER_LONG; 1254 unsigned long leftover; 1255 int ret; 1256 1257 if (!iommu->num_non_pinned_groups || !dma->iommu_mapped) { 1258 /* nothing to do */ 1259 } else if (!iommu->num_non_hwdbm_groups) { 1260 /* try to get dirty log from IOMMU */ 1261 ret = vfio_iommu_dirty_log_sync(iommu, dma, pgshift); 1262 if (ret) 1263 return ret; 1264 } else { 1265 /* 1266 * mark all pages dirty if any IOMMU capable device is not able 1267 * to report dirty pages and all pages are pinned and mapped. 1268 */ 1269 bitmap_set(dma->bitmap, 0, nbits); 1270 } 1271 1272 if (shift) { 1273 bitmap_shift_left(dma->bitmap, dma->bitmap, shift, 1274 nbits + shift); 1275 1276 if (copy_from_user(&leftover, 1277 (void __user *)(bitmap + copy_offset), 1278 sizeof(leftover))) 1279 return -EFAULT; 1280 1281 bitmap_or(dma->bitmap, dma->bitmap, &leftover, shift); 1282 } 1283 1284 if (copy_to_user((void __user *)(bitmap + copy_offset), dma->bitmap, 1285 DIRTY_BITMAP_BYTES(nbits + shift))) 1286 return -EFAULT; 1287 1288 /* Recover the bitmap if it'll be used to clear hardware dirty log */ 1289 if (shift && iommu->num_non_pinned_groups && dma->iommu_mapped && 1290 !iommu->num_non_hwdbm_groups) 1291 bitmap_shift_right(dma->bitmap, dma->bitmap, shift, 1292 nbits + shift); 1293 1294 return 0; 1295 } 1296 1297 static int vfio_iova_dirty_bitmap(u64 __user *bitmap, struct vfio_iommu *iommu, 1298 dma_addr_t iova, size_t size, size_t pgsize) 1299 { 1300 struct vfio_dma *dma; 1301 struct rb_node *n; 1302 unsigned long pgshift = __ffs(pgsize); 1303 int ret; 1304 1305 /* 1306 * GET_BITMAP request must fully cover vfio_dma mappings. Multiple 1307 * vfio_dma mappings may be clubbed by specifying large ranges, but 1308 * there must not be any previous mappings bisected by the range. 1309 * An error will be returned if these conditions are not met. 1310 */ 1311 dma = vfio_find_dma(iommu, iova, 1); 1312 if (dma && dma->iova != iova) 1313 return -EINVAL; 1314 1315 dma = vfio_find_dma(iommu, iova + size - 1, 0); 1316 if (dma && dma->iova + dma->size != iova + size) 1317 return -EINVAL; 1318 1319 for (n = rb_first(&iommu->dma_list); n; n = rb_next(n)) { 1320 struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node); 1321 1322 if (dma->iova < iova) 1323 continue; 1324 1325 if (dma->iova > iova + size - 1) 1326 break; 1327 1328 ret = update_user_bitmap(bitmap, iommu, dma, iova, pgsize); 1329 if (ret) 1330 return ret; 1331 1332 /* Clear iommu dirty log to re-enable dirty log tracking */ 1333 if (iommu->num_non_pinned_groups && dma->iommu_mapped && 1334 !iommu->num_non_hwdbm_groups) { 1335 ret = vfio_iommu_dirty_log_clear(iommu, dma->iova, 1336 dma->size, dma->bitmap, dma->iova, 1337 pgshift); 1338 if (ret) 1339 return ret; 1340 } 1341 1342 /* 1343 * Re-populate bitmap to include all pinned pages which are 1344 * considered as dirty but exclude pages which are unpinned and 1345 * pages which are marked dirty by vfio_dma_rw() 1346 */ 1347 bitmap_clear(dma->bitmap, 0, dma->size >> pgshift); 1348 vfio_dma_populate_bitmap(dma, pgsize); 1349 } 1350 return 0; 1351 } 1352 1353 static int verify_bitmap_size(uint64_t npages, uint64_t bitmap_size) 1354 { 1355 if (!npages || !bitmap_size || (bitmap_size > DIRTY_BITMAP_SIZE_MAX) || 1356 (bitmap_size < DIRTY_BITMAP_BYTES(npages))) 1357 return -EINVAL; 1358 1359 return 0; 1360 } 1361 1362 static void vfio_dma_dirty_log_switch(struct vfio_iommu *iommu, 1363 struct vfio_dma *dma, bool enable) 1364 { 1365 struct vfio_domain *d; 1366 1367 if (!dma->iommu_mapped) 1368 return; 1369 1370 list_for_each_entry(d, &iommu->domain_list, next) { 1371 if (d->num_non_hwdbm_groups) 1372 continue; > 1373 WARN_ON(iommu_switch_dirty_log(d->domain, enable, dma->iova, 1374 dma->size, d->prot | dma->prot)); 1375 } 1376 } 1377 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org