lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:   Fri, 17 Jul 2020 16:58:37 +0800
From:   kernel test robot <lkp@...el.com>
To:     Alexey Kardashevskiy <aik@...abs.ru>
Cc:     kbuild-all@...ts.01.org, linux-kernel@...r.kernel.org,
        Michael Ellerman <mpe@...erman.id.au>
Subject: arch/powerpc/platforms/powernv/pci-ioda-tce.c:77:34: sparse: sparse:
 cast from restricted __be64

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head:   07a56bb875afbe39dabbf6ba7b83783d166863db
commit: 56090a3902c80c296e822d11acdb6a101b322c52 powerpc/powernv/ioda: Fix race in TCE level allocation
date:   11 months ago
config: powerpc64-randconfig-s031-20200717 (attached as .config)
compiler: powerpc64-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-49-g707c5017-dirty
        git checkout 56090a3902c80c296e822d11acdb6a101b322c52
        # 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=powerpc64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@...el.com>


sparse warnings: (new ones prefixed by >>)

   arch/powerpc/platforms/powernv/pci-ioda-tce.c:196:45: sparse: sparse: cast to restricted __be64
>> arch/powerpc/platforms/powernv/pci-ioda-tce.c:77:34: sparse: sparse: cast from restricted __be64
>> arch/powerpc/platforms/powernv/pci-ioda-tce.c:77:34: sparse: sparse: cast from restricted __be64
   arch/powerpc/platforms/powernv/pci-ioda-tce.c:77:34: sparse: sparse: cast to restricted __be64

vim +77 arch/powerpc/platforms/powernv/pci-ioda-tce.c

    50	
    51	static void pnv_pci_ioda2_table_do_free_pages(__be64 *addr,
    52			unsigned long size, unsigned int levels);
    53	
    54	static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc)
    55	{
    56		__be64 *tmp = user ? tbl->it_userspace : (__be64 *) tbl->it_base;
    57		int  level = tbl->it_indirect_levels;
    58		const long shift = ilog2(tbl->it_level_size);
    59		unsigned long mask = (tbl->it_level_size - 1) << (level * shift);
    60	
    61		while (level) {
    62			int n = (idx & mask) >> (level * shift);
    63			unsigned long oldtce, tce = be64_to_cpu(READ_ONCE(tmp[n]));
    64	
    65			if (!tce) {
    66				__be64 *tmp2;
    67	
    68				if (!alloc)
    69					return NULL;
    70	
    71				tmp2 = pnv_alloc_tce_level(tbl->it_nid,
    72						ilog2(tbl->it_level_size) + 3);
    73				if (!tmp2)
    74					return NULL;
    75	
    76				tce = __pa(tmp2) | TCE_PCI_READ | TCE_PCI_WRITE;
  > 77				oldtce = be64_to_cpu(cmpxchg(&tmp[n], 0,
    78						cpu_to_be64(tce)));
    79				if (oldtce) {
    80					pnv_pci_ioda2_table_do_free_pages(tmp2,
    81						ilog2(tbl->it_level_size) + 3, 1);
    82					tce = oldtce;
    83				}
    84			}
    85	
    86			tmp = __va(tce & ~(TCE_PCI_READ | TCE_PCI_WRITE));
    87			idx &= ~mask;
    88			mask >>= shift;
    89			--level;
    90		}
    91	
    92		return tmp + idx;
    93	}
    94	
    95	int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
    96			unsigned long uaddr, enum dma_data_direction direction,
    97			unsigned long attrs)
    98	{
    99		u64 proto_tce = iommu_direction_to_tce_perm(direction);
   100		u64 rpn = __pa(uaddr) >> tbl->it_page_shift;
   101		long i;
   102	
   103		if (proto_tce & TCE_PCI_WRITE)
   104			proto_tce |= TCE_PCI_READ;
   105	
   106		for (i = 0; i < npages; i++) {
   107			unsigned long newtce = proto_tce |
   108				((rpn + i) << tbl->it_page_shift);
   109			unsigned long idx = index - tbl->it_offset + i;
   110	
   111			*(pnv_tce(tbl, false, idx, true)) = cpu_to_be64(newtce);
   112		}
   113	
   114		return 0;
   115	}
   116	
   117	#ifdef CONFIG_IOMMU_API
   118	int pnv_tce_xchg(struct iommu_table *tbl, long index,
   119			unsigned long *hpa, enum dma_data_direction *direction,
   120			bool alloc)
   121	{
   122		u64 proto_tce = iommu_direction_to_tce_perm(*direction);
   123		unsigned long newtce = *hpa | proto_tce, oldtce;
   124		unsigned long idx = index - tbl->it_offset;
   125		__be64 *ptce = NULL;
   126	
   127		BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl));
   128	
   129		if (*direction == DMA_NONE) {
   130			ptce = pnv_tce(tbl, false, idx, false);
   131			if (!ptce) {
   132				*hpa = 0;
   133				return 0;
   134			}
   135		}
   136	
   137		if (!ptce) {
   138			ptce = pnv_tce(tbl, false, idx, alloc);
   139			if (!ptce)
   140				return alloc ? H_HARDWARE : H_TOO_HARD;
   141		}
   142	
   143		if (newtce & TCE_PCI_WRITE)
   144			newtce |= TCE_PCI_READ;
   145	
   146		oldtce = be64_to_cpu(xchg(ptce, cpu_to_be64(newtce)));
   147		*hpa = oldtce & ~(TCE_PCI_READ | TCE_PCI_WRITE);
   148		*direction = iommu_tce_direction(oldtce);
   149	
   150		return 0;
   151	}
   152	
   153	__be64 *pnv_tce_useraddrptr(struct iommu_table *tbl, long index, bool alloc)
   154	{
   155		if (WARN_ON_ONCE(!tbl->it_userspace))
   156			return NULL;
   157	
   158		return pnv_tce(tbl, true, index - tbl->it_offset, alloc);
   159	}
   160	#endif
   161	
   162	void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
   163	{
   164		long i;
   165	
   166		for (i = 0; i < npages; i++) {
   167			unsigned long idx = index - tbl->it_offset + i;
   168			__be64 *ptce = pnv_tce(tbl, false, idx,	false);
   169	
   170			if (ptce)
   171				*ptce = cpu_to_be64(0);
   172		}
   173	}
   174	
   175	unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
   176	{
   177		__be64 *ptce = pnv_tce(tbl, false, index - tbl->it_offset, false);
   178	
   179		if (!ptce)
   180			return 0;
   181	
   182		return be64_to_cpu(*ptce);
   183	}
   184	
   185	static void pnv_pci_ioda2_table_do_free_pages(__be64 *addr,
   186			unsigned long size, unsigned int levels)
   187	{
   188		const unsigned long addr_ul = (unsigned long) addr &
   189				~(TCE_PCI_READ | TCE_PCI_WRITE);
   190	
   191		if (levels) {
   192			long i;
   193			u64 *tmp = (u64 *) addr_ul;
   194	
   195			for (i = 0; i < size; ++i) {
 > 196				unsigned long hpa = be64_to_cpu(tmp[i]);
   197	
   198				if (!(hpa & (TCE_PCI_READ | TCE_PCI_WRITE)))
   199					continue;
   200	
   201				pnv_pci_ioda2_table_do_free_pages(__va(hpa), size,
   202						levels - 1);
   203			}
   204		}
   205	
   206		free_pages(addr_ul, get_order(size << 3));
   207	}
   208	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

Download attachment ".config.gz" of type "application/gzip" (29756 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