aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Holt <holt@sgi.com>2006-12-17 21:34:56 +0100
committerAdrian Bunk <bunk@stusta.de>2006-12-17 21:34:56 +0100
commit4adf3c785f91eda9b5a9706200d2e1c9554a0318 (patch)
treefeeaf5f43e44a9fab29dd38c1511fc01c8267aea
parent961428b9aed2ee9cf631d16f1620640cd54a4557 (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: Tony Luck <tony.luck@intel.com> Signed-off-by: Adrian Bunk <bunk@stusta.de>
-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 1f11db470d9..0675a2b4f50 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -383,14 +383,13 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
* bcopy to the destination.
*/
- /* Add the leader from source */
- headBteLen = len + (src & L1_CACHE_MASK);
- /* Add the trailing bytes from footer. */
- headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
- headBteSource = src & ~L1_CACHE_MASK;
headBcopySrcOffset = src & L1_CACHE_MASK;
headBcopyDest = dest;
headBcopyLen = len;
+
+ headBteSource = src - headBcopySrcOffset;
+ /* Add the leading and trailing bytes from source */
+ headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
}
if (headBcopyLen > 0) {