net: ipa: properly limit modem routing table use

[ Upstream commit cf412ec333 ]

IPA can route packets between IPA-connected entities.  The AP and
modem are currently the only such entities supported, and no routing
is required to transfer packets between them.

The number of entries in each routing table is fixed, and defined at
initialization time.  Some of these entries are designated for use
by the modem, and the rest are available for the AP to use.  The AP
sends a QMI message to the modem which describes (among other
things) information about routing table memory available for the
modem to use.

Currently the QMI initialization packet gives wrong information in
its description of routing tables.  What *should* be supplied is the
maximum index that the modem can use for the routing table memory
located at a given location.  The current code instead supplies the
total *number* of routing table entries.  Furthermore, the modem is
granted the entire table, not just the subset it's supposed to use.

This patch fixes this.  First, the ipa_mem_bounds structure is
generalized so its "end" field can be interpreted either as a final
byte offset, or a final array index.  Second, the IPv4 and IPv6
(non-hashed and hashed) table information fields in the QMI
ipa_init_modem_driver_req structure are changed to be ipa_mem_bounds
rather than ipa_mem_array structures.  Third, we set the "end" value
for each routing table to be the last index, rather than setting the
"count" to be the number of indices.  Finally, instead of allowing
the modem to use all of a routing table's memory, it is limited to
just the portion meant to be used by the modem.  In all versions of
IPA currently supported, that is IPA_ROUTE_MODEM_COUNT (8) entries.

Update a few comments for clarity.

Fixes: 530f9216a9 ("soc: qcom: ipa: AP/modem communications")
Signed-off-by: Alex Elder <elder@linaro.org>
Link: https://lore.kernel.org/r/20220913204602.1803004-1-elder@linaro.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Alex Elder 2022-09-13 15:46:02 -05:00 коммит произвёл Greg Kroah-Hartman
Родитель cbdab7d68f
Коммит c2dc533a7e
5 изменённых файлов: 32 добавлений и 26 удалений

Просмотреть файл

@ -308,12 +308,12 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
mem = ipa_mem_find(ipa, IPA_MEM_V4_ROUTE); mem = ipa_mem_find(ipa, IPA_MEM_V4_ROUTE);
req.v4_route_tbl_info_valid = 1; req.v4_route_tbl_info_valid = 1;
req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset; req.v4_route_tbl_info.start = ipa->mem_offset + mem->offset;
req.v4_route_tbl_info.count = mem->size / sizeof(__le64); req.v4_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE); mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE);
req.v6_route_tbl_info_valid = 1; req.v6_route_tbl_info_valid = 1;
req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset; req.v6_route_tbl_info.start = ipa->mem_offset + mem->offset;
req.v6_route_tbl_info.count = mem->size / sizeof(__le64); req.v6_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER); mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER);
req.v4_filter_tbl_start_valid = 1; req.v4_filter_tbl_start_valid = 1;
@ -352,7 +352,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
req.v4_hash_route_tbl_info_valid = 1; req.v4_hash_route_tbl_info_valid = 1;
req.v4_hash_route_tbl_info.start = req.v4_hash_route_tbl_info.start =
ipa->mem_offset + mem->offset; ipa->mem_offset + mem->offset;
req.v4_hash_route_tbl_info.count = mem->size / sizeof(__le64); req.v4_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
} }
mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE_HASHED); mem = ipa_mem_find(ipa, IPA_MEM_V6_ROUTE_HASHED);
@ -360,7 +360,7 @@ init_modem_driver_req(struct ipa_qmi *ipa_qmi)
req.v6_hash_route_tbl_info_valid = 1; req.v6_hash_route_tbl_info_valid = 1;
req.v6_hash_route_tbl_info.start = req.v6_hash_route_tbl_info.start =
ipa->mem_offset + mem->offset; ipa->mem_offset + mem->offset;
req.v6_hash_route_tbl_info.count = mem->size / sizeof(__le64); req.v6_hash_route_tbl_info.end = IPA_ROUTE_MODEM_COUNT - 1;
} }
mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER_HASHED); mem = ipa_mem_find(ipa, IPA_MEM_V4_FILTER_HASHED);

Просмотреть файл

