From patchwork Tue Jun 26 00:58:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend, 01/12] soc: qcom: smem: rename variable in qcom_smem_get_global() X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139906 Message-Id: <20180626005856.14174-2-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:45 -0500 From: Alex Elder List-Id: Rename the variable "area" to be "region" in qcom_smem_get_global(), so its name better matches its type. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 70b2ee80d6bd..c46bb43c0f3d 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -277,7 +277,7 @@ struct qcom_smem { u32 item_count; unsigned num_regions; - struct smem_region regions[0]; + struct smem_region regions[]; }; static void * @@ -494,7 +494,7 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, size_t *size) { struct smem_header *header; - struct smem_region *area; + struct smem_region *region; struct smem_global_entry *entry; u32 aux_base; unsigned i; @@ -507,12 +507,12 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK; for (i = 0; i < smem->num_regions; i++) { - area = &smem->regions[i]; + region = &smem->regions[i]; - if (area->aux_base == aux_base || !aux_base) { + if (region->aux_base == aux_base || !aux_base) { if (size != NULL) *size = le32_to_cpu(entry->size); - return area->virt_base + le32_to_cpu(entry->offset); + return region->virt_base + le32_to_cpu(entry->offset); } } From patchwork Tue Jun 26 00:58:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend, 02/12] soc: qcom: smem: initialize region struct only when successful X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139895 Message-Id: <20180626005856.14174-3-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:46 -0500 From: Alex Elder List-Id: Hold off initializing anything for the array entry representing a memory region in qcom_smem_map_memory() until we know we've successfully mapped it. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index c46bb43c0f3d..d8008bf480a4 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -887,6 +887,7 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev, { struct device_node *np; struct resource r; + resource_size_t size; int ret; np = of_parse_phandle(dev->of_node, name, 0); @@ -899,12 +900,13 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev, of_node_put(np); if (ret) return ret; + size = resource_size(&r); - smem->regions[i].aux_base = (u32)r.start; - smem->regions[i].size = resource_size(&r); - smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, resource_size(&r)); + smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, size); if (!smem->regions[i].virt_base) return -ENOMEM; + smem->regions[i].aux_base = (u32)r.start; + smem->regions[i].size = size; return 0; } From patchwork Tue Jun 26 00:58:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend, 03/12] soc: qcom: smem: always ignore partitions with 0 offset or size X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139905 Message-Id: <20180626005856.14174-4-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:47 -0500 From: Alex Elder List-Id: In qcom_smem_enumerate_partitions(), any partition table entry having a zero offset or size field is ignored. Move those checks earlier in the loop, because there's no sense in examining the host fields for those entries. Add the same checks in qcom_smem_set_global_partition(), so the scan for the global partition skips over these invalid entries. This allows a later check for zero size or offset once the global entry is found to be eliminated. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index d8008bf480a4..83ba549cfea0 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -742,9 +742,13 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) { entry = &ptable->entry[i]; + if (!le32_to_cpu(entry->offset)) + continue; + if (!le32_to_cpu(entry->size)) + continue; + host0 = le16_to_cpu(entry->host0); host1 = le16_to_cpu(entry->host1); - if (host0 == SMEM_GLOBAL_HOST && host0 == host1) { found = true; break; @@ -756,11 +760,6 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) return -EINVAL; } - if (!le32_to_cpu(entry->offset) || !le32_to_cpu(entry->size)) { - dev_err(smem->dev, "Invalid entry for global partition\n"); - return -EINVAL; - } - header = smem->regions[0].virt_base + le32_to_cpu(entry->offset); host0 = le16_to_cpu(header->host0); host1 = le16_to_cpu(header->host1); @@ -809,18 +808,16 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) { entry = &ptable->entry[i]; + if (!le32_to_cpu(entry->offset)) + continue; + if (!le32_to_cpu(entry->size)) + continue; + host0 = le16_to_cpu(entry->host0); host1 = le16_to_cpu(entry->host1); - if (host0 != local_host && host1 != local_host) continue; - if (!le32_to_cpu(entry->offset)) - continue; - - if (!le32_to_cpu(entry->size)) - continue; - if (host0 == local_host) remote_host = host1; else From patchwork Tue Jun 26 00:58:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend, 04/12] soc: qcom: smem: small refactor in qcom_smem_enumerate_partitions() X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139904 Message-Id: <20180626005856.14174-5-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:48 -0500 From: Alex Elder List-Id: Combine the code that checks whether a partition table entry is associated with the local host with the assignment of the remote host id value. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 83ba549cfea0..5d3ed510e54b 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -815,13 +815,12 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, host0 = le16_to_cpu(entry->host0); host1 = le16_to_cpu(entry->host1); - if (host0 != local_host && host1 != local_host) - continue; - if (host0 == local_host) remote_host = host1; - else + else if (host1 == local_host) remote_host = host0; + else + continue; if (remote_host >= SMEM_HOST_COUNT) { dev_err(smem->dev, From patchwork Tue Jun 26 00:58:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend, 05/12] soc: qcom: smem: verify both host ids in partition header X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139903 Message-Id: <20180626005856.14174-6-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:49 -0500 From: Alex Elder List-Id: The global partition is indicated by having both host values in its table of contents entry equal SMEM_GLOBAL_HOST=0xfffe. In qcom_smem_set_global_partition(), we check whether the header structure at the beginning of the partition contains that host value, but the check only verifies *one* of them. Change the check so the partition header must have SMEM_GLOBAL_HOST for *both* its host fields. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 5d3ed510e54b..6931602d9a9e 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -769,7 +769,7 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) return -EINVAL; } - if (host0 != SMEM_GLOBAL_HOST && host1 != SMEM_GLOBAL_HOST) { + if (host0 != SMEM_GLOBAL_HOST || host1 != SMEM_GLOBAL_HOST) { dev_err(smem->dev, "Global partition hosts are invalid\n"); return -EINVAL; } From patchwork Tue Jun 26 00:58:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend,06/12] soc: qcom: smem: require order of host ids to match X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139896 Message-Id: <20180626005856.14174-7-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:50 -0500 From: Alex Elder List-Id: In qcom_smem_enumerate_partitions(), we find all partitions that have a given local host id in either its host0 or its host1 field in the partition table entry. We then verify that the header structure at the start of each partition also contains the same two host ids as is found in the table of contents. There is no requirement that the order of the two host ids be the same in the table of contents and in the partition header. This patch changes that, requiring host0 to in the partition table entry to equal host0 in the partition header structure (and similar for the host1 values). Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 6931602d9a9e..49f228e9d2d3 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -847,15 +847,9 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, return -EINVAL; } - if (host0 != local_host && host1 != local_host) { + if (host0 != host0 || host1 != host1) { dev_err(smem->dev, - "Partition %d hosts are invalid\n", i); - return -EINVAL; - } - - if (host0 != remote_host && host1 != remote_host) { - dev_err(smem->dev, - "Partition %d hosts are invalid\n", i); + "Partition %d hosts don't match\n", i); return -EINVAL; } From patchwork Tue Jun 26 00:58:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend, 09/12] soc: qcom: smem: verify partition offset_free_uncached X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139898 Message-Id: <20180626005856.14174-10-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:53 -0500 From: Alex Elder List-Id: Add verification in qcom_smem_partition_header() that the offset_free_uncached field in a partition's header structure does not exceed the partition's size. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 95d218d3a595..f5d7af1623a9 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -755,6 +755,12 @@ qcom_smem_partition_header(struct qcom_smem *smem, return NULL; } + if (le32_to_cpu(header->offset_free_uncached) > size) { + dev_err(smem->dev, "bad partition free uncached (%u > %u)\n", + le32_to_cpu(header->offset_free_uncached), size); + return NULL; + } + return header; } @@ -763,7 +769,7 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) struct smem_partition_header *header; struct smem_ptable_entry *entry; struct smem_ptable *ptable; - u32 host0, host1, size; + u32 host0, host1; bool found = false; int i; @@ -803,13 +809,6 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) return -EINVAL; } - size = le32_to_cpu(header->offset_free_uncached); - if (size > le32_to_cpu(header->size)) { - dev_err(smem->dev, - "Global partition has invalid free pointer\n"); - return -EINVAL; - } - smem->global_partition = header; smem->global_cacheline = le32_to_cpu(entry->cacheline); @@ -873,12 +872,6 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, return -EINVAL; } - if (le32_to_cpu(header->offset_free_uncached) > le32_to_cpu(header->size)) { - dev_err(smem->dev, - "Partition %d has invalid free pointer\n", i); - return -EINVAL; - } - smem->partitions[remote_host] = header; smem->cacheline[remote_host] = le32_to_cpu(entry->cacheline); } From patchwork Tue Jun 26 00:58:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend,10/12] soc: qcom: smem: small change in global entry loop X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139897 Message-Id: <20180626005856.14174-11-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:54 -0500 From: Alex Elder List-Id: Change the logic in the loop that finds that global host entry in the partition table not require the host0 and host1 local variables. The next patch will remove them. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index f5d7af1623a9..8597aa03232c 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -784,9 +784,10 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) if (!le32_to_cpu(entry->size)) continue; - host0 = le16_to_cpu(entry->host0); - host1 = le16_to_cpu(entry->host1); - if (host0 == SMEM_GLOBAL_HOST && host0 == host1) { + if (le16_to_cpu(entry->host0) != SMEM_GLOBAL_HOST) + continue; + + if (le16_to_cpu(entry->host1) == SMEM_GLOBAL_HOST) { found = true; break; } From patchwork Tue Jun 26 00:58:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend,11/12] soc: qcom: smem: verify partition host ids match X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139899 Message-Id: <20180626005856.14174-12-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:55 -0500 From: Alex Elder List-Id: Add verification in qcom_smem_partition_header() that the host ids found in a partition's header structure match those in its partition table entry. Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 8597aa03232c..7383a0e1b468 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -734,7 +734,7 @@ static u32 qcom_smem_get_item_count(struct qcom_smem *smem) */ static struct smem_partition_header * qcom_smem_partition_header(struct qcom_smem *smem, - struct smem_ptable_entry *entry) + struct smem_ptable_entry *entry, u16 host0, u16 host1) { struct smem_partition_header *header; u32 size; @@ -748,6 +748,17 @@ qcom_smem_partition_header(struct qcom_smem *smem, return NULL; } + if (host0 != le16_to_cpu(header->host0)) { + dev_err(smem->dev, "bad host0 (%hu != %hu)\n", + host0, le16_to_cpu(header->host0)); + return NULL; + } + if (host1 != le16_to_cpu(header->host1)) { + dev_err(smem->dev, "bad host1 (%hu != %hu)\n", + host1, le16_to_cpu(header->host1)); + return NULL; + } + size = le32_to_cpu(header->size); if (size != le32_to_cpu(entry->size)) { dev_err(smem->dev, "bad partition size (%u != %u)\n", @@ -769,7 +780,6 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) struct smem_partition_header *header; struct smem_ptable_entry *entry; struct smem_ptable *ptable; - u32 host0, host1; bool found = false; int i; @@ -798,18 +808,11 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) return -EINVAL; } - header = qcom_smem_partition_header(smem, entry); + header = qcom_smem_partition_header(smem, entry, + SMEM_GLOBAL_HOST, SMEM_GLOBAL_HOST); if (!header) return -EINVAL; - host0 = le16_to_cpu(header->host0); - host1 = le16_to_cpu(header->host1); - - if (host0 != SMEM_GLOBAL_HOST || host1 != SMEM_GLOBAL_HOST) { - dev_err(smem->dev, "Global partition hosts are invalid\n"); - return -EINVAL; - } - smem->global_partition = header; smem->global_cacheline = le32_to_cpu(entry->cacheline); @@ -860,19 +863,10 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, return -EINVAL; } - header = qcom_smem_partition_header(smem, entry); + header = qcom_smem_partition_header(smem, entry, host0, host1); if (!header) return -EINVAL; - host0 = le16_to_cpu(header->host0); - host1 = le16_to_cpu(header->host1); - - if (host0 != host0 || host1 != host1) { - dev_err(smem->dev, - "Partition %d hosts don't match\n", i); - return -EINVAL; - } - smem->partitions[remote_host] = header; smem->cacheline[remote_host] = le32_to_cpu(entry->cacheline); } From patchwork Tue Jun 26 00:58:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [resend,12/12] soc: qcom: smem: a few last cleanups X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 139900 Message-Id: <20180626005856.14174-13-elder@linaro.org> To: andy.gross@linaro.org Cc: clew@codeaurora.org, aneela@codeaurora.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 25 Jun 2018 19:58:56 -0500 From: Alex Elder List-Id: This patch contains several small cleanups: - In qcom_smem_enumerate_partitions(), change the "local_host" argument to have 16 bit unsigned type - Also in qcom_smem_enumerate_partitions(), change the type of the "host0" and "host1" local variables to be u16 - Fix error messages reporting host ids to use the right format specifier - Shorten the error messages as well, to fit on one line - Add a compile-time check to ensure the local host value passed to qcom_smem_enumerate_partitions() is in range Signed-off-by: Alex Elder --- drivers/soc/qcom/smem.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) -- 2.17.1 diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 7383a0e1b468..0d7f369c3f7a 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -819,14 +819,14 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem) return 0; } -static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, - unsigned int local_host) +static int +qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) { struct smem_partition_header *header; struct smem_ptable_entry *entry; struct smem_ptable *ptable; unsigned int remote_host; - u32 host0, host1; + u16 host0, host1; int i; ptable = qcom_smem_get_ptable(smem); @@ -850,16 +850,12 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem, continue; if (remote_host >= SMEM_HOST_COUNT) { - dev_err(smem->dev, - "Invalid remote host %d\n", - remote_host); + dev_err(smem->dev, "bad host %hu\n", remote_host); return -EINVAL; } if (smem->partitions[remote_host]) { - dev_err(smem->dev, - "Already found a partition for host %d\n", - remote_host); + dev_err(smem->dev, "duplicate host %hu\n", remote_host); return -EINVAL; } @@ -956,6 +952,7 @@ static int qcom_smem_probe(struct platform_device *pdev) return -EINVAL; } + BUILD_BUG_ON(SMEM_HOST_APPS >= SMEM_HOST_COUNT); ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS); if (ret < 0 && ret != -ENOENT) return ret;