Re: [PATCH v3 5/5] staging: vchiq: Combine vchiq platform code into single file
From: kernel test robot
Date: Sun Jul 04 2021 - 14:08:19 EST
Hi Ojaswin,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on staging/staging-testing]
[also build test WARNING on next-20210701]
[cannot apply to v5.13]
[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/Ojaswin-Mujoo/vchiq-Patch-to-separate-platform-and-cdev-code/20210705-000124
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 77ad1f0e99bd00af024e650b862cfda3137af660
config: x86_64-randconfig-a004-20210704 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 89c1c64cc3170a05a881bb9954feafc3edca6704)
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
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/6e25765ec91ba341b2c85fdd00da9ef4c2ed737c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Ojaswin-Mujoo/vchiq-Patch-to-separate-platform-and-cdev-code/20210705-000124
git checkout 6e25765ec91ba341b2c85fdd00da9ef4c2ed737c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>
All warnings (new ones prefixed by >>):
>> drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c:378:16: warning: result of comparison of constant 419244183493398898 with expression of type 'unsigned int' is always false [-Wtautological-constant-out-of-range-compare]
if (num_pages > (SIZE_MAX - sizeof(struct pagelist) -
~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
vim +378 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
345
346 /* There is a potential problem with partial cache lines (pages?)
347 * at the ends of the block when reading. If the CPU accessed anything in
348 * the same line (page?) then it may have pulled old data into the cache,
349 * obscuring the new data underneath. We can solve this by transferring the
350 * partial cache lines separately, and allowing the ARM to copy into the
351 * cached area.
352 */
353
354 static struct vchiq_pagelist_info *
355 create_pagelist(char *buf, char __user *ubuf,
356 size_t count, unsigned short type)
357 {
358 struct pagelist *pagelist;
359 struct vchiq_pagelist_info *pagelistinfo;
360 struct page **pages;
361 u32 *addrs;
362 unsigned int num_pages, offset, i, k;
363 int actual_pages;
364 size_t pagelist_size;
365 struct scatterlist *scatterlist, *sg;
366 int dma_buffers;
367 dma_addr_t dma_addr;
368
369 if (count >= INT_MAX - PAGE_SIZE)
370 return NULL;
371
372 if (buf)
373 offset = (uintptr_t)buf & (PAGE_SIZE - 1);
374 else
375 offset = (uintptr_t)ubuf & (PAGE_SIZE - 1);
376 num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE);
377
> 378 if (num_pages > (SIZE_MAX - sizeof(struct pagelist) -
379 sizeof(struct vchiq_pagelist_info)) /
380 (sizeof(u32) + sizeof(pages[0]) +
381 sizeof(struct scatterlist)))
382 return NULL;
383
384 pagelist_size = sizeof(struct pagelist) +
385 (num_pages * sizeof(u32)) +
386 (num_pages * sizeof(pages[0]) +
387 (num_pages * sizeof(struct scatterlist))) +
388 sizeof(struct vchiq_pagelist_info);
389
390 /* Allocate enough storage to hold the page pointers and the page
391 * list
392 */
393 pagelist = dma_alloc_coherent(g_dev, pagelist_size, &dma_addr,
394 GFP_KERNEL);
395
396 vchiq_log_trace(vchiq_arm_log_level, "%s - %pK", __func__, pagelist);
397
398 if (!pagelist)
399 return NULL;
400
401 addrs = pagelist->addrs;
402 pages = (struct page **)(addrs + num_pages);
403 scatterlist = (struct scatterlist *)(pages + num_pages);
404 pagelistinfo = (struct vchiq_pagelist_info *)
405 (scatterlist + num_pages);
406
407 pagelist->length = count;
408 pagelist->type = type;
409 pagelist->offset = offset;
410
411 /* Populate the fields of the pagelistinfo structure */
412 pagelistinfo->pagelist = pagelist;
413 pagelistinfo->pagelist_buffer_size = pagelist_size;
414 pagelistinfo->dma_addr = dma_addr;
415 pagelistinfo->dma_dir = (type == PAGELIST_WRITE) ?
416 DMA_TO_DEVICE : DMA_FROM_DEVICE;
417 pagelistinfo->num_pages = num_pages;
418 pagelistinfo->pages_need_release = 0;
419 pagelistinfo->pages = pages;
420 pagelistinfo->scatterlist = scatterlist;
421 pagelistinfo->scatterlist_mapped = 0;
422
423 if (buf) {
424 unsigned long length = count;
425 unsigned int off = offset;
426
427 for (actual_pages = 0; actual_pages < num_pages;
428 actual_pages++) {
429 struct page *pg =
430 vmalloc_to_page((buf +
431 (actual_pages * PAGE_SIZE)));
432 size_t bytes = PAGE_SIZE - off;
433
434 if (!pg) {
435 cleanup_pagelistinfo(pagelistinfo);
436 return NULL;
437 }
438
439 if (bytes > length)
440 bytes = length;
441 pages[actual_pages] = pg;
442 length -= bytes;
443 off = 0;
444 }
445 /* do not try and release vmalloc pages */
446 } else {
447 actual_pages = pin_user_pages_fast(
448 (unsigned long)ubuf & PAGE_MASK,
449 num_pages,
450 type == PAGELIST_READ,
451 pages);
452
453 if (actual_pages != num_pages) {
454 vchiq_log_info(vchiq_arm_log_level,
455 "%s - only %d/%d pages locked",
456 __func__, actual_pages, num_pages);
457
458 /* This is probably due to the process being killed */
459 if (actual_pages > 0)
460 unpin_user_pages(pages, actual_pages);
461 cleanup_pagelistinfo(pagelistinfo);
462 return NULL;
463 }
464 /* release user pages */
465 pagelistinfo->pages_need_release = 1;
466 }
467
468 /*
469 * Initialize the scatterlist so that the magic cookie
470 * is filled if debugging is enabled
471 */
472 sg_init_table(scatterlist, num_pages);
473 /* Now set the pages for each scatterlist */
474 for (i = 0; i < num_pages; i++) {
475 unsigned int len = PAGE_SIZE - offset;
476
477 if (len > count)
478 len = count;
479 sg_set_page(scatterlist + i, pages[i], len, offset);
480 offset = 0;
481 count -= len;
482 }
483
484 dma_buffers = dma_map_sg(g_dev,
485 scatterlist,
486 num_pages,
487 pagelistinfo->dma_dir);
488
489 if (dma_buffers == 0) {
490 cleanup_pagelistinfo(pagelistinfo);
491 return NULL;
492 }
493
494 pagelistinfo->scatterlist_mapped = 1;
495
496 /* Combine adjacent blocks for performance */
497 k = 0;
498 for_each_sg(scatterlist, sg, dma_buffers, i) {
499 u32 len = sg_dma_len(sg);
500 u32 addr = sg_dma_address(sg);
501
502 /* Note: addrs is the address + page_count - 1
503 * The firmware expects blocks after the first to be page-
504 * aligned and a multiple of the page size
505 */
506 WARN_ON(len == 0);
507 WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
508 WARN_ON(i && (addr & ~PAGE_MASK));
509 if (k > 0 &&
510 ((addrs[k - 1] & PAGE_MASK) +
511 (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT))
512 == (addr & PAGE_MASK))
513 addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT);
514 else
515 addrs[k++] = (addr & PAGE_MASK) |
516 (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1);
517 }
518
519 /* Partial cache lines (fragments) require special measures */
520 if ((type == PAGELIST_READ) &&
521 ((pagelist->offset & (g_cache_line_size - 1)) ||
522 ((pagelist->offset + pagelist->length) &
523 (g_cache_line_size - 1)))) {
524 char *fragments;
525
526 if (down_interruptible(&g_free_fragments_sema)) {
527 cleanup_pagelistinfo(pagelistinfo);
528 return NULL;
529 }
530
531 WARN_ON(!g_free_fragments);
532
533 down(&g_free_fragments_mutex);
534 fragments = g_free_fragments;
535 WARN_ON(!fragments);
536 g_free_fragments = *(char **) g_free_fragments;
537 up(&g_free_fragments_mutex);
538 pagelist->type = PAGELIST_READ_WITH_FRAGMENTS +
539 (fragments - g_fragments_base) / g_fragments_size;
540 }
541
542 return pagelistinfo;
543 }
544
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx
Attachment:
.config.gz
Description: application/gzip