2022-10-21 19:17:47

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 0/7] net: ipa: validation cleanup

This series gathers a set of IPA driver cleanups, mostly involving
code that ensures certain things are known to be correct *early*
(either at build or initializatin time), so they can be assumed good
during normal operation.

The first removes three constant symbols, by making a (reasonable)
assumption that a routing table consists of entries for the modem
followed by entries for the AP, with no unused entries between them.

The second removes two checks that are redundant (they verify the
sizes of two memory regions are in range, which will have been done
earlier for all regions).

The third adds some new checks to routing and filter tables that
can be done at "init time" (without requiring any access to IPA
hardware).

The fourth moves a check that routing and filter table addresses can
be encoded within certain IPA immediate commands, so it's performed
earlier; the checks can be done without touching IPA hardware. The
fifth moves some other command-related checks earlier, for the same
reason.

The sixth removes the definition ipa_table_valid(), because what it
does has become redundant. Finally, the last patch moves two more
validation calls so they're done very early in the probe process.
This will be required by some upcoming patches, which will record
the size of the routing and filter tables at this time so they're
available for subsequent initialization.

-Alex

Alex Elder (7):
net: ipa: kill two constant symbols
net: ipa: remove two memory region checks
net: ipa: validate IPA table memory earlier
net: ipa: verify table sizes fit in commands early
net: ipa: introduce ipa_cmd_init()
net: ipa: kill ipa_table_valid()
net: ipa: check table memory regions earlier

drivers/net/ipa/ipa_cmd.c | 53 ++++--------
drivers/net/ipa/ipa_cmd.h | 16 +++-
drivers/net/ipa/ipa_mem.c | 14 ++--
drivers/net/ipa/ipa_table.c | 162 +++++++++++++++++++++---------------
drivers/net/ipa/ipa_table.h | 15 ++--
5 files changed, 138 insertions(+), 122 deletions(-)

--
2.34.1


2022-10-21 19:18:11

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 1/7] net: ipa: kill two constant symbols

The entries in each IPA routing table are divided between the modem
and the AP. The modem always gets some number of entries located at
the base of the table; the AP gets all those that follow.

