All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/2] smem partition remap and bound check changes
@ 2021-07-08 16:58 Deepak Kumar Singh
  2021-07-08 16:58 ` [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST Deepak Kumar Singh
  2021-07-08 16:58 ` [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures Deepak Kumar Singh
  0 siblings, 2 replies; 6+ messages in thread
From: Deepak Kumar Singh @ 2021-07-08 16:58 UTC (permalink / raw)
  To: bjorn.andersson, clew
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc, Deepak Kumar Singh

Change from[V1]
Addressed most of the review comments in V1.
Also changed the patch order.

Deepak Kumar Singh (2):
  soc: qcom: smem: map only partitions used by local HOST
  soc: qcom: smem: validate fields of shared structures

 drivers/soc/qcom/smem.c | 290 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 229 insertions(+), 61 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST
  2021-07-08 16:58 [PATCH V2 0/2] smem partition remap and bound check changes Deepak Kumar Singh
@ 2021-07-08 16:58 ` Deepak Kumar Singh
  2021-07-08 23:17     ` kernel test robot
  2021-07-08 16:58 ` [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures Deepak Kumar Singh
  1 sibling, 1 reply; 6+ messages in thread
From: Deepak Kumar Singh @ 2021-07-08 16:58 UTC (permalink / raw)
  To: bjorn.andersson, clew
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc,
	Deepak Kumar Singh, Andy Gross

SMEM driver is IO mapping complete region and CPU is doing a speculative
read into a partition where local HOST does not have permission resulting
in a NOC error.

Map only those partitions which are accessibly to local HOST.

Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
---
 drivers/soc/qcom/smem.c | 208 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 157 insertions(+), 51 deletions(-)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index cc4e065..9404eec 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -194,6 +194,20 @@ struct smem_partition_header {
 	__le32 reserved[3];
 };
 
+/**
+ * struct smem_partition - describes smem partition
+ * @virt_base:	starting virtual address of partition
+ * @phys_base:	starting physical address of partition
+ * @cacheline:	alignment for "cached" entries
+ * @size:	size of partition
+ */
+struct smem_partition {
+	void __iomem *virt_base;
+	phys_addr_t phys_base;
+	size_t cacheline;
+	size_t size;
+};
+
 static const u8 SMEM_PART_MAGIC[] = { 0x24, 0x50, 0x52, 0x54 };
 
 /**
@@ -249,11 +263,9 @@ struct smem_region {
  * struct qcom_smem - device data for the smem device
  * @dev:	device pointer
  * @hwlock:	reference to a hwspinlock
- * @global_partition:	pointer to global partition when in use
- * @global_cacheline:	cacheline size for global partition
- * @partitions:	list of pointers to partitions affecting the current
- *		processor/host
- * @cacheline:	list of cacheline sizes for each host
+ * @ptable: virtual base of partition table
+ * @global_partition: describes for global partition when in use
+ * @partitions: list of partitions of current processor/host
  * @item_count: max accepted item number
  * @socinfo:	platform device pointer
  * @num_regions: number of @regions
@@ -264,12 +276,11 @@ struct qcom_smem {
 
 	struct hwspinlock *hwlock;
 
-	struct smem_partition_header *global_partition;
-	size_t global_cacheline;
-	struct smem_partition_header *partitions[SMEM_HOST_COUNT];
-	size_t cacheline[SMEM_HOST_COUNT];
 	u32 item_count;
 	struct platform_device *socinfo;
+	struct smem_ptable *ptable;
+	struct smem_partition global_partition;
+	struct smem_partition partitions[SMEM_HOST_COUNT];
 
 	unsigned num_regions;
 	struct smem_region regions[];
@@ -347,14 +358,17 @@ static struct qcom_smem *__smem;
 #define HWSPINLOCK_TIMEOUT	1000
 
 static int qcom_smem_alloc_private(struct qcom_smem *smem,
-				   struct smem_partition_header *phdr,
+				   struct smem_partition *part,
 				   unsigned item,
 				   size_t size)
 {
 	struct smem_private_entry *hdr, *end;
+	struct smem_partition_header *phdr;
 	size_t alloc_size;
 	void *cached;
 
+	phdr = part->virt_base;
+
 	hdr = phdr_to_first_uncached_entry(phdr);
 	end = phdr_to_last_uncached_entry(phdr);
 	cached = phdr_to_last_cached_entry(phdr);
@@ -441,7 +455,7 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
  */
 int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
 {
-	struct smem_partition_header *phdr;
+	struct smem_partition *part;
 	unsigned long flags;
 	int ret;
 
@@ -463,12 +477,12 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
 	if (ret)
 		return ret;
 
-	if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
-		phdr = __smem->partitions[host];
-		ret = qcom_smem_alloc_private(__smem, phdr, item, size);
-	} else if (__smem->global_partition) {
-		phdr = __smem->global_partition;
-		ret = qcom_smem_alloc_private(__smem, phdr, item, size);
+	if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
+		part = &__smem->partitions[host];
+		ret = qcom_smem_alloc_private(__smem, part, item, size);
+	} else if (__smem->global_partition.virt_base) {
+		part = &__smem->global_partition;
+		ret = qcom_smem_alloc_private(__smem, part, item, size);
 	} else {
 		ret = qcom_smem_alloc_global(__smem, item, size);
 	}
@@ -510,12 +524,14 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
 }
 
 static void *qcom_smem_get_private(struct qcom_smem *smem,
-				   struct smem_partition_header *phdr,
-				   size_t cacheline,
+				   struct smem_partition *part,
 				   unsigned item,
 				   size_t *size)
 {
 	struct smem_private_entry *e, *end;
+	struct smem_partition_header *phdr;
+
+	phdr = part->virt_base;
 
 	e = phdr_to_first_uncached_entry(phdr);
 	end = phdr_to_last_uncached_entry(phdr);
@@ -537,7 +553,7 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
 
 	/* Item was not found in the uncached list, search the cached list */
 
-	e = phdr_to_first_cached_entry(phdr, cacheline);
+	e = phdr_to_first_cached_entry(phdr, part->cacheline);
 	end = phdr_to_last_cached_entry(phdr);
 
 	while (e > end) {
@@ -552,7 +568,7 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
 			return cached_entry_to_item(e);
 		}
 
-		e = cached_entry_next(e, cacheline);
+		e = cached_entry_next(e, part->cacheline);
 	}
 
 	return ERR_PTR(-ENOENT);
@@ -575,9 +591,8 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
  */
 void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
 {
-	struct smem_partition_header *phdr;
+	struct smem_partition *part;
 	unsigned long flags;
-	size_t cacheln;
 	int ret;
 	void *ptr = ERR_PTR(-EPROBE_DEFER);
 
@@ -593,14 +608,12 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
 	if (ret)
 		return ERR_PTR(ret);
 
-	if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
-		phdr = __smem->partitions[host];
-		cacheln = __smem->cacheline[host];
-		ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
-	} else if (__smem->global_partition) {
-		phdr = __smem->global_partition;
-		cacheln = __smem->global_cacheline;
-		ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
+	if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
+		part = &__smem->partitions[host];
+		ptr = qcom_smem_get_private(__smem, part, item, size);
+	} else if (__smem->global_partition.virt_base) {
+		part = &__smem->global_partition;
+		ptr = qcom_smem_get_private(__smem, part, item, size);
 	} else {
 		ptr = qcom_smem_get_global(__smem, item, size);
 	}
@@ -621,6 +634,7 @@ EXPORT_SYMBOL(qcom_smem_get);
  */
 int qcom_smem_get_free_space(unsigned host)
 {
+	struct smem_partition *part;
 	struct smem_partition_header *phdr;
 	struct smem_header *header;
 	unsigned ret;
@@ -628,12 +642,14 @@ int qcom_smem_get_free_space(unsigned host)
 	if (!__smem)
 		return -EPROBE_DEFER;
 
-	if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
-		phdr = __smem->partitions[host];
+	if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
+		part = &__smem->partitions[host];
+		phdr = part->virt_base;
 		ret = le32_to_cpu(phdr->offset_free_cached) -
 		      le32_to_cpu(phdr->offset_free_uncached);
-	} else if (__smem->global_partition) {
-		phdr = __smem->global_partition;
+	} else if (__smem->global_partition.virt_base) {
+		part = &__smem->global_partition;
+		phdr = part->virt_base;
 		ret = le32_to_cpu(phdr->offset_free_cached) -
 		      le32_to_cpu(phdr->offset_free_uncached);
 	} else {
@@ -645,6 +661,11 @@ int qcom_smem_get_free_space(unsigned host)
 }
 EXPORT_SYMBOL(qcom_smem_get_free_space);
 
+static bool addr_in_range(void __iomem *base, size_t size, void *addr)
+{
+	return base && (addr >= base && addr < base + size);
+}
+
 /**
  * qcom_smem_virt_to_phys() - return the physical address associated
  * with an smem item pointer (previously returned by qcom_smem_get()
@@ -654,17 +675,36 @@ EXPORT_SYMBOL(qcom_smem_get_free_space);
  */
 phys_addr_t qcom_smem_virt_to_phys(void *p)
 {
-	unsigned i;
+	struct smem_partition *part;
+	struct smem_region *area;
+	u64 offset;
+	u32 i;
+
+	for (i = 0; i < SMEM_HOST_COUNT; i++) {
+		part = &__smem->partitions[i];
+
+		if (addr_in_range(part->virt_base, part->size, p)) {
+			offset = p - part->virt_base;
+
+			return (phys_addr_t)part->phys_base + offset;
+		}
+	}
+
+	part = &__smem->global_partition;
+
+	if (addr_in_range(part->virt_base, part->size, p)) {
+		offset = p - part->virt_base;
+
+		return (phys_addr_t)part->phys_base + offset;
+	}
 
 	for (i = 0; i < __smem->num_regions; i++) {
-		struct smem_region *region = &__smem->regions[i];
+		area = &__smem->regions[i];
 
-		if (p < region->virt_base)
-			continue;
-		if (p < region->virt_base + region->size) {
-			u64 offset = p - region->virt_base;
+		if (addr_in_range(area->virt_base, area->size, p)) {
+			offset = p - area->virt_base;
 
-			return (phys_addr_t)region->aux_base + offset;
+			return (phys_addr_t)area->aux_base + offset;
 		}
 	}
 
@@ -688,7 +728,7 @@ static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem)
 	struct smem_ptable *ptable;
 	u32 version;
 
-	ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
+	ptable = smem->ptable;
 	if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
 		return ERR_PTR(-ENOENT);
 
@@ -727,9 +767,14 @@ qcom_smem_partition_header(struct qcom_smem *smem,
 		struct smem_ptable_entry *entry, u16 host0, u16 host1)
 {
 	struct smem_partition_header *header;
+	u32 phys_addr;
 	u32 size;
 
-	header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+	phys_addr = smem->regions[0].aux_base + le32_to_cpu(entry->offset);
+	header = devm_ioremap_wc(smem->dev, phys_addr, le32_to_cpu(entry->size));
+
+	if (!header)
+		return NULL;
 
 	if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
 		dev_err(smem->dev, "bad partition magic %4ph\n", header->magic);
@@ -771,7 +816,7 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
 	bool found = false;
 	int i;
 
-	if (smem->global_partition) {
+	if (smem->global_partition.virt_base) {
 		dev_err(smem->dev, "Already found the global partition\n");
 		return -EINVAL;
 	}
@@ -806,8 +851,11 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
 	if (!header)
 		return -EINVAL;
 
-	smem->global_partition = header;
-	smem->global_cacheline = le32_to_cpu(entry->cacheline);
+	smem->global_partition.virt_base = (void __iomem *)header;
+	smem->global_partition.phys_base = smem->regions[0].aux_base +
+								le32_to_cpu(entry->offset);
+	smem->global_partition.size = le32_to_cpu(entry->size);
+	smem->global_partition.cacheline = le32_to_cpu(entry->cacheline);
 
 	return 0;
 }
@@ -847,7 +895,7 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
 			return -EINVAL;
 		}
 
-		if (smem->partitions[remote_host]) {
+		if (smem->partitions[remote_host].virt_base) {
 			dev_err(smem->dev, "duplicate host %hu\n", remote_host);
 			return -EINVAL;
 		}
@@ -856,8 +904,11 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
 		if (!header)
 			return -EINVAL;
 
-		smem->partitions[remote_host] = header;
-		smem->cacheline[remote_host] = le32_to_cpu(entry->cacheline);
+		smem->partitions[remote_host].virt_base = (void __iomem *)header;
+		smem->partitions[remote_host].phys_base = smem->regions[0].aux_base +
+										le32_to_cpu(entry->offset);
+		smem->partitions[remote_host].size = le32_to_cpu(entry->size);
+		smem->partitions[remote_host].cacheline = le32_to_cpu(entry->cacheline);
 	}
 
 	return 0;
@@ -892,6 +943,58 @@ static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
 	return 0;
 }
 
+static int qcom_smem_map_toc(struct qcom_smem *smem, struct device *dev,
+				const char *name, int i)
+{
+	struct device_node *np;
+	struct resource r;
+	u32 ptable_start;
+	int ret;
+
+	np = of_parse_phandle(dev->of_node, name, 0);
+	if (!np) {
+		dev_err(dev, "No %s specified\n", name);
+		return -EINVAL;
+	}
+
+	ret = of_address_to_resource(np, 0, &r);
+	of_node_put(np);
+	if (ret)
+		return ret;
+
+	smem->regions[i].aux_base = (u32)r.start;
+	smem->regions[i].size = resource_size(&r);
+	/* map starting 4K for smem header */
+	smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, SZ_4K);
+	ptable_start = r.start + resource_size(&r) - SZ_4K;
+	/* map last 4k for toc */
+	smem->ptable = devm_ioremap_wc(dev, ptable_start, SZ_4K);
+
+	if (!smem->regions[i].virt_base || !smem->ptable)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int qcom_smem_map_global(struct qcom_smem *smem)
+{
+	struct smem_header *header;
+	u32 phys_addr;
+	u32 size;
+
+	phys_addr = smem->regions[0].aux_base;
+	header = smem->regions[0].virt_base;
+	size = header->available;
+
+	smem->regions[0].size = size;
+	smem->regions[0].virt_base = devm_ioremap_wc(smem->dev, phys_addr, size);
+
+	if (!smem->regions[0].virt_base)
+		return -ENOMEM;
+
+	return 0;
+}
+
 static int qcom_smem_probe(struct platform_device *pdev)
 {
 	struct smem_header *header;
@@ -914,7 +1017,7 @@ static int qcom_smem_probe(struct platform_device *pdev)
 	smem->dev = &pdev->dev;
 	smem->num_regions = num_regions;
 
-	ret = qcom_smem_map_memory(smem, &pdev->dev, "memory-region", 0);
+	ret = qcom_smem_map_toc(smem, &pdev->dev, "memory-region", 0);
 	if (ret)
 		return ret;
 
@@ -930,6 +1033,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 	}
 
 	version = qcom_smem_get_sbl_version(smem);
+	/* unmap smem header */
+	devm_iounmap(smem->dev, smem->regions[0].virt_base);
 	switch (version >> 16) {
 	case SMEM_GLOBAL_PART_VERSION:
 		ret = qcom_smem_set_global_partition(smem);
@@ -938,6 +1043,7 @@ static int qcom_smem_probe(struct platform_device *pdev)
 		smem->item_count = qcom_smem_get_item_count(smem);
 		break;
 	case SMEM_GLOBAL_HEAP_VERSION:
+		qcom_smem_map_global(smem);
 		smem->item_count = SMEM_ITEM_COUNT;
 		break;
 	default:
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures
  2021-07-08 16:58 [PATCH V2 0/2] smem partition remap and bound check changes Deepak Kumar Singh
  2021-07-08 16:58 ` [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST Deepak Kumar Singh
@ 2021-07-08 16:58 ` Deepak Kumar Singh
  2021-07-09  0:12   ` kernel test robot
  1 sibling, 1 reply; 6+ messages in thread
From: Deepak Kumar Singh @ 2021-07-08 16:58 UTC (permalink / raw)
  To: bjorn.andersson, clew
  Cc: linux-kernel, linux-arm-msm, linux-remoteproc,
	Deepak Kumar Singh, Andy Gross

Structures in shared memory that can be modified by remote
processors may have untrusted values, they should be validated
before use.

Adding proper validation before using fields of shared
structures.

Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
---
 drivers/soc/qcom/smem.c | 82 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 72 insertions(+), 10 deletions(-)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 9404eec..e4f62d9 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -366,13 +366,18 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
 	struct smem_partition_header *phdr;
 	size_t alloc_size;
 	void *cached;
+	void *p_end;
 
 	phdr = part->virt_base;
+	p_end = (void *)phdr + part->size;
 
 	hdr = phdr_to_first_uncached_entry(phdr);
 	end = phdr_to_last_uncached_entry(phdr);
 	cached = phdr_to_last_cached_entry(phdr);
 
+	if (WARN_ON((void *)end > p_end || (void *)cached > p_end))
+		return -EINVAL;
+
 	while (hdr < end) {
 		if (hdr->canary != SMEM_PRIVATE_CANARY)
 			goto bad_canary;
@@ -382,6 +387,9 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
 		hdr = uncached_entry_next(hdr);
 	}
 
+	if (WARN_ON((void *)hdr > p_end))
+		return -EINVAL;
+
 	/* Check that we don't grow into the cached region */
 	alloc_size = sizeof(*hdr) + ALIGN(size, 8);
 	if ((void *)hdr + alloc_size > cached) {
@@ -500,6 +508,8 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
 	struct smem_header *header;
 	struct smem_region *region;
 	struct smem_global_entry *entry;
+	u64 entry_offset;
+	u32 e_size;
 	u32 aux_base;
 	unsigned i;
 
@@ -514,9 +524,16 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
 		region = &smem->regions[i];
 
 		if (region->aux_base == aux_base || !aux_base) {
+			e_size = le32_to_cpu(entry->size);
+			entry_offset = le32_to_cpu(entry->offset);
+
+			if (WARN_ON(e_size + entry_offset > region->size))
+				return ERR_PTR(-EINVAL);
+
 			if (size != NULL)
-				*size = le32_to_cpu(entry->size);
-			return region->virt_base + le32_to_cpu(entry->offset);
+				*size = e_size;
+
+			return region->virt_base + entry_offset;
 		}
 	}
 
@@ -530,47 +547,83 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
 {
 	struct smem_private_entry *e, *end;
 	struct smem_partition_header *phdr;
+	void *item_ptr, *p_end;
+	u32 padding_data;
+	u32 e_size;
 
 	phdr = part->virt_base;
+	p_end = (void *)phdr + part->size;
 
 	e = phdr_to_first_uncached_entry(phdr);
 	end = phdr_to_last_uncached_entry(phdr);
 
+	if (WARN_ON((void *)end > p_end))
+		return ERR_PTR(-EINVAL);
+
 	while (e < end) {
 		if (e->canary != SMEM_PRIVATE_CANARY)
 			goto invalid_canary;
 
 		if (le16_to_cpu(e->item) == item) {
-			if (size != NULL)
-				*size = le32_to_cpu(e->size) -
-					le16_to_cpu(e->padding_data);
+			if (size != NULL) {
+				e_size = le32_to_cpu(e->size);
+				padding_data = le16_to_cpu(e->padding_data);
+
+				if (WARN_ON(e_size > part->size || padding_data > e_size))
+					return ERR_PTR(-EINVAL);
+
+				*size = e_size - padding_data;
+			}
 
-			return uncached_entry_to_item(e);
+			item_ptr = uncached_entry_to_item(e);
+			if (WARN_ON(item_ptr > p_end))
+				return ERR_PTR(-EINVAL);
+
+			return item_ptr;
 		}
 
 		e = uncached_entry_next(e);
 	}
 
+	if (WARN_ON((void *)e > p_end))
+		return ERR_PTR(-EINVAL);
+
 	/* Item was not found in the uncached list, search the cached list */
 
 	e = phdr_to_first_cached_entry(phdr, part->cacheline);
 	end = phdr_to_last_cached_entry(phdr);
 
+	if (WARN_ON((void *)e < (void *)phdr || (void *)end > p_end))
+		return ERR_PTR(-EINVAL);
+
 	while (e > end) {
 		if (e->canary != SMEM_PRIVATE_CANARY)
 			goto invalid_canary;
 
 		if (le16_to_cpu(e->item) == item) {
-			if (size != NULL)
-				*size = le32_to_cpu(e->size) -
-					le16_to_cpu(e->padding_data);
+			if (size != NULL) {
+				e_size = le32_to_cpu(e->size);
+				padding_data = le16_to_cpu(e->padding_data);
+
+				if (WARN_ON(e_size > part->size || padding_data > e_size))
+					return ERR_PTR(-EINVAL);
 
-			return cached_entry_to_item(e);
+				*size = e_size - padding_data;
+			}
+
+			item_ptr = cached_entry_to_item(e);
+			if (WARN_ON(item_ptr < (void *)phdr))
+				return ERR_PTR(-EINVAL);
+
+			return item_ptr;
 		}
 
 		e = cached_entry_next(e, part->cacheline);
 	}
 
+	if (WARN_ON((void *)e < (void *)phdr))
+		return ERR_PTR(-EINVAL);
+
 	return ERR_PTR(-ENOENT);
 
 invalid_canary:
@@ -647,14 +700,23 @@ int qcom_smem_get_free_space(unsigned host)
 		phdr = part->virt_base;
 		ret = le32_to_cpu(phdr->offset_free_cached) -
 		      le32_to_cpu(phdr->offset_free_uncached);
+
+		if (ret > le32_to_cpu(part->size))
+			return -EINVAL;
 	} else if (__smem->global_partition.virt_base) {
 		part = &__smem->global_partition;
 		phdr = part->virt_base;
 		ret = le32_to_cpu(phdr->offset_free_cached) -
 		      le32_to_cpu(phdr->offset_free_uncached);
+
+		if (ret > le32_to_cpu(part->size))
+			return -EINVAL;
 	} else {
 		header = __smem->regions[0].virt_base;
 		ret = le32_to_cpu(header->available);
+
+		if (ret > __smem->regions[0].size)
+			return -EINVAL;
 	}
 
 	return ret;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST
  2021-07-08 16:58 ` [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST Deepak Kumar Singh
@ 2021-07-08 23:17     ` kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-07-08 23:17 UTC (permalink / raw)
  To: Deepak Kumar Singh, bjorn.andersson, clew
  Cc: kbuild-all, linux-kernel, linux-arm-msm, linux-remoteproc,
	Deepak Kumar Singh, Andy Gross

[-- Attachment #1: Type: text/plain, Size: 9212 bytes --]

Hi Deepak,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.13 next-20210708]
[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/Deepak-Kumar-Singh/smem-partition-remap-and-bound-check-changes/20210709-010025
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e9f1cbc0c4114880090c7a578117d3b9cf184ad4
config: x86_64-randconfig-s021-20210707 (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/33e2ecba1aca3061ac33cb9665f417a76902abaa
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Deepak-Kumar-Singh/smem-partition-remap-and-bound-check-changes/20210709-010025
        git checkout 33e2ecba1aca3061ac33cb9665f417a76902abaa
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/soc/qcom/smem.c:370:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:370:14: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:370:14: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:421:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:421:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:421:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:506:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:506:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:506:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:519:50: sparse: sparse: incorrect type in return expression (different address spaces) @@     expected void * @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:519:50: sparse:     expected void *
   drivers/soc/qcom/smem.c:519:50: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:534:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:534:14: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:534:14: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:647:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:647:22: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:647:22: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:652:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:652:22: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:652:22: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:656:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:656:24: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:656:24: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:666:30: sparse: sparse: incompatible types in comparison expression (different address spaces):
   drivers/soc/qcom/smem.c:666:30: sparse:    void *
   drivers/soc/qcom/smem.c:666:30: sparse:    void [noderef] __iomem *
   drivers/soc/qcom/smem.c:687:36: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:696:28: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:705:36: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:720:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:720:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:720:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:753:57: sparse: sparse: restricted __le32 degrades to integer
   drivers/soc/qcom/smem.c:774:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *header @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:774:16: sparse:     expected struct smem_partition_header *header
   drivers/soc/qcom/smem.c:774:16: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:971:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_ptable *ptable @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:971:22: sparse:     expected struct smem_ptable *ptable
   drivers/soc/qcom/smem.c:971:22: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:986:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:986:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:986:16: sparse:     got void [noderef] __iomem *virt_base
>> drivers/soc/qcom/smem.c:987:14: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] size @@     got restricted __le32 [usertype] available @@
   drivers/soc/qcom/smem.c:987:14: sparse:     expected unsigned int [usertype] size
   drivers/soc/qcom/smem.c:987:14: sparse:     got restricted __le32 [usertype] available
   drivers/soc/qcom/smem.c:1028:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:1028:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:1028:16: sparse:     got void [noderef] __iomem *virt_base

vim +370 drivers/soc/qcom/smem.c

   359	
   360	static int qcom_smem_alloc_private(struct qcom_smem *smem,
   361					   struct smem_partition *part,
   362					   unsigned item,
   363					   size_t size)
   364	{
   365		struct smem_private_entry *hdr, *end;
   366		struct smem_partition_header *phdr;
   367		size_t alloc_size;
   368		void *cached;
   369	
 > 370		phdr = part->virt_base;
   371	
   372		hdr = phdr_to_first_uncached_entry(phdr);
   373		end = phdr_to_last_uncached_entry(phdr);
   374		cached = phdr_to_last_cached_entry(phdr);
   375	
   376		while (hdr < end) {
   377			if (hdr->canary != SMEM_PRIVATE_CANARY)
   378				goto bad_canary;
   379			if (le16_to_cpu(hdr->item) == item)
   380				return -EEXIST;
   381	
   382			hdr = uncached_entry_next(hdr);
   383		}
   384	
   385		/* Check that we don't grow into the cached region */
   386		alloc_size = sizeof(*hdr) + ALIGN(size, 8);
   387		if ((void *)hdr + alloc_size > cached) {
   388			dev_err(smem->dev, "Out of memory\n");
   389			return -ENOSPC;
   390		}
   391	
   392		hdr->canary = SMEM_PRIVATE_CANARY;
   393		hdr->item = cpu_to_le16(item);
   394		hdr->size = cpu_to_le32(ALIGN(size, 8));
   395		hdr->padding_data = cpu_to_le16(le32_to_cpu(hdr->size) - size);
   396		hdr->padding_hdr = 0;
   397	
   398		/*
   399		 * Ensure the header is written before we advance the free offset, so
   400		 * that remote processors that does not take the remote spinlock still
   401		 * gets a consistent view of the linked list.
   402		 */
   403		wmb();
   404		le32_add_cpu(&phdr->offset_free_uncached, alloc_size);
   405	
   406		return 0;
   407	bad_canary:
   408		dev_err(smem->dev, "Found invalid canary in hosts %hu:%hu partition\n",
   409			le16_to_cpu(phdr->host0), le16_to_cpu(phdr->host1));
   410	
   411		return -EINVAL;
   412	}
   413	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38793 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST
@ 2021-07-08 23:17     ` kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-07-08 23:17 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 9354 bytes --]

Hi Deepak,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.13 next-20210708]
[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/Deepak-Kumar-Singh/smem-partition-remap-and-bound-check-changes/20210709-010025
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e9f1cbc0c4114880090c7a578117d3b9cf184ad4
config: x86_64-randconfig-s021-20210707 (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/33e2ecba1aca3061ac33cb9665f417a76902abaa
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Deepak-Kumar-Singh/smem-partition-remap-and-bound-check-changes/20210709-010025
        git checkout 33e2ecba1aca3061ac33cb9665f417a76902abaa
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/soc/qcom/smem.c:370:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:370:14: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:370:14: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:421:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:421:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:421:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:506:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:506:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:506:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:519:50: sparse: sparse: incorrect type in return expression (different address spaces) @@     expected void * @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:519:50: sparse:     expected void *
   drivers/soc/qcom/smem.c:519:50: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:534:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:534:14: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:534:14: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:647:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:647:22: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:647:22: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:652:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:652:22: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:652:22: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:656:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:656:24: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:656:24: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:666:30: sparse: sparse: incompatible types in comparison expression (different address spaces):
   drivers/soc/qcom/smem.c:666:30: sparse:    void *
   drivers/soc/qcom/smem.c:666:30: sparse:    void [noderef] __iomem *
   drivers/soc/qcom/smem.c:687:36: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:696:28: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:705:36: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:720:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:720:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:720:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:753:57: sparse: sparse: restricted __le32 degrades to integer
   drivers/soc/qcom/smem.c:774:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *header @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:774:16: sparse:     expected struct smem_partition_header *header
   drivers/soc/qcom/smem.c:774:16: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:971:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_ptable *ptable @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:971:22: sparse:     expected struct smem_ptable *ptable
   drivers/soc/qcom/smem.c:971:22: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:986:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:986:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:986:16: sparse:     got void [noderef] __iomem *virt_base
>> drivers/soc/qcom/smem.c:987:14: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] size @@     got restricted __le32 [usertype] available @@
   drivers/soc/qcom/smem.c:987:14: sparse:     expected unsigned int [usertype] size
   drivers/soc/qcom/smem.c:987:14: sparse:     got restricted __le32 [usertype] available
   drivers/soc/qcom/smem.c:1028:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:1028:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:1028:16: sparse:     got void [noderef] __iomem *virt_base

vim +370 drivers/soc/qcom/smem.c

   359	
   360	static int qcom_smem_alloc_private(struct qcom_smem *smem,
   361					   struct smem_partition *part,
   362					   unsigned item,
   363					   size_t size)
   364	{
   365		struct smem_private_entry *hdr, *end;
   366		struct smem_partition_header *phdr;
   367		size_t alloc_size;
   368		void *cached;
   369	
 > 370		phdr = part->virt_base;
   371	
   372		hdr = phdr_to_first_uncached_entry(phdr);
   373		end = phdr_to_last_uncached_entry(phdr);
   374		cached = phdr_to_last_cached_entry(phdr);
   375	
   376		while (hdr < end) {
   377			if (hdr->canary != SMEM_PRIVATE_CANARY)
   378				goto bad_canary;
   379			if (le16_to_cpu(hdr->item) == item)
   380				return -EEXIST;
   381	
   382			hdr = uncached_entry_next(hdr);
   383		}
   384	
   385		/* Check that we don't grow into the cached region */
   386		alloc_size = sizeof(*hdr) + ALIGN(size, 8);
   387		if ((void *)hdr + alloc_size > cached) {
   388			dev_err(smem->dev, "Out of memory\n");
   389			return -ENOSPC;
   390		}
   391	
   392		hdr->canary = SMEM_PRIVATE_CANARY;
   393		hdr->item = cpu_to_le16(item);
   394		hdr->size = cpu_to_le32(ALIGN(size, 8));
   395		hdr->padding_data = cpu_to_le16(le32_to_cpu(hdr->size) - size);
   396		hdr->padding_hdr = 0;
   397	
   398		/*
   399		 * Ensure the header is written before we advance the free offset, so
   400		 * that remote processors that does not take the remote spinlock still
   401		 * gets a consistent view of the linked list.
   402		 */
   403		wmb();
   404		le32_add_cpu(&phdr->offset_free_uncached, alloc_size);
   405	
   406		return 0;
   407	bad_canary:
   408		dev_err(smem->dev, "Found invalid canary in hosts %hu:%hu partition\n",
   409			le16_to_cpu(phdr->host0), le16_to_cpu(phdr->host1));
   410	
   411		return -EINVAL;
   412	}
   413	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38793 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures
  2021-07-08 16:58 ` [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures Deepak Kumar Singh
@ 2021-07-09  0:12   ` kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2021-07-09  0:12 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 14829 bytes --]

Hi Deepak,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.13 next-20210708]
[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/Deepak-Kumar-Singh/smem-partition-remap-and-bound-check-changes/20210709-010025
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e9f1cbc0c4114880090c7a578117d3b9cf184ad4
config: x86_64-randconfig-s021-20210707 (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/04fbf96d72efa72996d7e78dcb648caa88a84069
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Deepak-Kumar-Singh/smem-partition-remap-and-bound-check-changes/20210709-010025
        git checkout 04fbf96d72efa72996d7e78dcb648caa88a84069
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/soc/qcom/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
   drivers/soc/qcom/smem.c:371:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:371:14: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:371:14: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:429:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:429:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:429:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:516:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:516:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:516:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:536:50: sparse: sparse: incorrect type in return expression (different address spaces) @@     expected void * @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:536:50: sparse:     expected void *
   drivers/soc/qcom/smem.c:536:50: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:554:14: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:554:14: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:554:14: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:700:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:700:22: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:700:22: sparse:     got void [noderef] __iomem *virt_base
>> drivers/soc/qcom/smem.c:704:27: sparse: sparse: cast to restricted __le32
   drivers/soc/qcom/smem.c:708:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *phdr @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:708:22: sparse:     expected struct smem_partition_header *phdr
   drivers/soc/qcom/smem.c:708:22: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:712:27: sparse: sparse: cast to restricted __le32
   drivers/soc/qcom/smem.c:715:24: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:715:24: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:715:24: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:728:30: sparse: sparse: incompatible types in comparison expression (different address spaces):
   drivers/soc/qcom/smem.c:728:30: sparse:    void *
   drivers/soc/qcom/smem.c:728:30: sparse:    void [noderef] __iomem *
   drivers/soc/qcom/smem.c:749:36: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:758:28: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:767:36: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/soc/qcom/smem.c:782:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:782:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:782:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:815:57: sparse: sparse: restricted __le32 degrades to integer
   drivers/soc/qcom/smem.c:836:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_partition_header *header @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:836:16: sparse:     expected struct smem_partition_header *header
   drivers/soc/qcom/smem.c:836:16: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:1033:22: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_ptable *ptable @@     got void [noderef] __iomem * @@
   drivers/soc/qcom/smem.c:1033:22: sparse:     expected struct smem_ptable *ptable
   drivers/soc/qcom/smem.c:1033:22: sparse:     got void [noderef] __iomem *
   drivers/soc/qcom/smem.c:1048:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:1048:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:1048:16: sparse:     got void [noderef] __iomem *virt_base
   drivers/soc/qcom/smem.c:1049:14: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] size @@     got restricted __le32 [usertype] available @@
   drivers/soc/qcom/smem.c:1049:14: sparse:     expected unsigned int [usertype] size
   drivers/soc/qcom/smem.c:1049:14: sparse:     got restricted __le32 [usertype] available
   drivers/soc/qcom/smem.c:1090:16: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct smem_header *header @@     got void [noderef] __iomem *virt_base @@
   drivers/soc/qcom/smem.c:1090:16: sparse:     expected struct smem_header *header
   drivers/soc/qcom/smem.c:1090:16: sparse:     got void [noderef] __iomem *virt_base

vim +704 drivers/soc/qcom/smem.c

   503	
   504	static void *qcom_smem_get_global(struct qcom_smem *smem,
   505					  unsigned item,
   506					  size_t *size)
   507	{
   508		struct smem_header *header;
   509		struct smem_region *region;
   510		struct smem_global_entry *entry;
   511		u64 entry_offset;
   512		u32 e_size;
   513		u32 aux_base;
   514		unsigned i;
   515	
   516		header = smem->regions[0].virt_base;
   517		entry = &header->toc[item];
   518		if (!entry->allocated)
   519			return ERR_PTR(-ENXIO);
   520	
   521		aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
   522	
   523		for (i = 0; i < smem->num_regions; i++) {
   524			region = &smem->regions[i];
   525	
   526			if (region->aux_base == aux_base || !aux_base) {
   527				e_size = le32_to_cpu(entry->size);
   528				entry_offset = le32_to_cpu(entry->offset);
   529	
   530				if (WARN_ON(e_size + entry_offset > region->size))
   531					return ERR_PTR(-EINVAL);
   532	
   533				if (size != NULL)
   534					*size = e_size;
   535	
 > 536				return region->virt_base + entry_offset;
   537			}
   538		}
   539	
   540		return ERR_PTR(-ENOENT);
   541	}
   542	
   543	static void *qcom_smem_get_private(struct qcom_smem *smem,
   544					   struct smem_partition *part,
   545					   unsigned item,
   546					   size_t *size)
   547	{
   548		struct smem_private_entry *e, *end;
   549		struct smem_partition_header *phdr;
   550		void *item_ptr, *p_end;
   551		u32 padding_data;
   552		u32 e_size;
   553	
   554		phdr = part->virt_base;
   555		p_end = (void *)phdr + part->size;
   556	
   557		e = phdr_to_first_uncached_entry(phdr);
   558		end = phdr_to_last_uncached_entry(phdr);
   559	
   560		if (WARN_ON((void *)end > p_end))
   561			return ERR_PTR(-EINVAL);
   562	
   563		while (e < end) {
   564			if (e->canary != SMEM_PRIVATE_CANARY)
   565				goto invalid_canary;
   566	
   567			if (le16_to_cpu(e->item) == item) {
   568				if (size != NULL) {
   569					e_size = le32_to_cpu(e->size);
   570					padding_data = le16_to_cpu(e->padding_data);
   571	
   572					if (WARN_ON(e_size > part->size || padding_data > e_size))
   573						return ERR_PTR(-EINVAL);
   574	
   575					*size = e_size - padding_data;
   576				}
   577	
   578				item_ptr = uncached_entry_to_item(e);
   579				if (WARN_ON(item_ptr > p_end))
   580					return ERR_PTR(-EINVAL);
   581	
   582				return item_ptr;
   583			}
   584	
   585			e = uncached_entry_next(e);
   586		}
   587	
   588		if (WARN_ON((void *)e > p_end))
   589			return ERR_PTR(-EINVAL);
   590	
   591		/* Item was not found in the uncached list, search the cached list */
   592	
   593		e = phdr_to_first_cached_entry(phdr, part->cacheline);
   594		end = phdr_to_last_cached_entry(phdr);
   595	
   596		if (WARN_ON((void *)e < (void *)phdr || (void *)end > p_end))
   597			return ERR_PTR(-EINVAL);
   598	
   599		while (e > end) {
   600			if (e->canary != SMEM_PRIVATE_CANARY)
   601				goto invalid_canary;
   602	
   603			if (le16_to_cpu(e->item) == item) {
   604				if (size != NULL) {
   605					e_size = le32_to_cpu(e->size);
   606					padding_data = le16_to_cpu(e->padding_data);
   607	
   608					if (WARN_ON(e_size > part->size || padding_data > e_size))
   609						return ERR_PTR(-EINVAL);
   610	
   611					*size = e_size - padding_data;
   612				}
   613	
   614				item_ptr = cached_entry_to_item(e);
   615				if (WARN_ON(item_ptr < (void *)phdr))
   616					return ERR_PTR(-EINVAL);
   617	
   618				return item_ptr;
   619			}
   620	
   621			e = cached_entry_next(e, part->cacheline);
   622		}
   623	
   624		if (WARN_ON((void *)e < (void *)phdr))
   625			return ERR_PTR(-EINVAL);
   626	
   627		return ERR_PTR(-ENOENT);
   628	
   629	invalid_canary:
   630		dev_err(smem->dev, "Found invalid canary in hosts %hu:%hu partition\n",
   631				le16_to_cpu(phdr->host0), le16_to_cpu(phdr->host1));
   632	
   633		return ERR_PTR(-EINVAL);
   634	}
   635	
   636	/**
   637	 * qcom_smem_get() - resolve ptr of size of a smem item
   638	 * @host:	the remote processor, or -1
   639	 * @item:	smem item handle
   640	 * @size:	pointer to be filled out with size of the item
   641	 *
   642	 * Looks up smem item and returns pointer to it. Size of smem
   643	 * item is returned in @size.
   644	 */
   645	void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
   646	{
   647		struct smem_partition *part;
   648		unsigned long flags;
   649		int ret;
   650		void *ptr = ERR_PTR(-EPROBE_DEFER);
   651	
   652		if (!__smem)
   653			return ptr;
   654	
   655		if (WARN_ON(item >= __smem->item_count))
   656			return ERR_PTR(-EINVAL);
   657	
   658		ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
   659						  HWSPINLOCK_TIMEOUT,
   660						  &flags);
   661		if (ret)
   662			return ERR_PTR(ret);
   663	
   664		if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
   665			part = &__smem->partitions[host];
   666			ptr = qcom_smem_get_private(__smem, part, item, size);
   667		} else if (__smem->global_partition.virt_base) {
   668			part = &__smem->global_partition;
   669			ptr = qcom_smem_get_private(__smem, part, item, size);
   670		} else {
   671			ptr = qcom_smem_get_global(__smem, item, size);
   672		}
   673	
   674		hwspin_unlock_irqrestore(__smem->hwlock, &flags);
   675	
   676		return ptr;
   677	
   678	}
   679	EXPORT_SYMBOL(qcom_smem_get);
   680	
   681	/**
   682	 * qcom_smem_get_free_space() - retrieve amount of free space in a partition
   683	 * @host:	the remote processor identifying a partition, or -1
   684	 *
   685	 * To be used by smem clients as a quick way to determine if any new
   686	 * allocations has been made.
   687	 */
   688	int qcom_smem_get_free_space(unsigned host)
   689	{
   690		struct smem_partition *part;
   691		struct smem_partition_header *phdr;
   692		struct smem_header *header;
   693		unsigned ret;
   694	
   695		if (!__smem)
   696			return -EPROBE_DEFER;
   697	
   698		if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
   699			part = &__smem->partitions[host];
   700			phdr = part->virt_base;
   701			ret = le32_to_cpu(phdr->offset_free_cached) -
   702			      le32_to_cpu(phdr->offset_free_uncached);
   703	
 > 704			if (ret > le32_to_cpu(part->size))
   705				return -EINVAL;
   706		} else if (__smem->global_partition.virt_base) {
   707			part = &__smem->global_partition;
   708			phdr = part->virt_base;
   709			ret = le32_to_cpu(phdr->offset_free_cached) -
   710			      le32_to_cpu(phdr->offset_free_uncached);
   711	
   712			if (ret > le32_to_cpu(part->size))
   713				return -EINVAL;
   714		} else {
   715			header = __smem->regions[0].virt_base;
   716			ret = le32_to_cpu(header->available);
   717	
   718			if (ret > __smem->regions[0].size)
   719				return -EINVAL;
   720		}
   721	
   722		return ret;
   723	}
   724	EXPORT_SYMBOL(qcom_smem_get_free_space);
   725	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38793 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-09  0:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-08 16:58 [PATCH V2 0/2] smem partition remap and bound check changes Deepak Kumar Singh
2021-07-08 16:58 ` [PATCH V2 1/2] soc: qcom: smem: map only partitions used by local HOST Deepak Kumar Singh
2021-07-08 23:17   ` kernel test robot
2021-07-08 23:17     ` kernel test robot
2021-07-08 16:58 ` [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures Deepak Kumar Singh
2021-07-09  0:12   ` kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.