Hi "Peng, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on soc/for-next] [also build test WARNING on linus/master v5.13 next-20210628] [cannot apply to xlnx/master remoteproc/for-next rpmsg/for-next] [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/Peng-Fan-OSS/remoteproc-elf_loader-fix-loading-segment-when-is_iomem-true/20210628-143358 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-randconfig-s002-20210628 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.3-341-g8af24329-dirty # https://github.com/0day-ci/linux/commit/2c90d7d15776bf485ad028de63002efbc2facc66 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Peng-Fan-OSS/remoteproc-elf_loader-fix-loading-segment-when-is_iomem-true/20210628-143358 git checkout 2c90d7d15776bf485ad028de63002efbc2facc66 # save the attached .config to linux build tree make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot sparse warnings: (new ones prefixed by >>) >> drivers/remoteproc/remoteproc_elf_loader.c:219:45: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void volatile [noderef] __iomem * @@ got void *[assigned] ptr @@ drivers/remoteproc/remoteproc_elf_loader.c:219:45: sparse: expected void volatile [noderef] __iomem * drivers/remoteproc/remoteproc_elf_loader.c:219:45: sparse: got void *[assigned] ptr >> drivers/remoteproc/remoteproc_elf_loader.c:219:51: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const * @@ got void [noderef] __iomem * @@ drivers/remoteproc/remoteproc_elf_loader.c:219:51: sparse: expected void const * drivers/remoteproc/remoteproc_elf_loader.c:219:51: sparse: got void [noderef] __iomem * vim +219 drivers/remoteproc/remoteproc_elf_loader.c 131 132 /** 133 * rproc_elf_load_segments() - load firmware segments to memory 134 * @rproc: remote processor which will be booted using these fw segments 135 * @fw: the ELF firmware image 136 * 137 * This function loads the firmware segments to memory, where the remote 138 * processor expects them. 139 * 140 * Some remote processors will expect their code and data to be placed 141 * in specific device addresses, and can't have them dynamically assigned. 142 * 143 * We currently support only those kind of remote processors, and expect 144 * the program header's paddr member to contain those addresses. We then go 145 * through the physically contiguous "carveout" memory regions which we 146 * allocated (and mapped) earlier on behalf of the remote processor, 147 * and "translate" device address to kernel addresses, so we can copy the 148 * segments where they are expected. 149 * 150 * Currently we only support remote processors that required carveout 151 * allocations and got them mapped onto their iommus. Some processors 152 * might be different: they might not have iommus, and would prefer to 153 * directly allocate memory for every segment/resource. This is not yet 154 * supported, though. 155 */ 156 int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) 157 { 158 struct device *dev = &rproc->dev; 159 const void *ehdr, *phdr; 160 int i, ret = 0; 161 u16 phnum; 162 const u8 *elf_data = fw->data; 163 u8 class = fw_elf_get_class(fw); 164 u32 elf_phdr_get_size = elf_size_of_phdr(class); 165 166 ehdr = elf_data; 167 phnum = elf_hdr_get_e_phnum(class, ehdr); 168 phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr); 169 170 /* go through the available ELF segments */ 171 for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) { 172 u64 da = elf_phdr_get_p_paddr(class, phdr); 173 u64 memsz = elf_phdr_get_p_memsz(class, phdr); 174 u64 filesz = elf_phdr_get_p_filesz(class, phdr); 175 u64 offset = elf_phdr_get_p_offset(class, phdr); 176 u32 type = elf_phdr_get_p_type(class, phdr); 177 void *ptr; 178 bool is_iomem; 179 180 if (type != PT_LOAD) 181 continue; 182 183 dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n", 184 type, da, memsz, filesz); 185 186 if (filesz > memsz) { 187 dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n", 188 filesz, memsz); 189 ret = -EINVAL; 190 break; 191 } 192 193 if (offset + filesz > fw->size) { 194 dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n", 195 offset + filesz, fw->size); 196 ret = -EINVAL; 197 break; 198 } 199 200 if (!rproc_u64_fit_in_size_t(memsz)) { 201 dev_err(dev, "size (%llx) does not fit in size_t type\n", 202 memsz); 203 ret = -EOVERFLOW; 204 break; 205 } 206 207 /* grab the kernel address for this device address */ 208 ptr = rproc_da_to_va(rproc, da, memsz, &is_iomem); 209 if (!ptr) { 210 dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da, 211 memsz); 212 ret = -EINVAL; 213 break; 214 } 215 216 /* put the segment where the remote processor expects it */ 217 if (filesz) { 218 if (is_iomem) > 219 memcpy_toio(ptr, (void __iomem *)(elf_data + offset), filesz); 220 else 221 memcpy(ptr, elf_data + offset, filesz); 222 } 223 224 /* 225 * Zero out remaining memory for this segment. 226 * 227 * This isn't strictly required since dma_alloc_coherent already 228 * did this for us. albeit harmless, we may consider removing 229 * this. 230 */ 231 if (memsz > filesz) { 232 if (is_iomem) 233 memset_io((void __iomem *)(ptr + filesz), 0, memsz - filesz); 234 else 235 memset(ptr + filesz, 0, memsz - filesz); 236 } 237 } 238 239 return ret; 240 } 241 EXPORT_SYMBOL(rproc_elf_load_segments); 242 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org