[PATCH 4/5] SCSI: add cpu cache flushes after kmapping and modifying a page

From: Tejun Heo
Date: Sat Jun 03 2006 - 23:42:08 EST


Add calls to flush_kernel_dcache_page() after CPU has kmapped and
modified a page. This fixes PIO cache coherency bugs on architectures
with aliased caches.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>

---

drivers/scsi/3w-9xxx.c | 1 +
drivers/scsi/3w-xxxx.c | 1 +
drivers/scsi/aacraid/aachba.c | 4 +++-
drivers/scsi/ide-scsi.c | 1 +
drivers/scsi/ips.c | 2 ++
drivers/scsi/iscsi_tcp.c | 1 +
drivers/scsi/megaraid.c | 2 ++
drivers/scsi/qlogicpti.c | 1 +
drivers/scsi/scsi_debug.c | 1 +
drivers/scsi/scsi_lib.c | 1 +
10 files changed, 14 insertions(+), 1 deletions(-)

9b4bdd1409efb726d4a6561a4f7e2aff878ab4f4
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index caeb6d2..172f16b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1948,6 +1948,7 @@ static void twa_scsiop_execute_scsi_comp
local_irq_save(flags);
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
+ flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
kunmap_atomic(buf - sg->offset, KM_IRQ0);
local_irq_restore(flags);
}
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index e8e41e6..8449551 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1527,6 +1527,7 @@ static void tw_transfer_internal(TW_Devi
struct scatterlist *sg;

sg = (struct scatterlist *)cmd->request_buffer;
+ flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
kunmap_atomic(buf - sg->offset, KM_IRQ0);
local_irq_restore(flags);
}
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 642a3b4..b7c00b8 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -376,8 +376,10 @@ static void aac_internal_transfer(struct

memcpy(buf + offset, data, transfer_len - offset);

- if (scsicmd->use_sg)
+ if (scsicmd->use_sg) {
+ flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ }

}

diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 39b760a..9c28b95 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -189,6 +189,7 @@ static void idescsi_input_buffers (ide_d
pc->sg->offset;
drive->hwif->atapi_input_bytes(drive,
buf + pc->b_count, count);
+ flush_kernel_dcache_page(kmap_atomic_to_page(buf - pc->sg->offset));
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index a4c0b04..29eb3f0 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -3682,6 +3682,8 @@ ips_scmd_buf_write(Scsi_Cmnd * scmd, voi
local_irq_save(flags);
buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
memcpy(buffer, &cdata[xfer_cnt], min_cnt);
+ flush_kernel_dcache_page(
+ kmap_atomic_to_page(buffer - sg[i].offset));
kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
local_irq_restore(flags);

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 2068b66..ae9784c 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -945,6 +945,7 @@ static int iscsi_scsi_data_in(struct isc
dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
rc = iscsi_ctask_copy(conn, ctask, dest + sg[i].offset,
sg[i].length, offset);
+ flush_kernel_dcache_page(kmap_atomic_to_page(dest));
kunmap_atomic(dest, KM_SOFTIRQ0);
if (rc == -EAGAIN)
/* continue with the next SKB/PDU */
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index de35ffe..7cb7590 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -671,6 +671,8 @@ #endif
struct scatterlist *sg;

sg = (struct scatterlist *)cmd->request_buffer;
+ flush_kernel_dcache_page(
+ kmap_atomic_to_page(buf - sg->offset));
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
cmd->result = (DID_OK << 16);
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index c7e78dc..f8201f2 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1146,6 +1146,7 @@ static void scsi_rbuf_put(struct scsi_cm
struct scatterlist *sg;

sg = (struct scatterlist *) cmd->request_buffer;
+ flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 5a5d2af..88543db 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -511,6 +511,7 @@ static int fill_from_dev_buffer(struct s
len = arr_len - req_len;
}
memcpy(kaddr_off, arr + req_len, len);
+ flush_kernel_dcache_page(kmap_atomic_to_page(kaddr));
kunmap_atomic(kaddr, KM_USER0);
act_len += len;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 764a8b3..8bb2f6c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -945,6 +945,7 @@ void scsi_io_completion(struct scsi_cmnd
unsigned long flags;
char *to = bio_kmap_irq(req->bio, &flags);
memcpy(to, cmd->buffer, cmd->bufflen);
+ flush_kernel_dcache_page(kmap_atomic_to_page(to));
bio_kunmap_irq(to, &flags);
}
kfree(cmd->buffer);
--
1.3.2


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/