There's no reason to think the modem will use anything different
from the first entries in a routing table, so:
- Get rid of IPA_ROUTE_MODEM_MIN (just assume it's 0)
- Get rid of IPA_ROUTE_AP_MIN (just assume it's IPA_ROUTE_MODEM_COUNT)
And finally:
- Open-code IPA_ROUTE_AP_COUNT and remove its definition

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_table.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 510ff2dc8999a..74d7082b3c5aa 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -106,12 +106,6 @@
* ----------------------
*/

-/* Assignment of route table entries to the modem and AP */
-#define IPA_ROUTE_MODEM_MIN 0
-#define IPA_ROUTE_AP_MIN IPA_ROUTE_MODEM_COUNT
-#define IPA_ROUTE_AP_COUNT \
- (IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT)
-
/* Filter or route rules consist of a set of 32-bit values followed by a
* 32-bit all-zero rule list terminator. The "zero rule" is simply an
* all-zero rule followed by the list terminator.
@@ -342,11 +336,11 @@ static int ipa_route_reset(struct ipa *ipa, bool modem)
}

if (modem) {
- first = IPA_ROUTE_MODEM_MIN;
+ first = 0;
count = IPA_ROUTE_MODEM_COUNT;
} else {
- first = IPA_ROUTE_AP_MIN;
- count = IPA_ROUTE_AP_COUNT;
+ first = IPA_ROUTE_MODEM_COUNT;
+ count = IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT;
}

ipa_table_reset_add(trans, false, first, count, IPA_MEM_V4_ROUTE);
@@ -561,8 +555,7 @@ static void ipa_filter_config(struct ipa *ipa, bool modem)

static bool ipa_route_id_modem(u32 route_id)
{
- return route_id >= IPA_ROUTE_MODEM_MIN &&
- route_id <= IPA_ROUTE_MODEM_MIN + IPA_ROUTE_MODEM_COUNT - 1;
+ return route_id < IPA_ROUTE_MODEM_COUNT;
}

/**
--
2.34.1

2022-10-21 19:19:06

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 6/7] net: ipa: kill ipa_table_valid()

What ipa_table_valid() (and ipa_table_valid_one(), which it calls)
does is ensure that the memory regions that hold routing and filter
tables have reasonable size. Specifically, it checks that the size
of a region is sufficient (or rather, exactly the right size) to
hold the maximum number of entries supported by the driver. (There
is an additional check that's erroneous, but in practice it is never
reached.)

Recently ipa_table_mem_valid() was added, which is called by
ipa_table_init(). That function verifies that all table memory
regions are of sufficient size, and requires hashed tables to have
zero size if hashing is not supported. It only ensures the filter
table is large enough to hold the number of endpoints that support
filtering, but that is adequate.

Therefore everything that ipa_table_valid() does is redundant, so
get rid of it.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_mem.c | 4 ---
drivers/net/ipa/ipa_table.c | 50 -------------------------------------
drivers/net/ipa/ipa_table.h | 8 ------
3 files changed, 62 deletions(-)

diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index 2238dac2af07e..4022ae01a1319 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -366,10 +366,6 @@ int ipa_mem_config(struct ipa *ipa)
while (--canary_count);
}

- /* Make sure filter and route table memory regions are valid */
- if (!ipa_table_valid(ipa))
- goto err_dma_free;
-
/* Verify the microcontroller ring alignment (if defined) */
mem = ipa_mem_find(ipa, IPA_MEM_UC_EVENT_RING);
if (mem && mem->offset % 1024) {
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 9822b18d9ed39..7a60f2867de92 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -155,56 +155,6 @@ ipa_table_mem(struct ipa *ipa, bool filter, bool hashed, bool ipv6)
return ipa_mem_find(ipa, mem_id);
}

-static bool
-ipa_table_valid_one(struct ipa *ipa, enum ipa_mem_id mem_id, bool route)
-{
- const struct ipa_mem *mem = ipa_mem_find(ipa, mem_id);
- struct device *dev = &ipa->pdev->dev;
- u32 size;
-
- if (route)
- size = IPA_ROUTE_COUNT_MAX * sizeof(__le64);
- else
- size = (1 + IPA_FILTER_COUNT_MAX) * sizeof(__le64);
- /* mem->size >= size is sufficient, but we'll demand more */
- if (mem->size == size)
- return true;
-
- /* Hashed table regions can be zero size if hashing is not supported */
- if (ipa_table_hash_support(ipa) && !mem->size)
- return true;
-
- dev_err(dev, "%s table region %u size 0x%02x, expected 0x%02x\n",
- route ? "route" : "filter", mem_id, mem->size, size);
-
- return false;
-}
-
-/* Verify the filter and route table memory regions are the expected size */
-bool ipa_table_valid(struct ipa *ipa)
-{
- bool valid;
-
- valid = ipa_table_valid_one(ipa, IPA_MEM_V4_FILTER, false);
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_FILTER, false);
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V4_ROUTE, true);
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_ROUTE, true);
-
- if (!ipa_table_hash_support(ipa))
- return valid;
-
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V4_FILTER_HASHED,
- false);
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_FILTER_HASHED,
- false);
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V4_ROUTE_HASHED,
- true);
- valid = valid && ipa_table_valid_one(ipa, IPA_MEM_V6_ROUTE_HASHED,
- true);
-
- return valid;
-}
-
bool ipa_filter_map_valid(struct ipa *ipa, u32 filter_map)
{
struct device *dev = &ipa->pdev->dev;
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 395189f75d784..73ca8369c6352 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -19,14 +19,6 @@ struct ipa;
/* The maximum number of route table entries (IPv4, IPv6; hashed or not) */
#define IPA_ROUTE_COUNT_MAX 15

-/**
- * ipa_table_valid() - Validate route and filter table memory regions
- * @ipa: IPA pointer
- *
- * Return: true if all regions are valid, false otherwise
- */
-bool ipa_table_valid(struct ipa *ipa);
-
/**
* ipa_filter_map_valid() - Validate a filter table endpoint bitmap
* @ipa: IPA pointer
--
2.34.1

2022-10-21 19:33:06

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 3/7] net: ipa: validate IPA table memory earlier

Add checks in ipa_table_init() to ensure the memory regions defined
for IPA filter and routing tables are valid.

For routing tables, the checks ensure:
- The non-hashed IPv4 and IPv6 routing tables are defined
- The non-hashed IPv4 and IPv6 routing tables are the same size
- The number entries in the non-hashed IPv4 routing table is enough
to hold the number entries available to the modem, plus at least
one usable by the AP.

For filter tables, the checks ensure:
- The non-hashed IPv4 and IPv6 filter tables are defined
- The non-hashed IPv4 and IPv6 filter tables are the same size
- The number entries in the non-hashed IPv4 filter table is enough
to hold the endpoint bitmap, plus an entry for each defined
endpoint that supports filtering.

In addition, for both routing and filter tables:
- If hashing isn't supported (IPA v4.2), hashed tables are zero size
- If hashing *is* supported, all hashed tables are the same size as
their non-hashed counterparts.

When validating the size of routing tables, require the AP to have
at least one entry (in addition to those used by the modem).

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_table.c | 98 +++++++++++++++++++++++++++++++++++--
1 file changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 74d7082b3c5aa..222362a7a2a8c 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -134,9 +134,25 @@ static void ipa_table_validate_build(void)
BUILD_BUG_ON(IPA_ROUTE_COUNT_MAX > 32);
/* The modem must be allotted at least one route table entry */
BUILD_BUG_ON(!IPA_ROUTE_MODEM_COUNT);
- /* But it can't have more than what is available */
- BUILD_BUG_ON(IPA_ROUTE_MODEM_COUNT > IPA_ROUTE_COUNT_MAX);
+ /* AP must too, but we can't use more than what is available */
+ BUILD_BUG_ON(IPA_ROUTE_MODEM_COUNT >= IPA_ROUTE_COUNT_MAX);
+}

