diff options
author | Dan Williams <dan.j.williams@intel.com> | 2007-07-20 00:31:46 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-20 08:44:19 -0700 |
commit | eb0645a8b1f14da300f40bb9f424640cd1181fbf (patch) | |
tree | 462789626fcd1775bec80d74d19bcd68797589c8 /crypto/async_tx/async_memcpy.c | |
parent | 7c6129c68fe90a61166800b40217a850b8faee98 (diff) | |
download | lwn-eb0645a8b1f14da300f40bb9f424640cd1181fbf.tar.gz lwn-eb0645a8b1f14da300f40bb9f424640cd1181fbf.zip |
async_tx: fix kmap_atomic usage in async_memcpy
Andrew Morton:
[async_memcpy] is very wrong if both ASYNC_TX_KMAP_DST and
ASYNC_TX_KMAP_SRC can ever be set. We'll end up using the same kmap
slot for both src add dest and we get either corrupted data or a BUG.
Evgeniy Polyakov:
Btw, shouldn't it always be kmap_atomic() even if flag is not set.
That pages are usual one returned by alloc_page().
So fix the usage of kmap_atomic and kill the ASYNC_TX_KMAP_DST and
ASYNC_TX_KMAP_SRC flags.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'crypto/async_tx/async_memcpy.c')
-rw-r--r-- | crypto/async_tx/async_memcpy.c | 19 |
1 files changed, 4 insertions, 15 deletions
diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c index a973f4ef897d..047e533fcc5b 100644 --- a/crypto/async_tx/async_memcpy.c +++ b/crypto/async_tx/async_memcpy.c @@ -36,7 +36,6 @@ * @offset: offset in pages to start transaction * @len: length in bytes * @flags: ASYNC_TX_ASSUME_COHERENT, ASYNC_TX_ACK, ASYNC_TX_DEP_ACK, - * ASYNC_TX_KMAP_SRC, ASYNC_TX_KMAP_DST * @depend_tx: memcpy depends on the result of this transaction * @cb_fn: function to call when the memcpy completes * @cb_param: parameter to pass to the callback routine @@ -88,23 +87,13 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, __FUNCTION__); } - if (flags & ASYNC_TX_KMAP_DST) - dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; - else - dest_buf = page_address(dest) + dest_offset; - - if (flags & ASYNC_TX_KMAP_SRC) - src_buf = kmap_atomic(src, KM_USER0) + src_offset; - else - src_buf = page_address(src) + src_offset; + dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; + src_buf = kmap_atomic(src, KM_USER1) + src_offset; memcpy(dest_buf, src_buf, len); - if (flags & ASYNC_TX_KMAP_DST) - kunmap_atomic(dest_buf, KM_USER0); - - if (flags & ASYNC_TX_KMAP_SRC) - kunmap_atomic(src_buf, KM_USER0); + kunmap_atomic(dest_buf, KM_USER0); + kunmap_atomic(src_buf, KM_USER1); async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param); } |