mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-08 05:43:28 -04:00
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 <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
4c7ccfcd09
commit
2d65ed7692
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2019-2020 Linaro Ltd.
|
||||
* Copyright (C) 2019-2021 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
@@ -244,11 +244,15 @@ static bool ipa_cmd_register_write_offset_valid(struct ipa *ipa,
|
||||
if (ipa->version != IPA_VERSION_3_5_1)
|
||||
bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK);
|
||||
BUILD_BUG_ON(bit_count > 32);
|
||||
offset_max = ~0 >> (32 - bit_count);
|
||||
offset_max = ~0U >> (32 - bit_count);
|
||||
|
||||
/* Make sure the offset can be represented by the field(s)
|
||||
* that holds it. Also make sure the offset is not outside
|
||||
* the overall IPA memory range.
|
||||
*/
|
||||
if (offset > offset_max || ipa->mem_offset > offset_max - offset) {
|
||||
dev_err(dev, "%s offset too large 0x%04x + 0x%04x > 0x%04x)\n",
|
||||
ipa->mem_offset + offset, offset_max);
|
||||
name, ipa->mem_offset, offset, offset_max);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -261,12 +265,24 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa)
|
||||
const char *name;
|
||||
u32 offset;
|
||||
|
||||
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
|
||||
name = "filter/route hash flush";
|
||||
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
|
||||
return false;
|
||||
/* If hashed tables are supported, ensure the hash flush register
|
||||
* offset will fit in a register write IPA immediate command.
|
||||
*/
|
||||
if (ipa->version != IPA_VERSION_4_2) {
|
||||
offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version);
|
||||
name = "filter/route hash flush";
|
||||
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT);
|
||||
/* Each endpoint can have a status endpoint associated with it,
|
||||
* and this is recorded in an endpoint register. If the modem
|
||||
* crashes, we reset the status endpoint for all modem endpoints
|
||||
* using a register write IPA immediate command. Make sure the
|
||||
* worst case (highest endpoint number) offset of that endpoint
|
||||
* fits in the register write command field(s) that must hold it.
|
||||
*/
|
||||
offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT - 1);
|
||||
name = "maximal endpoint status";
|
||||
if (!ipa_cmd_register_write_offset_valid(ipa, name, offset))
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user