+static const struct ipa_mem *
+ipa_table_mem(struct ipa *ipa, bool filter, bool hashed, bool ipv6)
+{
+ enum ipa_mem_id mem_id;
+
+ mem_id = filter ? hashed ? ipv6 ? IPA_MEM_V6_FILTER_HASHED
+ : IPA_MEM_V4_FILTER_HASHED
+ : ipv6 ? IPA_MEM_V6_FILTER
+ : IPA_MEM_V4_FILTER
+ : hashed ? ipv6 ? IPA_MEM_V6_ROUTE_HASHED
+ : IPA_MEM_V4_ROUTE_HASHED
+ : ipv6 ? IPA_MEM_V6_ROUTE
+ : IPA_MEM_V4_ROUTE;
+
+ return ipa_mem_find(ipa, mem_id);
}

static bool
@@ -604,8 +620,77 @@ void ipa_table_config(struct ipa *ipa)
ipa_route_config(ipa, true);
}

-/*
- * Initialize a coherent DMA allocation containing initialized filter and
+/* Zero modem_route_count means filter table memory check */
+static bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
+{
+ bool hash_support = ipa_table_hash_support(ipa);
+ bool filter = !modem_route_count;
+ const struct ipa_mem *mem_hashed;
+ const struct ipa_mem *mem_ipv4;
+ const struct ipa_mem *mem_ipv6;
+ u32 count;
+
+ /* IPv4 and IPv6 non-hashed tables are expected to be defined and
+ * have the same size. Both must have at least two entries (and
+ * would normally have more than that).
+ */
+ mem_ipv4 = ipa_table_mem(ipa, filter, false, false);
+ if (!mem_ipv4)
+ return false;
+
+ mem_ipv6 = ipa_table_mem(ipa, filter, false, true);
+ if (!mem_ipv6)
+ return false;
+
+ if (mem_ipv4->size != mem_ipv6->size)
+ return false;
+
+ /* Make sure the regions are big enough */
+ count = mem_ipv4->size / sizeof(__le64);
+ if (count < 2)
+ return false;
+ if (filter) {
+ /* Filter tables must able to hold the endpoint bitmap plus
+ * an entry for each endpoint that supports filtering
+ */
+ if (count < 1 + hweight32(ipa->filter_map))
+ return false;
+ } else {
+ /* Routing tables must be able to hold all modem entries,
+ * plus at least one entry for the AP.
+ */
+ if (count < modem_route_count + 1)
+ return false;
+ }
+
+ /* If hashing is supported, hashed tables are expected to be defined,
+ * and have the same size as non-hashed tables. If hashing is not
+ * supported, hashed tables are expected to have zero size (or not
+ * be defined).
+ */
+ mem_hashed = ipa_table_mem(ipa, filter, true, false);
+ if (hash_support) {
+ if (!mem_hashed || mem_hashed->size != mem_ipv4->size)
+ return false;
+ } else {
+ if (mem_hashed && mem_hashed->size)
+ return false;
+ }
+
+ /* Same check for IPv6 tables */
+ mem_hashed = ipa_table_mem(ipa, filter, true, true);
+ if (hash_support) {
+ if (!mem_hashed || mem_hashed->size != mem_ipv6->size)
+ return false;
+ } else {
+ if (mem_hashed && mem_hashed->size)
+ return false;
+ }
+
+ return true;
+}
+
+/* Initialize a coherent DMA allocation containing initialized filter and
* route table data. This is used when initializing or resetting the IPA
* filter or route table.
*
@@ -653,6 +738,11 @@ int ipa_table_init(struct ipa *ipa)

ipa_table_validate_build();

+ if (!ipa_table_mem_valid(ipa, 0))
+ return -EINVAL;
+ if (!ipa_table_mem_valid(ipa, IPA_ROUTE_MODEM_COUNT))
+ return -EINVAL;
+
/* The IPA hardware requires route and filter table rules to be
* aligned on a 128-byte boundary. We put the "zero rule" at the
* base of the table area allocated here. The DMA address returned
--
2.34.1

2022-10-21 19:35:58

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 4/7] net: ipa: verify table sizes fit in commands early

We currently verify the table size and offset fit in the immediate
command fields that must encode them in ipa_table_valid_one(). We
can now make this check earlier, in ipa_table_mem_valid().

The non-hashed IPv4 filter and route tables will always exist, and
their sizes will match the IPv6 tables, as well as the hashed tables
(if supported). So it's sufficient to verify the offset and size of
the IPv4 non-hashed tables fit into these fields.

Rename the function ipa_cmd_table_init_valid(), to reinforce that
it is the TABLE_INIT immediate command fields we're checking.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 3 ++-
drivers/net/ipa/ipa_cmd.h | 6 +++---
drivers/net/ipa/ipa_table.c | 8 ++++----
3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index e46e8f80b1743..abee6cc018a27 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -171,7 +171,8 @@ static void ipa_cmd_validate_build(void)
}

/* Validate a memory region holding a table */
-bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, bool route)
+bool ipa_cmd_table_init_valid(struct ipa *ipa, const struct ipa_mem *mem,
+ bool route)
{
u32 offset_max = field_max(IP_FLTRT_FLAGS_NHASH_ADDR_FMASK);
u32 size_max = field_max(IP_FLTRT_FLAGS_NHASH_SIZE_FMASK);
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index 8e4243c1f0bbe..d03cc619e2c31 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -47,15 +47,15 @@ enum ipa_cmd_opcode {
};

/**
- * ipa_cmd_table_valid() - Validate a memory region holding a table
+ * ipa_cmd_table_init_valid() - Validate a memory region holding a table
* @ipa: - IPA pointer
* @mem: - IPA memory region descriptor
* @route: - Whether the region holds a route or filter table
*
* Return: true if region is valid, false otherwise
*/
-bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem,
- bool route);
+bool ipa_cmd_table_init_valid(struct ipa *ipa, const struct ipa_mem *mem,
+ bool route);

