提交 64fb5eb8 编写于 作者: B Bjorn Andersson

soc: qcom: mdt_loader: Allow hash to reside in any segment

It's been observed that some firmware found on Qualcomm SM8450 devices
carries the hash segment as the last segment in the ELF. Extend the
support to allow picking the hash from any segment in the MDT/MBN.
Signed-off-by: NBjorn Andersson <bjorn.andersson@linaro.org>
Reviewed-by: NDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20220128025513.97188-5-bjorn.andersson@linaro.org
上级 8bd42e23
...@@ -126,9 +126,11 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, ...@@ -126,9 +126,11 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
{ {
const struct elf32_phdr *phdrs; const struct elf32_phdr *phdrs;
const struct elf32_hdr *ehdr; const struct elf32_hdr *ehdr;
unsigned int hash_segment = 0;
size_t hash_offset; size_t hash_offset;
size_t hash_size; size_t hash_size;
size_t ehdr_size; size_t ehdr_size;
unsigned int i;
ssize_t ret; ssize_t ret;
void *data; void *data;
...@@ -141,11 +143,20 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, ...@@ -141,11 +143,20 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
if (phdrs[0].p_type == PT_LOAD) if (phdrs[0].p_type == PT_LOAD)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH) for (i = 1; i < ehdr->e_phnum; i++) {
if ((phdrs[i].p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) {
hash_segment = i;
break;
}
}
if (!hash_segment) {
dev_err(dev, "no hash segment found in %s\n", fw_name);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
}
ehdr_size = phdrs[0].p_filesz; ehdr_size = phdrs[0].p_filesz;
hash_size = phdrs[1].p_filesz; hash_size = phdrs[hash_segment].p_filesz;
data = kmalloc(ehdr_size + hash_size, GFP_KERNEL); data = kmalloc(ehdr_size + hash_size, GFP_KERNEL);
if (!data) if (!data)
...@@ -158,13 +169,13 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, ...@@ -158,13 +169,13 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
/* Firmware is split and hash is packed following the ELF header */ /* Firmware is split and hash is packed following the ELF header */
hash_offset = phdrs[0].p_filesz; hash_offset = phdrs[0].p_filesz;
memcpy(data + ehdr_size, fw->data + hash_offset, hash_size); memcpy(data + ehdr_size, fw->data + hash_offset, hash_size);
} else if (phdrs[1].p_offset + hash_size <= fw->size) { } else if (phdrs[hash_segment].p_offset + hash_size <= fw->size) {
/* Hash is in its own segment, but within the loaded file */ /* Hash is in its own segment, but within the loaded file */
hash_offset = phdrs[1].p_offset; hash_offset = phdrs[hash_segment].p_offset;
memcpy(data + ehdr_size, fw->data + hash_offset, hash_size); memcpy(data + ehdr_size, fw->data + hash_offset, hash_size);
} else { } else {
/* Hash is in its own segment, beyond the loaded file */ /* Hash is in its own segment, beyond the loaded file */
ret = mdt_load_split_segment(data + ehdr_size, phdrs, 1, fw_name, dev); ret = mdt_load_split_segment(data + ehdr_size, phdrs, hash_segment, fw_name, dev);
if (ret) { if (ret) {
kfree(data); kfree(data);
return ERR_PTR(ret); return ERR_PTR(ret);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册