From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CE021CEAC2; Tue, 27 May 2025 17:17:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748366261; cv=none; b=L9CpCPbwACNdZQlqFVx+8zHh2arE+stUx3Koj5NCTHLvWRKII8f9YFQLkOtuZB1uA1SbEcgNtVZqTGTgnXPQNfb6OutL+4rEPLy08X0ZOQ+PcPIjZtTIlH6e2orwpKfRdWdXek85o1xEdDpWN/N9rHz7dQZmQG3LJh4mgNK4cn4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1748366261; c=relaxed/simple; bh=plXl5L3qUQwfTbwJ/hSaN4SW+YK0NA9Nnj7WSKpcFYU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ri1Cz1O8DUqJBW18+w6+nEXKxrrMPdjpvRMzpK0oKbI3cUXS6USPZspXep0AQp8oJBzzSOh0NNqq5uV3NWBrsiu8BOEGZQKnD74RVHDaKvsWNnF/r69M7mgZSFn03KZ3Zu/PDj8Yx7ot7OPex1WFaQZ84LV6FG2MNVZAPFkkCio= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=1SSG0fVQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="1SSG0fVQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C222FC4CEE9; Tue, 27 May 2025 17:17:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1748366261; bh=plXl5L3qUQwfTbwJ/hSaN4SW+YK0NA9Nnj7WSKpcFYU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1SSG0fVQRiKw3EjbWHzjXZWdzzcUTQhHwS41cr2Cj/E+Yj39cABYZTbzgACgSQ9p6 DqWmLUEtWDFSl7EtTCN56fsUiqmrBOncUzhAg1VbBHx+b0+Iez57QOZ6DbhKm4VJvJ 40nuxpIJcme515+xZYTmgsyrrIH0mPdVqBhHKBas= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Dmitry Baryshkov , Srinivas Kandagatla , Sasha Levin Subject: [PATCH 6.14 012/783] nvmem: core: fix bit offsets of more than one byte Date: Tue, 27 May 2025 18:16:49 +0200 Message-ID: <20250527162513.544032181@linuxfoundation.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250527162513.035720581@linuxfoundation.org> References: <20250527162513.035720581@linuxfoundation.org> User-Agent: quilt/0.68 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dmitry Baryshkov [ Upstream commit 7a06ef75107799675ea6e4d73b9df37e18e352a8 ] If the NVMEM specifies a stride to access data, reading particular cell might require bit offset that is bigger than one byte. Rework NVMEM core code to support bit offsets of more than 8 bits. Signed-off-by: Dmitry Baryshkov Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20250411112251.68002-9-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/nvmem/core.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index fff85bbf0ecd0..7872903c08a11 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -837,7 +837,9 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod if (addr && len == (2 * sizeof(u32))) { info.bit_offset = be32_to_cpup(addr++); info.nbits = be32_to_cpup(addr); - if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) { + if (info.bit_offset >= BITS_PER_BYTE * info.bytes || + info.nbits < 1 || + info.bit_offset + info.nbits > BITS_PER_BYTE * info.bytes) { dev_err(dev, "nvmem: invalid bits on %pOF\n", child); of_node_put(child); return -EINVAL; @@ -1630,21 +1632,29 @@ EXPORT_SYMBOL_GPL(nvmem_cell_put); static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf) { u8 *p, *b; - int i, extra, bit_offset = cell->bit_offset; + int i, extra, bytes_offset; + int bit_offset = cell->bit_offset; p = b = buf; - if (bit_offset) { + + bytes_offset = bit_offset / BITS_PER_BYTE; + b += bytes_offset; + bit_offset %= BITS_PER_BYTE; + + if (bit_offset % BITS_PER_BYTE) { /* First shift */ - *b++ >>= bit_offset; + *p = *b++ >> bit_offset; /* setup rest of the bytes if any */ for (i = 1; i < cell->bytes; i++) { /* Get bits from next byte and shift them towards msb */ - *p |= *b << (BITS_PER_BYTE - bit_offset); + *p++ |= *b << (BITS_PER_BYTE - bit_offset); - p = b; - *b++ >>= bit_offset; + *p = *b++ >> bit_offset; } + } else if (p != b) { + memmove(p, b, cell->bytes - bytes_offset); + p += cell->bytes - 1; } else { /* point to the msb */ p += cell->bytes - 1; -- 2.39.5