/**
* ipa_cmd_data_valid() - Validate command-realted configuration is valid
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 222362a7a2a8c..9822b18d9ed39 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -166,10 +166,6 @@ ipa_table_valid_one(struct ipa *ipa, enum ipa_mem_id mem_id, bool route)
size = IPA_ROUTE_COUNT_MAX * sizeof(__le64);
else
size = (1 + IPA_FILTER_COUNT_MAX) * sizeof(__le64);
-
- if (!ipa_cmd_table_valid(ipa, mem, route))
- return false;
-
/* mem->size >= size is sufficient, but we'll demand more */
if (mem->size == size)
return true;
@@ -645,6 +641,10 @@ static bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
if (mem_ipv4->size != mem_ipv6->size)
return false;

+ /* Table offset and size must fit in TABLE_INIT command fields */
+ if (!ipa_cmd_table_init_valid(ipa, mem_ipv4, !filter))
+ return false;
+
/* Make sure the regions are big enough */
count = mem_ipv4->size / sizeof(__le64);
if (count < 2)
--
2.34.1

2022-10-21 19:37:40

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 2/7] net: ipa: remove two memory region checks

There's no need to ensure table memory regions fit within the
IPA-local memory range. And there's no need to ensure the modem
header memory region is in range either. These are verified for all
memory regions in ipa_mem_size_valid(), once we have settled on the
size of IPA memory.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 19 -------------------
1 file changed, 19 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index 26c3db9f52b18..e46e8f80b1743 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -197,16 +197,6 @@ bool ipa_cmd_table_valid(struct ipa *ipa, const struct ipa_mem *mem, bool route)
return false;
}

