Skip to content

Commit 2d65ed7

Browse files
Alex Elderdavem330
authored andcommitted
net: ipa: fix register write command validation
In ipa_cmd_register_write_valid() we verify that values we will supply to a REGISTER_WRITE IPA immediate command will fit in the fields that need to hold them. This patch fixes some issues in that function and ipa_cmd_register_write_offset_valid(). The dev_err() call in ipa_cmd_register_write_offset_valid() has some printf format errors: - The name of the register (corresponding to the string format specifier) was not supplied. - The IPA base offset and offset need to be supplied separately to match the other format specifiers. Also make the ~0 constant used there to compute the maximum supported offset value explicitly unsigned. There are two other issues in ipa_cmd_register_write_valid(): - There's no need to check the hash flush register for platforms (like IPA v4.2) that do not support hashed tables - The highest possible endpoint number, whose status register offset is computed, is COUNT - 1, not COUNT. Fix these problems, and add some additional commentary. Signed-off-by: Alex Elder <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4c7ccfc commit 2d65ed7

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

drivers/net/ipa/ipa_cmd.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4-
* Copyright (C) 2019-2020 Linaro Ltd.
4+
* Copyright (C) 2019-2021 Linaro Ltd.
55
*/
66

77
#include <linux/types.h>
@@ -244,11 +244,15 @@ static bool ipa_cmd_register_write_offset_valid(struct ipa *ipa,
244244
if (ipa->version != IPA_VERSION_3_5_1)
245245
bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK);
246246
BUILD_BUG_ON(bit_count > 32);
247-
offset_max = ~0 >> (32 - bit_count);
247+
offset_max = ~0U >> (32 - bit_count);
248248

249+
/* Make sure the offset can be represented by the field(s)
250+
* that holds it. Also make sure the offset is not outside
251+
* the overall IPA memory range.
252+
*/
249253
if (offset > offset_max || ipa->mem_offset > offset_max - offset) {
250254
dev_err(dev, "%s offset too large 0x%04x + 0x%04x > 0x%04x)\n",
251-
ipa->mem_offset + offset, offset_max);
255+
name, ipa->mem_offset, offset, offset_max);
252256
return false;
253257
}
254258

@@ -261,12 +265,24 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
261265
const char *name;
262266
u32 offset;
263267

264-
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
265-
name = "filter/route hash flush";
266-
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
267-
return false;
268+
/* If hashed tables are supported, ensure the hash flush register
269+
* offset will fit in a register write IPA immediate command.
270+
*/
271+
if (ipa->version != IPA_VERSION_4_2) {
272+
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
273+
name = "filter/route hash flush";
274+
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
275+
return false;
276+
}
268277

269-
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT);
278+
/* Each endpoint can have a status endpoint associated with it,
279+
* and this is recorded in an endpoint register. If the modem
280+
* crashes, we reset the status endpoint for all modem endpoints
281+
* using a register write IPA immediate command. Make sure the
282+
* worst case (highest endpoint number) offset of that endpoint
283+
* fits in the register write command field(s) that must hold it.
284+
*/
285+
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT - 1);
270286
name = "maximal endpoint status";
271287
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
272288
return false;

0 commit comments

Comments
 (0)