[PATCH v3 5/5] staging: vchiq: Combine vchiq platform code into single file

kernel test robot lkp at intel.com
Sun Jul 4 11:07:11 PDT 2021


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 at intel.com>

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@lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 43420 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210705/db976851/attachment-0001.gz>


More information about the linux-arm-kernel mailing list