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_get_boot_addr() - Get rproc's boot address. 117 * @rproc: the remote processor handle 118 * @fw: the ELF firmware image 119 * 120 * This function returns the entry point address of the ELF 121 * image. 122 * 123 * Note that the boot address is not a configurable property of all remote 124 * processors. Some will always boot at a specific hard-coded address. 125 */ 126 u64 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw) 127 { 128 return elf_hdr_get_e_entry(fw_elf_get_class(fw), fw->data); 129 } 130 EXPORT_SYMBOL(rproc_elf_get_boot_addr); 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 179 if (type != PT_LOAD) 180 continue; 181 182 dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n", 183 type, da, memsz, filesz); 184 185 if (filesz > memsz) { 186 dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n", 187 filesz, memsz); 188 ret = -EINVAL; 189 break; 190 } 191 192 if (offset + filesz > fw->size) { 193 dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n", 194 offset + filesz, fw->size); 195 ret = -EINVAL; 196 break; 197 } 198 199 if (!rproc_u64_fit_in_size_t(memsz)) { 200 dev_err(dev, "size (%llx) does not fit in size_t type\n", 201 memsz); 202 ret = -EOVERFLOW; 203 break; 204 } 205 206 /* grab the kernel address for this device address */ 207 ptr = rproc_da_to_va(rproc, da, memsz); 208 if (!ptr) { 209 dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da, 210 memsz); 211 ret = -EINVAL; 212 break; 213 } 214 215 /* put the segment where the remote processor expects it */ 216 if (filesz) 217 memcpy(ptr, elf_data + offset, filesz); 218 219 /* 220 * Zero out remaining memory for this segment. 221 * 222 * This isn't strictly required since dma_alloc_coherent already 223 * did this for us. albeit harmless, we may consider removing 224 * this. 225 */ 226 if (memsz > filesz) 227 memset(ptr + filesz, 0, memsz - filesz); 228 } 229 230 return ret; 231 } 232 EXPORT_SYMBOL(rproc_elf_load_segments); 233 234 static const void * 235 find_table(struct device *dev, const struct firmware *fw) 236 { 237 const void *shdr, *name_table_shdr; 238 int i; 239 const char *name_table; 240 struct resource_table *table = NULL; 241 const u8 *elf_data = (void *)fw->data; 242 u8 class = fw_elf_get_class(fw); 243 size_t fw_size = fw->size; 244 const void *ehdr = elf_data; 245 u16 shnum = elf_hdr_get_e_shnum(class, ehdr); 246 u32 elf_shdr_get_size = elf_size_of_shdr(class); 247 u16 shstrndx = elf_hdr_get_e_shstrndx(class, ehdr); 248 249 /* look for the resource table and handle it */ 250 /* First, get the section header according to the elf class */ 251 shdr = elf_data + elf_hdr_get_e_shoff(class, ehdr); 252 /* Compute name table section header entry in shdr array */ 253 name_table_shdr = shdr + (shstrndx * elf_shdr_get_size); 254 /* Finally, compute the name table section address in elf */ 255 name_table = elf_data + elf_shdr_get_sh_offset(class, name_table_shdr); 256 257 for (i = 0; i < shnum; i++, shdr += elf_shdr_get_size) { 258 u64 size = elf_shdr_get_sh_size(class, shdr); 259 u64 offset = elf_shdr_get_sh_offset(class, shdr); 260 u32 name = elf_shdr_get_sh_name(class, shdr); 261 262 if (strcmp(name_table + name, ".resource_table")) 263 continue; 264 265 table = (struct resource_table *)(elf_data + offset); 266 267 /* make sure we have the entire table */ 268 if (offset + size > fw_size || offset + size < size) { 269 dev_err(dev, "resource table truncated\n"); 270 return NULL; 271 } 272 273 /* make sure table has at least the header */ 274 if (sizeof(struct resource_table) > size) { 275 dev_err(dev, "header-less resource table\n"); 276 return NULL; 277 } 278 279 /* we don't support any version beyond the first */ 280 if (table->ver != 1) { 281 dev_err(dev, "unsupported fw ver: %d\n", table->ver); 282 return NULL; 283 } 284 285 /* make sure reserved bytes are zeroes */ 286 if (table->reserved[0] || table->reserved[1]) { 287 dev_err(dev, "non zero reserved bytes\n"); 288 return NULL; 289 } 290 291 /* make sure the offsets array isn't truncated */ 292 if (struct_size(table, offset, table->num) > size) { 293 dev_err(dev, "resource table incomplete\n"); 294 return NULL; 295 } 296 297 return shdr; 298 } 299 300 return NULL; 301 } 302 303 /** 304 * rproc_elf_load_rsc_table() - load the resource table 305 * @rproc: the rproc handle 306 * @fw: the ELF firmware image 307 * 308 * This function finds the resource table inside the remote processor's 309 * firmware, load it into the @cached_table and update @table_ptr. 310 * 311 * Return: 0 on success, negative errno on failure. 312 */ 313 int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw) 314 { 315 const void *shdr; 316 struct device *dev = &rproc->dev; 317 struct resource_table *table = NULL; 318 const u8 *elf_data = fw->data; 319 size_t tablesz; 320 u8 class = fw_elf_get_class(fw); 321 u64 sh_offset; 322 323 shdr = find_table(dev, fw); 324 if (!shdr) 325 return -EINVAL; 326 327 sh_offset = elf_shdr_get_sh_offset(class, shdr); 328 table = (struct resource_table *)(elf_data + sh_offset); 329 tablesz = elf_shdr_get_sh_size(class, shdr); 330 331 /* 332 * Create a copy of the resource table. When a virtio device starts 333 * and calls vring_new_virtqueue() the address of the allocated vring 334 * will be stored in the cached_table. Before the device is started, 335 * cached_table will be copied into device memory. 336 */ 337 rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); 338 if (!rproc->cached_table) 339 return -ENOMEM; 340 341 rproc->table_ptr = rproc->cached_table; 342 rproc->table_sz = tablesz; 343 344 return 0; 345 } 346 EXPORT_SYMBOL(rproc_elf_load_rsc_table); 347 348 /** 349 * rproc_elf_find_loaded_rsc_table() - find the loaded resource table 350 * @rproc: the rproc handle 351 * @fw: the ELF firmware image 352 * 353 * This function finds the location of the loaded resource table. Don't 354 * call this function if the table wasn't loaded yet - it's a bug if you do. 355 * 356 * Returns the pointer to the resource table if it is found or NULL otherwise. 357 * If the table wasn't loaded yet the result is unspecified. 358 */ 359 struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, 360 const struct firmware *fw) 361 { 362 const void *shdr; 363 u64 sh_addr, sh_size; 364 u8 class = fw_elf_get_class(fw); 365 struct device *dev = &rproc->dev; 366 367 shdr = find_table(&rproc->dev, fw); 368 if (!shdr) 369 return NULL; 370 371 sh_addr = elf_shdr_get_sh_addr(class, shdr); 372 sh_size = elf_shdr_get_sh_size(class, shdr); 373 374 if (!rproc_u64_fit_in_size_t(sh_size)) { 375 dev_err(dev, "size (%llx) does not fit in size_t type\n", 376 sh_size); 377 return NULL; 378 } 379 380 return rproc_da_to_va(rproc, sh_addr, sh_size); 381 } 382 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table); 383