- /* Entire memory range must fit within IPA-local memory */
- if (mem->offset > ipa->mem_size ||
- mem->size > ipa->mem_size - mem->offset) {
- dev_err(dev, "%s table region out of range\n", table);
- dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n",
- mem->offset, mem->size, ipa->mem_size);
-
- return false;
- }
-
return true;
}

@@ -257,15 +247,6 @@ static bool ipa_cmd_header_valid(struct ipa *ipa)
return false;
}

- /* Make sure the entire combined area fits in IPA memory */
- if (size > ipa->mem_size || offset > ipa->mem_size - size) {
- dev_err(dev, "header table region out of range\n");
- dev_err(dev, " (0x%04x + 0x%04x > 0x%04x)\n",
- offset, size, ipa->mem_size);
-
- return false;
- }
-
return true;
}

--
2.34.1

2022-10-21 19:38:15

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 7/7] net: ipa: check table memory regions earlier

Verify that the sizes of the routing and filter table memory regions
are valid as part of memory initialization, rather than waiting for
table initialization. The main reason to do this is that upcoming
patches use these memory region sizes to determine the number of
entries in these tables, and we'll want to know these sizes are good
sooner.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_mem.c | 6 ++++++
drivers/net/ipa/ipa_table.c | 7 +------
drivers/net/ipa/ipa_table.h | 7 +++++++
3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index 4022ae01a1319..a3d2317452ac6 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -617,6 +617,12 @@ int ipa_mem_init(struct ipa *ipa, const struct ipa_mem_data *mem_data)
ipa->mem_count = mem_data->local_count;
ipa->mem = mem_data->local;

+ /* Check the route and filter table memory regions */
+ if (!ipa_table_mem_valid(ipa, 0))
+ return -EINVAL;
+ if (!ipa_table_mem_valid(ipa, IPA_ROUTE_MODEM_COUNT))
+ return -EINVAL;
+
ret = dma_set_mask_and_coherent(&ipa->pdev->dev, DMA_BIT_MASK(64));
if (ret) {
dev_err(dev, "error %d setting DMA mask\n", ret);
diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c
index 7a60f2867de92..58a1a9da3133e 100644
--- a/drivers/net/ipa/ipa_table.c
+++ b/drivers/net/ipa/ipa_table.c
@@ -567,7 +567,7 @@ void ipa_table_config(struct ipa *ipa)
}

