Message ID | 20210517115907.52503-2-mika.westerberg@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | thunderbolt: NVM fixes and consolidation | expand |
On Mon, May 17, 2021 at 02:59:04PM +0300, Mika Westerberg wrote: > From: Mathias Nyman <mathias.nyman@linux.intel.com> > > Up to 64 bytes of data can be read from NVM in one go. Read address > must be dword aligned. Data is read into a local buffer. > > If caller asks to read data starting at an unaligned address then full > dword is anyway read from NVM into a local buffer. Data is then copied > from the local buffer starting at the unaligned offset to the caller > buffer. > > In cases where asked data length + unaligned offset is over 64 bytes > we need to make sure we don't read past the 64 bytes in the local > buffer when copying to caller buffer, and make sure that we don't > skip copying unaligned offset bytes from local buffer anymore after > the first round of 64 byte NVM data read. > > Fixes: 3e13676862f9 ("thunderbolt: Add support for DMA configuration based mailbox") > Cc: stable@vger.kernel.org > Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Applied to thunderbolt.git/fixes.
diff --git a/drivers/thunderbolt/dma_port.c b/drivers/thunderbolt/dma_port.c index 7288aaf01ae6..5631319f7b20 100644 --- a/drivers/thunderbolt/dma_port.c +++ b/drivers/thunderbolt/dma_port.c @@ -366,15 +366,15 @@ int dma_port_flash_read(struct tb_dma_port *dma, unsigned int address, void *buf, size_t size) { unsigned int retries = DMA_PORT_RETRIES; - unsigned int offset; - - offset = address & 3; - address = address & ~3; do { - u32 nbytes = min_t(u32, size, MAIL_DATA_DWORDS * 4); + unsigned int offset; + size_t nbytes; int ret; + offset = address & 3; + nbytes = min_t(size_t, size + offset, MAIL_DATA_DWORDS * 4); + ret = dma_port_flash_read_block(dma, address, dma->buf, ALIGN(nbytes, 4)); if (ret) { @@ -386,6 +386,7 @@ int dma_port_flash_read(struct tb_dma_port *dma, unsigned int address, return ret; } + nbytes -= offset; memcpy(buf, dma->buf + offset, nbytes); size -= nbytes;