@ -311,7 +311,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
.tlv_type = 0x12, .tlv_type = 0x12,
.offset = offsetof(struct ipa_init_modem_driver_req, .offset = offsetof(struct ipa_init_modem_driver_req,
v4_route_tbl_info), v4_route_tbl_info),
.ei_array = ipa_mem_array_ei, .ei_array = ipa_mem_bounds_ei,
}, },
{ {
.data_type = QMI_OPT_FLAG, .data_type = QMI_OPT_FLAG,
@ -332,7 +332,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
.tlv_type = 0x13, .tlv_type = 0x13,
.offset = offsetof(struct ipa_init_modem_driver_req, .offset = offsetof(struct ipa_init_modem_driver_req,
v6_route_tbl_info), v6_route_tbl_info),
.ei_array = ipa_mem_array_ei, .ei_array = ipa_mem_bounds_ei,
}, },
{ {
.data_type = QMI_OPT_FLAG, .data_type = QMI_OPT_FLAG,
@ -496,7 +496,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
.tlv_type = 0x1b, .tlv_type = 0x1b,
.offset = offsetof(struct ipa_init_modem_driver_req, .offset = offsetof(struct ipa_init_modem_driver_req,
v4_hash_route_tbl_info), v4_hash_route_tbl_info),
.ei_array = ipa_mem_array_ei, .ei_array = ipa_mem_bounds_ei,
}, },
{ {
.data_type = QMI_OPT_FLAG, .data_type = QMI_OPT_FLAG,
@ -517,7 +517,7 @@ struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
.tlv_type = 0x1c, .tlv_type = 0x1c,
.offset = offsetof(struct ipa_init_modem_driver_req, .offset = offsetof(struct ipa_init_modem_driver_req,
v6_hash_route_tbl_info), v6_hash_route_tbl_info),
.ei_array = ipa_mem_array_ei, .ei_array = ipa_mem_bounds_ei,
}, },
{ {
.data_type = QMI_OPT_FLAG, .data_type = QMI_OPT_FLAG,

Просмотреть файл

@ -86,9 +86,11 @@ enum ipa_platform_type {
IPA_QMI_PLATFORM_TYPE_MSM_QNX_V01 = 0x5, /* QNX MSM */ IPA_QMI_PLATFORM_TYPE_MSM_QNX_V01 = 0x5, /* QNX MSM */
}; };
/* This defines the start and end offset of a range of memory. Both /* This defines the start and end offset of a range of memory. The start
* fields are offsets relative to the start of IPA shared memory. * value is a byte offset relative to the start of IPA shared memory. The
* The end value is the last addressable byte *within* the range. * end value is the last addressable unit *within* the range. Typically
* the end value is in units of bytes, however it can also be a maximum
* array index value.
*/ */
struct ipa_mem_bounds { struct ipa_mem_bounds {
u32 start; u32 start;
@ -129,18 +131,19 @@ struct ipa_init_modem_driver_req {
u8 hdr_tbl_info_valid; u8 hdr_tbl_info_valid;
struct ipa_mem_bounds hdr_tbl_info; struct ipa_mem_bounds hdr_tbl_info;
/* Routing table information. These define the location and size of /* Routing table information. These define the location and maximum
* non-hashable IPv4 and IPv6 filter tables. The start values are * *index* (not byte) for the modem portion of non-hashable IPv4 and
* offsets relative to the start of IPA shared memory. * IPv6 routing tables. The start values are byte offsets relative
* to the start of IPA shared memory.
*/ */
u8 v4_route_tbl_info_valid; u8 v4_route_tbl_info_valid;
struct ipa_mem_array v4_route_tbl_info; struct ipa_mem_bounds v4_route_tbl_info;
u8 v6_route_tbl_info_valid; u8 v6_route_tbl_info_valid;
struct ipa_mem_array v6_route_tbl_info; struct ipa_mem_bounds v6_route_tbl_info;
/* Filter table information. These define the location of the /* Filter table information. These define the location of the
* non-hashable IPv4 and IPv6 filter tables. The start values are * non-hashable IPv4 and IPv6 filter tables. The start values are
* offsets relative to the start of IPA shared memory. * byte offsets relative to the start of IPA shared memory.
*/ */
u8 v4_filter_tbl_start_valid; u8 v4_filter_tbl_start_valid;
u32 v4_filter_tbl_start; u32 v4_filter_tbl_start;
@ -181,18 +184,20 @@ struct ipa_init_modem_driver_req {
u8 zip_tbl_info_valid; u8 zip_tbl_info_valid;
struct ipa_mem_bounds zip_tbl_info; struct ipa_mem_bounds zip_tbl_info;
/* Routing table information. These define the location and size /* Routing table information. These define the location and maximum
* of hashable IPv4 and IPv6 filter tables. The start values are * *index* (not byte) for the modem portion of hashable IPv4 and IPv6
* offsets relative to the start of IPA shared memory. * routing tables (if supported by hardware). The start values are
* byte offsets relative to the start of IPA shared memory.
*/ */
u8 v4_hash_route_tbl_info_valid; u8 v4_hash_route_tbl_info_valid;
struct ipa_mem_array v4_hash_route_tbl_info; struct ipa_mem_bounds v4_hash_route_tbl_info;
u8 v6_hash_route_tbl_info_valid; u8 v6_hash_route_tbl_info_valid;
struct ipa_mem_array v6_hash_route_tbl_info; struct ipa_mem_bounds v6_hash_route_tbl_info;
/* Filter table information. These define the location and size /* Filter table information. These define the location and size
* of hashable IPv4 and IPv6 filter tables. The start values are * of hashable IPv4 and IPv6 filter tables (if supported by hardware).
* offsets relative to the start of IPA shared memory. * The start values are byte offsets relative to the start of IPA
* shared memory.
*/ */
u8 v4_hash_filter_tbl_start_valid; u8 v4_hash_filter_tbl_start_valid;
u32 v4_hash_filter_tbl_start; u32 v4_hash_filter_tbl_start;

Просмотреть файл

@ -108,8 +108,6 @@
/* Assignment of route table entries to the modem and AP */ /* Assignment of route table entries to the modem and AP */
#define IPA_ROUTE_MODEM_MIN 0 #define IPA_ROUTE_MODEM_MIN 0
#define IPA_ROUTE_MODEM_COUNT 8
#define IPA_ROUTE_AP_MIN IPA_ROUTE_MODEM_COUNT #define IPA_ROUTE_AP_MIN IPA_ROUTE_MODEM_COUNT
#define IPA_ROUTE_AP_COUNT \ #define IPA_ROUTE_AP_COUNT \
(IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT) (IPA_ROUTE_COUNT_MAX - IPA_ROUTE_MODEM_COUNT)

Просмотреть файл

@ -13,6 +13,9 @@ struct ipa;
/* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */ /* The maximum number of filter table entries (IPv4, IPv6; hashed or not) */
#define IPA_FILTER_COUNT_MAX 14 #define IPA_FILTER_COUNT_MAX 14
/* The number of route table entries allotted to the modem */
#define IPA_ROUTE_MODEM_COUNT 8
/* The maximum number of route table entries (IPv4, IPv6; hashed or not) */ /* The maximum number of route table entries (IPv4, IPv6; hashed or not) */
#define IPA_ROUTE_COUNT_MAX 15 #define IPA_ROUTE_COUNT_MAX 15