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 C1DCC28D2E8; Tue, 29 Apr 2025 23:51:33 +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=1745970693; cv=none; b=lWy4klo2ls5Slb+BcGLIcnWa9dWbViDZDdWOKEzt92TH/oHAPgYmJjq2TRer3m52/q8eTQ7bjkTk4veP7OgdUFZarWq0ngfyyt9dzj6i3nMKFXNM4f+Kd39rrTIp/OxaPikpa563RZ/6Rq5ACJh6ffChY1dczO13P6lvB0FSAjk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745970693; c=relaxed/simple; bh=H0IXE6nWDfmABu1NSpM4IZc2MKcVBAZkqQ09EDHfyEI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UWTliIZhBghpy8uiOTLmyuZkOwWLPsN+JLiglYwK7tMW8qqRvj/+PF0luq8jBd1DRzMp3Tm28dqIyDo4toAD0Gx71DmlaviOlZHp9wc3ug3/YAhWTHwxPZvLhU7tHaFdoVtE0sLfeag888n2LSWZ7nHWlAOwwHG/YzS96DGv0mo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=u/ar4ZmB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="u/ar4ZmB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C986BC4CEEE; Tue, 29 Apr 2025 23:51:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1745970693; bh=H0IXE6nWDfmABu1NSpM4IZc2MKcVBAZkqQ09EDHfyEI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u/ar4ZmB+qXzGoA46r4lBgNulIzmaLzwZ7C8UUHomQrwDDYzyJhIZ6QTFNCBwqO4D Zv4IboKz3tWa8EKtCTTXBW7gwfSw7OpztyxK+b266wvpzkAwenPcgs49TWwE0WU42B zaPaCgfS7qHhT/kXl/dt+ZLYhzBp8+rjEzwhElpHxa955Py2hmd4SX+xdAWecFWUSa rXaEsyc38kJvSI1l1QuMI650tzjgDTkCjEggubB2fQmKtG4OHhIz0QJ/4La16982Rv 0Gi0S/w5eHANCvfR8GSaOWz4nRC828Eb8Ul+wStdYIklKS5Wd7auUh861WNlZVpHbc Mt2U7aXfA4wtA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Dmitry Baryshkov , Srinivas Kandagatla , Greg Kroah-Hartman , Sasha Levin , srini@kernel.org Subject: [PATCH AUTOSEL 6.12 05/37] nvmem: core: fix bit offsets of more than one byte Date: Tue, 29 Apr 2025 19:50:50 -0400 Message-Id: <20250429235122.537321-5-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250429235122.537321-1-sashal@kernel.org> References: <20250429235122.537321-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.12.25 Content-Transfer-Encoding: 8bit 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 d00a3b015635c..8af2a569c23aa 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -824,7 +824,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; @@ -1617,21 +1619,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