aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2006-09-06 19:25:46 +0200
committerAdrian Bunk <bunk@stusta.de>2006-09-06 19:25:46 +0200
commitc1646ad43e8273c4748ce2d4be2ec71f9329dbbd (patch)
tree9760f99e594cca5ce3e0e83aeed68f442732ff34 /include
parenta3c94d77000442a64e0776174ad2a70e8aff1943 (diff)
ia64 SGI-SN2: fix silent data corruption caused by XPC
Jack Steiner identified a problem where XPC can cause a silent data corruption. On module load, the placement may cause the xpc_remote_copy_buffer to span two physical pages. DMA transfers are done to the start virtual address translated to physical. This patch changes the buffer from a statically allocated buffer to a kmalloc'd buffer. Dean Nelson reviewed this before posting. I have tested it in the configuration that was showing the memory corruption and verified it works. I also added a BUG_ON statement to help catch this if a similar situation is encountered. Signed-off-by: Robin Holt <holt@sgi.com> Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'include')
-rw-r--r--include/asm-ia64/sn/xp.h22
-rw-r--r--include/asm-ia64/sn/xpc.h3
2 files changed, 20 insertions, 5 deletions
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
index 9bd2f9bf329..6f807e0193b 100644
--- a/include/asm-ia64/sn/xp.h
+++ b/include/asm-ia64/sn/xp.h
@@ -60,23 +60,37 @@
* the bte_copy() once in the hope that the failure was due to a temporary
* aberration (i.e., the link going down temporarily).
*
- * See bte_copy for definition of the input parameters.
+ * src - physical address of the source of the transfer.
+ * vdst - virtual address of the destination of the transfer.
+ * len - number of bytes to transfer from source to destination.
+ * mode - see bte_copy() for definition.
+ * notification - see bte_copy() for definition.
*
* Note: xp_bte_copy() should never be called while holding a spinlock.
*/
static inline bte_result_t
-xp_bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
+xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
{
bte_result_t ret;
+ u64 pdst = ia64_tpa(vdst);
- ret = bte_copy(src, dest, len, mode, notification);
+ /*
+ * Ensure that the physically mapped memory is contiguous.
+ *
+ * We do this by ensuring that the memory is from region 7 only.
+ * If the need should arise to use memory from one of the other
+ * regions, then modify the BUG_ON() statement to ensure that the
+ * memory from that region is always physically contiguous.
+ */
+ BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
+ ret = bte_copy(src, pdst, len, mode, notification);
if (ret != BTE_SUCCESS) {
if (!in_interrupt()) {
cond_resched();
}
- ret = bte_copy(src, dest, len, mode, notification);
+ ret = bte_copy(src, pdst, len, mode, notification);
}
return ret;
diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h
index df7f5f4f3cd..f277b002472 100644
--- a/include/asm-ia64/sn/xpc.h
+++ b/include/asm-ia64/sn/xpc.h
@@ -684,7 +684,8 @@ extern struct xpc_vars *xpc_vars;
extern struct xpc_rsvd_page *xpc_rsvd_page;
extern struct xpc_vars_part *xpc_vars_part;
extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
-extern char xpc_remote_copy_buffer[];
+extern char *xpc_remote_copy_buffer;
+extern void *xpc_remote_copy_buffer_base;
extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
extern void xpc_allow_IPI_ops(void);
extern void xpc_restrict_IPI_ops(void);