1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Remote Processor Framework Elf loader 4 * 5 * Copyright (C) 2011 Texas Instruments, Inc. 6 * Copyright (C) 2011 Google, Inc. 7 * 8 * Ohad Ben-Cohen <ohad@wizery.com> 9 * Brian Swetland <swetland@google.com> 10 * Mark Grosen <mgrosen@ti.com> 11 * Fernando Guzman Lugo <fernando.lugo@ti.com> 12 * Suman Anna <s-anna@ti.com> 13 * Robert Tivy <rtivy@ti.com> 14 * Armando Uribe De Leon <x0095078@ti.com> 15 * Sjur Brændeland <sjur.brandeland@stericsson.com> 16 */ 17 18 #define pr_fmt(fmt) "%s: " fmt, __func__ 19 20 #include <linux/module.h> 21 #include <linux/firmware.h> 22 #include <linux/remoteproc.h> 23 #include <linux/elf.h> 24 25 #include "remoteproc_internal.h" 26 #include "remoteproc_elf_helpers.h" 27 28 /** 29 * rproc_elf_sanity_check() - Sanity Check for ELF32/ELF64 firmware image 30 * @rproc: the remote processor handle 31 * @fw: the ELF firmware image 32 * 33 * Make sure this fw image is sane (ie a correct ELF32/ELF64 file). 34 */ 35 int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw) 36 { 37 const char *name = rproc->firmware; 38 struct device *dev = &rproc->dev; 39 /* 40 * Elf files are beginning with the same structure. Thus, to simplify 41 * header parsing, we can use the elf32_hdr one for both elf64 and 42 * elf32. 43 */ 44 struct elf32_hdr *ehdr; 45 u32 elf_shdr_get_size; 46 u64 phoff, shoff; 47 char class; 48 u16 phnum; 49 50 if (!fw) { 51 dev_err(dev, "failed to load %s\n", name); 52 return -EINVAL; 53 } 54 55 if (fw->size < sizeof(struct elf32_hdr)) { 56 dev_err(dev, "Image is too small\n"); 57 return -EINVAL; 58 } 59 60 ehdr = (struct elf32_hdr *)fw->data; 61 62 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { 63 dev_err(dev, "Image is corrupted (bad magic)\n"); 64 return -EINVAL; 65 } 66 67 class = ehdr->e_ident[EI_CLASS]; 68 if (class != ELFCLASS32 && class != ELFCLASS64) { 69 dev_err(dev, "Unsupported class: %d\n", class); 70 return -EINVAL; 71 } 72 73 if (class == ELFCLASS64 && fw->size < sizeof(struct elf64_hdr)) { 74 dev_err(dev, "elf64 header is too small\n"); 75 return -EINVAL; 76 } 77 78 /* We assume the firmware has the same endianness as the host */ 79 # ifdef __LITTLE_ENDIAN 80 if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) { 81 # else /* BIG ENDIAN */ 82 if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) { 83 # endif 84 dev_err(dev, "Unsupported firmware endianness\n"); 85 return -EINVAL; 86 } 87 88 phoff = elf_hdr_get_e_phoff(class, fw->data); 89 shoff = elf_hdr_get_e_shoff(class, fw->data); 90 phnum = elf_hdr_get_e_phnum(class, fw->data); 91 elf_shdr_get_size = elf_size_of_shdr(class); 92 93 if (fw->size < shoff + elf_shdr_get_size) { 94 dev_err(dev, "Image is too small\n"); 95 return -EINVAL; 96 } 97 98 if (phnum == 0) { 99 dev_err(dev, "No loadable segments\n"); 100 return -EINVAL; 101 } 102 103 if (phoff > fw->size) { 104 dev_err(dev, "Firmware size is too small\n"); 105 return -EINVAL; 106 } 107 108 dev_dbg(dev, "Firmware is an elf%d file\n", 109 class == ELFCLASS32 ? 32 : 64); 110 111 return 0; 112 } 113 EXPORT_SYMBOL(rproc_elf_sanity_check); 114 115 /** 116 * rproc_elf_sanity_check() - Sanity Check ELF32 firmware image 117 * @rproc: the remote processor handle 118 * @fw: the ELF32 firmware image 119 * 120 * Make sure this fw image is sane. 121 */ 122 int rproc_elf32_sanity_check(struct rproc *rproc, const struct firmware *fw) 123 { 124 int ret = rproc_elf_sanity_check(rproc, fw); 125 126 if (ret) 127 return ret; 128 129 if (fw_elf_get_class(fw) == ELFCLASS32) 130 return 0; 131 132 return -EINVAL; 133 } 134 EXPORT_SYMBOL(rproc_elf32_sanity_check); 135 136 /** 137 * rproc_elf_get_boot_addr() - Get rproc's boot address. 138 * @rproc: the remote processor handle 139 * @fw: the ELF firmware image 140 * 141 * This function returns the entry point address of the ELF 142 * image. 143 * 144 * Note that the boot address is not a configurable property of all remote 145 * processors. Some will always boot at a specific hard-coded address. 146 */ 147 u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw) 148 { 149 return elf_hdr_get_e_entry(fw_elf_get_class(fw), fw->data); 150 } 151 EXPORT_SYMBOL(rproc_elf_get_boot_addr); 152 153 /** 154 * rproc_elf_load_segments() - load firmware segments to memory 155 * @rproc: remote processor which will be booted using these fw segments 156 * @fw: the ELF firmware image 157 * 158 * This function loads the firmware segments to memory, where the remote 159 * processor expects them. 160 * 161 * Some remote processors will expect their code and data to be placed 162 * in specific device addresses, and can't have them dynamically assigned. 163 * 164 * We currently support only those kind of remote processors, and expect 165 * the program header's paddr member to contain those addresses. We then go 166 * through the physically contiguous "carveout" memory regions which we 167 * allocated (and mapped) earlier on behalf of the remote processor, 168 * and "translate" device address to kernel addresses, so we can copy the 169 * segments where they are expected. 170 * 171 * Currently we only support remote processors that required carveout 172 * allocations and got them mapped onto their iommus. Some processors 173 * might be different: they might not have iommus, and would prefer to 174 * directly allocate memory for every segment/resource. This is not yet 175 * supported, though. 176 */ 177 int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) 178 { 179 struct device *dev = &rproc->dev; 180 const void *ehdr, *phdr; 181 int i, ret = 0; 182 u16 phnum; 183 const u8 *elf_data = fw->data; 184 u8 class = fw_elf_get_class(fw); 185 u32 elf_phdr_get_size = elf_size_of_phdr(class); 186 187 ehdr = elf_data; 188 phnum = elf_hdr_get_e_phnum(class, ehdr); 189 phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr); 190 191 /* go through the available ELF segments */ 192 for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) { 193 u64 da = elf_phdr_get_p_paddr(class, phdr); 194 u64 memsz = elf_phdr_get_p_memsz(class, phdr); 195 u64 filesz = elf_phdr_get_p_filesz(class, phdr); 196 u64 offset = elf_phdr_get_p_offset(class, phdr); 197 u32 type = elf_phdr_get_p_type(class, phdr); 198 void *ptr; 199 200 if (type != PT_LOAD) 201 continue; 202 203 dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n", 204 type, da, memsz, filesz); 205 206 if (filesz > memsz) { 207 dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n", 208 filesz, memsz); 209 ret = -EINVAL; 210 break; 211 } 212 213 if (offset + filesz > fw->size) { 214 dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n", 215 offset + filesz, fw->size); 216 ret = -EINVAL; 217 break; 218 } 219 220 if (!rproc_u64_fit_in_size_t(memsz)) { 221 dev_err(dev, "size (%llx) does not fit in size_t type\n", 222 memsz); 223 ret = -EOVERFLOW; 224 break; 225 } 226 227 /* grab the kernel address for this device address */ 228 ptr = rproc_da_to_va(rproc, da, memsz); 229 if (!ptr) { 230 dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da, 231 memsz); 232 ret = -EINVAL; 233 break; 234 } 235 236 /* put the segment where the remote processor expects it */ 237 if (filesz) 238 memcpy(ptr, elf_data + offset, filesz); 239 240 /* 241 * Zero out remaining memory for this segment. 242 * 243 * This isn't strictly required since dma_alloc_coherent already 244 * did this for us. albeit harmless, we may consider removing 245 * this. 246 */ 247 if (memsz > filesz) 248 memset(ptr + filesz, 0, memsz - filesz); 249 } 250 251 if (ret == 0) 252 rproc->elf_class = class; 253 254 return ret; 255 } 256 EXPORT_SYMBOL(rproc_elf_load_segments); 257 258 static const void * 259 find_table(struct device *dev, const struct firmware *fw) 260 { 261 const void *shdr, *name_table_shdr; 262 int i; 263 const char *name_table; 264 struct resource_table *table = NULL; 265 const u8 *elf_data = (void *)fw->data; 266 u8 class = fw_elf_get_class(fw); 267 size_t fw_size = fw->size; 268 const void *ehdr = elf_data; 269 u16 shnum = elf_hdr_get_e_shnum(class, ehdr); 270 u32 elf_shdr_get_size = elf_size_of_shdr(class); 271 u16 shstrndx = elf_hdr_get_e_shstrndx(class, ehdr); 272 273 /* look for the resource table and handle it */ 274 /* First, get the section header according to the elf class */ 275 shdr = elf_data + elf_hdr_get_e_shoff(class, ehdr); 276 /* Compute name table section header entry in shdr array */ 277 name_table_shdr = shdr + (shstrndx * elf_shdr_get_size); 278 /* Finally, compute the name table section address in elf */ 279 name_table = elf_data + elf_shdr_get_sh_offset(class, name_table_shdr); 280 281 for (i = 0; i < shnum; i++, shdr += elf_shdr_get_size) { 282 u64 size = elf_shdr_get_sh_size(class, shdr); 283 u64 offset = elf_shdr_get_sh_offset(class, shdr); 284 u32 name = elf_shdr_get_sh_name(class, shdr); 285 286 if (strcmp(name_table + name, ".resource_table")) 287 continue; 288 289 table = (struct resource_table *)(elf_data + offset); 290 291 /* make sure we have the entire table */ 292 if (offset + size > fw_size || offset + size < size) { 293 dev_err(dev, "resource table truncated\n"); 294 return NULL; 295 } 296 297 /* make sure table has at least the header */ 298 if (sizeof(struct resource_table) > size) { 299 dev_err(dev, "header-less resource table\n"); 300 return NULL; 301 } 302 303 /* we don't support any version beyond the first */ 304 if (table->ver != 1) { 305 dev_err(dev, "unsupported fw ver: %d\n", table->ver); 306 return NULL; 307 } 308 309 /* make sure reserved bytes are zeroes */ 310 if (table->reserved[0] || table->reserved[1]) { 311 dev_err(dev, "non zero reserved bytes\n"); 312 return NULL; 313 } 314 315 /* make sure the offsets array isn't truncated */ 316 if (struct_size(table, offset, table->num) > size) { 317 dev_err(dev, "resource table incomplete\n"); 318 return NULL; 319 } 320 321 return shdr; 322 } 323 324 return NULL; 325 } 326 327 /** 328 * rproc_elf_load_rsc_table() - load the resource table 329 * @rproc: the rproc handle 330 * @fw: the ELF firmware image 331 * 332 * This function finds the resource table inside the remote processor's 333 * firmware, load it into the @cached_table and update @table_ptr. 334 * 335 * Return: 0 on success, negative errno on failure. 336 */ 337 int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw) 338 { 339 const void *shdr; 340 struct device *dev = &rproc->dev; 341 struct resource_table *table = NULL; 342 const u8 *elf_data = fw->data; 343 size_t tablesz; 344 u8 class = fw_elf_get_class(fw); 345 u64 sh_offset; 346 347 shdr = find_table(dev, fw); 348 if (!shdr) 349 return -EINVAL; 350 351 sh_offset = elf_shdr_get_sh_offset(class, shdr); 352 table = (struct resource_table *)(elf_data + sh_offset); 353 tablesz = elf_shdr_get_sh_size(class, shdr); 354 355 /* 356 * Create a copy of the resource table. When a virtio device starts 357 * and calls vring_new_virtqueue() the address of the allocated vring 358 * will be stored in the cached_table. Before the device is started, 359 * cached_table will be copied into device memory. 360 */ 361 rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); 362 if (!rproc->cached_table) 363 return -ENOMEM; 364 365 rproc->table_ptr = rproc->cached_table; 366 rproc->table_sz = tablesz; 367 368 return 0; 369 } 370 EXPORT_SYMBOL(rproc_elf_load_rsc_table); 371 372 /** 373 * rproc_elf_find_loaded_rsc_table() - find the loaded resource table 374 * @rproc: the rproc handle 375 * @fw: the ELF firmware image 376 * 377 * This function finds the location of the loaded resource table. Don't 378 * call this function if the table wasn't loaded yet - it's a bug if you do. 379 * 380 * Returns the pointer to the resource table if it is found or NULL otherwise. 381 * If the table wasn't loaded yet the result is unspecified. 382 */ 383 struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, 384 const struct firmware *fw) 385 { 386 const void *shdr; 387 u64 sh_addr, sh_size; 388 u8 class = fw_elf_get_class(fw); 389 struct device *dev = &rproc->dev; 390 391 shdr = find_table(&rproc->dev, fw); 392 if (!shdr) 393 return NULL; 394 395 sh_addr = elf_shdr_get_sh_addr(class, shdr); 396 sh_size = elf_shdr_get_sh_size(class, shdr); 397 398 if (!rproc_u64_fit_in_size_t(sh_size)) { 399 dev_err(dev, "size (%llx) does not fit in size_t type\n", 400 sh_size); 401 return NULL; 402 } 403 404 return rproc_da_to_va(rproc, sh_addr, sh_size); 405 } 406 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table); 407