aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Holt <holt@sgi.com>2006-11-14 21:50:59 -0500
committerTony Luck <tony.luck@intel.com>2006-11-15 13:12:15 -0500
commitcbf093e8c7447a202e376199cc017161262bd7cd (patch)
tree02d468ac29306ea21c01f0bf16246e7d195ef39c
parent45c99533252ef2297f37c5fdd672a3e0eb566870 (diff)
[IA64] bte_unaligned_copy() transfers one extra cache line.
When called to do a transfer that has a start offset within the cache line which is uneven between source and destination and a length which terminates the source of the copy exactly on a cache line, one extra line gets copied into a temporary buffer. This is normally not an issue since the buffer is a kernel buffer and only the requested information gets copied into the user buffer. The problem arises when the source ends at the very last physical page of memory. That last cache line does not exist and results in the SHUB chip raising an MCA. Signed-off-by: Robin Holt <holt@sgi.com> Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/sn/kernel/bte.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index 7f73ad4408aa..ff1c55601178 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -381,14 +381,13 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
381 * bcopy to the destination. 381 * bcopy to the destination.
382 */ 382 */
383 383
384 /* Add the leader from source */
385 headBteLen = len + (src & L1_CACHE_MASK);
386 /* Add the trailing bytes from footer. */
387 headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
388 headBteSource = src & ~L1_CACHE_MASK;
389 headBcopySrcOffset = src & L1_CACHE_MASK; 384 headBcopySrcOffset = src & L1_CACHE_MASK;
390 headBcopyDest = dest; 385 headBcopyDest = dest;
391 headBcopyLen = len; 386 headBcopyLen = len;
387
388 headBteSource = src - headBcopySrcOffset;
389 /* Add the leading and trailing bytes from source */
390 headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
392 } 391 }
393 392
394 if (headBcopyLen > 0) { 393 if (headBcopyLen > 0) {