All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 5.13 01/11] libata: fix ata_pio_sector for CONFIG_HIGHMEM
@ 2021-08-03 11:43 Sasha Levin
  2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 02/11] reiserfs: add check for root_inode in reiserfs_fill_super Sasha Levin
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Sasha Levin @ 2021-08-03 11:43 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Christoph Hellwig, kernel test robot, Jens Axboe, Sasha Levin, linux-ide

From: Christoph Hellwig <hch@lst.de>

[ Upstream commit ecef6a9effe49e8e2635c839020b9833b71e934c ]

Data transfers are not required to be block aligned in memory, so they
span two pages.  Fix this by splitting the call to >sff_data_xfer into
two for that case.

This has been broken since the initial libata import before the damn
of git, but was uncovered by the legacy ide driver removal.

Reported-by: kernel test robot <oliver.sang@intel.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20210709130237.3730959-1-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/ata/libata-sff.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index ae7189d1a568..b71ea4a680b0 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -637,6 +637,20 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf,
 }
 EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
 
+static void ata_pio_xfer(struct ata_queued_cmd *qc, struct page *page,
+		unsigned int offset, size_t xfer_size)
+{
+	bool do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
+	unsigned char *buf;
+
+	buf = kmap_atomic(page);
+	qc->ap->ops->sff_data_xfer(qc, buf + offset, xfer_size, do_write);
+	kunmap_atomic(buf);
+
+	if (!do_write && !PageSlab(page))
+		flush_dcache_page(page);
+}
+
 /**
  *	ata_pio_sector - Transfer a sector of data.
  *	@qc: Command on going
@@ -648,11 +662,9 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
  */
 static void ata_pio_sector(struct ata_queued_cmd *qc)
 {
-	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
 	struct ata_port *ap = qc->ap;
 	struct page *page;
 	unsigned int offset;
-	unsigned char *buf;
 
 	if (!qc->cursg) {
 		qc->curbytes = qc->nbytes;
@@ -670,13 +682,20 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 
 	DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
 
-	/* do the actual data transfer */
-	buf = kmap_atomic(page);
-	ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write);
-	kunmap_atomic(buf);
+	/*
+	 * Split the transfer when it splits a page boundary.  Note that the
+	 * split still has to be dword aligned like all ATA data transfers.
+	 */
+	WARN_ON_ONCE(offset % 4);
+	if (offset + qc->sect_size > PAGE_SIZE) {
+		unsigned int split_len = PAGE_SIZE - offset;
 
-	if (!do_write && !PageSlab(page))
-		flush_dcache_page(page);
+		ata_pio_xfer(qc, page, offset, split_len);
+		ata_pio_xfer(qc, nth_page(page, 1), 0,
+			     qc->sect_size - split_len);
+	} else {
+		ata_pio_xfer(qc, page, offset, qc->sect_size);
+	}
 
 	qc->curbytes += qc->sect_size;
 	qc->cursg_ofs += qc->sect_size;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-08-03 11:46 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-03 11:43 [PATCH AUTOSEL 5.13 01/11] libata: fix ata_pio_sector for CONFIG_HIGHMEM Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 02/11] reiserfs: add check for root_inode in reiserfs_fill_super Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 03/11] reiserfs: check directory items on read from disk Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 04/11] virt_wifi: fix error on connect Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 05/11] net: qede: Fix end of loop tests for list_for_each_entry Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 06/11] alpha: Send stop IPI to send to online CPUs Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 07/11] net/qla3xxx: fix schedule while atomic in ql_wait_for_drvr_lock and ql_adapter_reset Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 08/11] smb3: rc uninitialized in one fallocate path Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 09/11] drm/amdgpu/display: only enable aux backlight control for OLED panels Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 10/11] platform/x86: gigabyte-wmi: add support for B550 Aorus Elite V2 Sasha Levin
2021-08-03 11:43 ` [PATCH AUTOSEL 5.13 11/11] HID: ft260: fix device removal due to USB disconnect Sasha Levin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.