/* Zero modem_route_count means filter table memory check */
-static bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
+bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count)
{
bool hash_support = ipa_table_hash_support(ipa);
bool filter = !modem_route_count;
@@ -688,11 +688,6 @@ int ipa_table_init(struct ipa *ipa)

ipa_table_validate_build();

- if (!ipa_table_mem_valid(ipa, 0))
- return -EINVAL;
- if (!ipa_table_mem_valid(ipa, IPA_ROUTE_MODEM_COUNT))
- return -EINVAL;
-
/* The IPA hardware requires route and filter table rules to be
* aligned on a 128-byte boundary. We put the "zero rule" at the
* base of the table area allocated here. The DMA address returned
diff --git a/drivers/net/ipa/ipa_table.h b/drivers/net/ipa/ipa_table.h
index 73ca8369c6352..65d96debd3917 100644
--- a/drivers/net/ipa/ipa_table.h
+++ b/drivers/net/ipa/ipa_table.h
@@ -78,4 +78,11 @@ int ipa_table_init(struct ipa *ipa);
*/
void ipa_table_exit(struct ipa *ipa);

+/**
+ * ipa_table_mem_valid() - Validate sizes of table memory regions
+ * @ipa: IPA pointer
+ * @modem_route_count: Number of modem route table entries
+ */
+bool ipa_table_mem_valid(struct ipa *ipa, bool modem_route_count);
+
#endif /* _IPA_TABLE_H_ */
--
2.34.1

2022-10-21 19:57:24

by Alex Elder

[permalink] [raw]
Subject: [PATCH net-next 5/7] net: ipa: introduce ipa_cmd_init()

Currently, ipa_cmd_data_valid() is called by ipa_mem_config().
Nothing it does requires access to hardware though, so it can be
done during the init phase of IPA driver startup.

Create a new function ipa_cmd_init(), whose purpose is to do early
initialization related to IPA immediate commands. It will call the
build-time validation function, then will make the two calls made
previously by ipa_cmd_data_valid(). This make ipa_cmd_data_valid()
unnecessary, so get rid of it.

Rename ipa_cmd_header_valid() to be ipa_cmd_header_init_local_valid(),
so its name is clearer about which IPA immediate command it is
associated with.

Signed-off-by: Alex Elder <[email protected]>
---
drivers/net/ipa/ipa_cmd.c | 31 +++++++++++++++----------------
drivers/net/ipa/ipa_cmd.h | 10 ++++++++++
drivers/net/ipa/ipa_mem.c | 4 ----
3 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c
index abee6cc018a27..de2cd86aa9e28 100644
--- a/drivers/net/ipa/ipa_cmd.c
+++ b/drivers/net/ipa/ipa_cmd.c
@@ -202,7 +202,7 @@ bool ipa_cmd_table_init_valid(struct ipa *ipa, const struct ipa_mem *mem,
}

/* Validate the memory region that holds headers */
-static bool ipa_cmd_header_valid(struct ipa *ipa)
+static bool ipa_cmd_header_init_local_valid(struct ipa *ipa)
{
struct device *dev = &ipa->pdev->dev;
const struct ipa_mem *mem;
@@ -318,26 +318,11 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
return true;
}

-bool ipa_cmd_data_valid(struct ipa *ipa)
-{
- if (!ipa_cmd_header_valid(ipa))
- return false;
-
- if (!ipa_cmd_register_write_valid(ipa))
- return false;
-
- return true;
-}
-
-
int ipa_cmd_pool_init(struct gsi_channel *channel, u32 tre_max)
{
struct gsi_trans_info *trans_info = &channel->trans_info;
struct device *dev = channel->gsi->dev;

- /* This is as good a place as any to validate build constants */
- ipa_cmd_validate_build();
-
/* Command payloads are allocated one at a time, but a single
* transaction can require up to the maximum supported by the
* channel; treat them as if they were allocated all at once.
@@ -637,3 +622,17 @@ struct gsi_trans *ipa_cmd_trans_alloc(struct ipa *ipa, u32 tre_count)
return gsi_channel_trans_alloc(&ipa->gsi, endpoint->channel_id,
tre_count, DMA_NONE);
}
+
+/* Init function for immediate commands; there is no ipa_cmd_exit() */
+int ipa_cmd_init(struct ipa *ipa)
+{
+ ipa_cmd_validate_build();
+
+ if (!ipa_cmd_header_init_local_valid(ipa))
+ return -EINVAL;
+
+ if (!ipa_cmd_register_write_valid(ipa))
+ return -EINVAL;
+
+ return 0;
+}
diff --git a/drivers/net/ipa/ipa_cmd.h b/drivers/net/ipa/ipa_cmd.h
index d03cc619e2c31..e2cf1c2b0ef24 100644
--- a/drivers/net/ipa/ipa_cmd.h
+++ b/drivers/net/ipa/ipa_cmd.h
@@ -162,4 +162,14 @@ void ipa_cmd_pipeline_clear_wait(struct ipa *ipa);
*/
struct gsi_trans *ipa_cmd_trans_alloc(struct ipa *ipa, u32 tre_count);

+/**
+ * ipa_cmd_init() - Initialize IPA immediate commands
+ * @ipa: - IPA pointer
+ *
+ * Return: 0 if successful, or a negative error code
+ *
+ * There is no need for a matching ipa_cmd_exit() function.
+ */
+int ipa_cmd_init(struct ipa *ipa);
+
#endif /* _IPA_CMD_H_ */
diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c
index f84c6830495a4..2238dac2af07e 100644
--- a/drivers/net/ipa/ipa_mem.c
+++ b/drivers/net/ipa/ipa_mem.c
@@ -370,10 +370,6 @@ int ipa_mem_config(struct ipa *ipa)
if (!ipa_table_valid(ipa))
goto err_dma_free;

- /* Validate memory-related properties relevant to immediate commands */
- if (!ipa_cmd_data_valid(ipa))
- goto err_dma_free;
-
/* Verify the microcontroller ring alignment (if defined) */
mem = ipa_mem_find(ipa, IPA_MEM_UC_EVENT_RING);
if (mem && mem->offset % 1024) {
--
2.34.1

2022-10-25 09:49:28

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH net-next 0/7] net: ipa: validation cleanup

Hello:

This series was applied to netdev/net-next.git (master)
by Paolo Abeni <[email protected]>:

On Fri, 21 Oct 2022 14:13:33 -0500 you wrote:
> This series gathers a set of IPA driver cleanups, mostly involving
> code that ensures certain things are known to be correct *early*
> (either at build or initializatin time), so they can be assumed good
> during normal operation.
>
> The first removes three constant symbols, by making a (reasonable)
> assumption that a routing table consists of entries for the modem
> followed by entries for the AP, with no unused entries between them.
>
> [...]

Here is the summary with links:
- [net-next,1/7] net: ipa: kill two constant symbols
https://git.kernel.org/netdev/net-next/c/fb4014ac76b8
- [net-next,2/7] net: ipa: remove two memory region checks
https://git.kernel.org/netdev/net-next/c/2554322b3199
- [net-next,3/7] net: ipa: validate IPA table memory earlier
https://git.kernel.org/netdev/net-next/c/cf13919654d5
- [net-next,4/7] net: ipa: verify table sizes fit in commands early
https://git.kernel.org/netdev/net-next/c/5444b0ea9915
- [net-next,5/7] net: ipa: introduce ipa_cmd_init()
https://git.kernel.org/netdev/net-next/c/7fd10a2aca6a
- [net-next,6/7] net: ipa: kill ipa_table_valid()
https://git.kernel.org/netdev/net-next/c/39ad815244ac
- [net-next,7/7] net: ipa: check table memory regions earlier
https://git.kernel.org/netdev/net-next/c/73da9cac517c

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html