From: Alex Elder <elder@xxxxxxxxxx> [ Upstream commit cd1150098f2cc7bd05740c105488c293f6761f5a ] It's possible that the length passed to ipa_header_size_encoded() is larger than what can be represented by the HDR_LEN field alone (starting with IPA v4.5). If we attempted that, u32_encode_bits() would trigger a build-time error. Avoid this problem by masking off high-order bits of the value encoded as the lower portion of the header length. The same sort of problem exists in ipa_metadata_offset_encoded(), so implement the same fix there. Signed-off-by: Alex Elder <elder@xxxxxxxxxx> Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- drivers/net/ipa/ipa_reg.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h index e6b0827a244e..732e691e9aa6 100644 --- a/drivers/net/ipa/ipa_reg.h +++ b/drivers/net/ipa/ipa_reg.h @@ -408,15 +408,18 @@ enum ipa_cs_offload_en { static inline u32 ipa_header_size_encoded(enum ipa_version version, u32 header_size) { + u32 size = header_size & field_mask(HDR_LEN_FMASK); u32 val; - val = u32_encode_bits(header_size, HDR_LEN_FMASK); - if (version < IPA_VERSION_4_5) + val = u32_encode_bits(size, HDR_LEN_FMASK); + if (version < IPA_VERSION_4_5) { + /* ipa_assert(header_size == size); */ return val; + } /* IPA v4.5 adds a few more most-significant bits */ - header_size >>= hweight32(HDR_LEN_FMASK); - val |= u32_encode_bits(header_size, HDR_LEN_MSB_FMASK); + size = header_size >> hweight32(HDR_LEN_FMASK); + val |= u32_encode_bits(size, HDR_LEN_MSB_FMASK); return val; } @@ -425,15 +428,18 @@ static inline u32 ipa_header_size_encoded(enum ipa_version version, static inline u32 ipa_metadata_offset_encoded(enum ipa_version version, u32 offset) { + u32 off = offset & field_mask(HDR_OFST_METADATA_FMASK); u32 val; - val = u32_encode_bits(offset, HDR_OFST_METADATA_FMASK); - if (version < IPA_VERSION_4_5) + val = u32_encode_bits(off, HDR_OFST_METADATA_FMASK); + if (version < IPA_VERSION_4_5) { + /* ipa_assert(offset == off); */ return val; + } /* IPA v4.5 adds a few more most-significant bits */ - offset >>= hweight32(HDR_OFST_METADATA_FMASK); - val |= u32_encode_bits(offset, HDR_OFST_METADATA_MSB_FMASK); + off = offset >> hweight32(HDR_OFST_METADATA_FMASK); + val |= u32_encode_bits(off, HDR_OFST_METADATA_MSB_FMASK); return val; } -- 2.30.1