lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 6 Jun 2008 11:47:13 -0500
From:	Dean Nelson <dcn@....com>
To:	akpm@...ux-foundation.org
Cc:	linux-kernel@...r.kernel.org
Subject: [Patch 05/18] create a common xp_remote_memcpy() function

Create a common remote memcpy function that maps to what the hardware booted
supports.

Signed-off-by: Dean Nelson <dcn@....com>

---

 drivers/misc/sgi-xp/xp.h            |   43 +------------------------
 drivers/misc/sgi-xp/xp_main.c       |    3 +
 drivers/misc/sgi-xp/xp_sn2.c        |   46 ++++++++++++++++++++++++++
 drivers/misc/sgi-xp/xp_uv.c         |   11 ++++++
 drivers/misc/sgi-xp/xpc.h           |    7 ----
 drivers/misc/sgi-xp/xpc_channel.c   |   20 ++++-------
 drivers/misc/sgi-xp/xpc_partition.c |   55 +++++++++++++-------------------
 drivers/misc/sgi-xp/xpnet.c         |   30 ++++++++---------
 8 files changed, 108 insertions(+), 107 deletions(-)

Index: linux-2.6/drivers/misc/sgi-xp/xp.h
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xp.h	2008-05-30 13:55:49.537296334 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xp.h	2008-05-30 13:56:05.871344137 -0500
@@ -17,7 +17,6 @@
 #include <linux/hardirq.h>
 #include <linux/mutex.h>
 #include <asm/sn/types.h>
-#include <asm/sn/bte.h>
 #ifdef CONFIG_IA64
 #include <asm/sn/arch.h>
 #endif
@@ -72,46 +71,6 @@
 #define XP_NASID_MASK_WORDS	((XP_MAX_PHYSNODE_ID + 63) / 64)
 
 /*
- * Wrapper for bte_copy() that should it return a failure status will retry
- * the bte_copy() once in the hope that the failure was due to a temporary
- * aberration (i.e., the link going down temporarily).
- *
- * 	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 vdst, u64 len, u64 mode, void *notification)
-{
-	bte_result_t ret;
-	u64 pdst = ia64_tpa(vdst);
-
-	/*
-	 * 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) && BTE_ERROR_RETRY(ret)) {
-		if (!in_interrupt())
-			cond_resched();
-
-		ret = bte_copy(src, pdst, len, mode, notification);
-	}
-
-	return ret;
-}
-
-/*
  * XPC establishes channel connections between the local partition and any
  * other partition that is currently up. Over these channels, kernel-level
  * `users' can communicate with their counterparts on the other partitions.
@@ -408,6 +367,8 @@ xpc_partid_to_nasids(short partid, void 
 
 extern short xp_max_npartitions;
 
+extern enum xp_retval (*xp_remote_memcpy) (void *, const void *, size_t);
+
 extern u64 xp_nofault_PIOR_target;
 extern int xp_nofault_PIOR(void *);
 extern int xp_error_PIOR(void);
Index: linux-2.6/drivers/misc/sgi-xp/xp_main.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xp_main.c	2008-05-30 13:55:49.665312383 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xp_main.c	2008-05-30 13:56:05.887346143 -0500
@@ -36,6 +36,9 @@ struct device *xp = &xp_dbg_subname;
 short xp_max_npartitions;
 EXPORT_SYMBOL_GPL(xp_max_npartitions);
 
+enum xp_retval (*xp_remote_memcpy) (void *dst, const void *src, size_t len);
+EXPORT_SYMBOL_GPL(xp_remote_memcpy);
+
 /*
  * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
  * users of XPC.
Index: linux-2.6/drivers/misc/sgi-xp/xp_sn2.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xp_sn2.c	2008-05-30 13:55:49.689315393 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xp_sn2.c	2008-05-30 13:56:05.911349152 -0500
@@ -13,6 +13,7 @@
  */
 
 #include <linux/device.h>
+#include <asm/sn/bte.h>
 #include <asm/sn/sn_sal.h>
 #include "xp.h"
 
@@ -72,6 +73,49 @@ xp_unregister_nofault_code_sn2(void)
 				       err_func_addr, 1, 0);
 }
 
+/*
+ * Wrapper for bte_copy().
+ *
+ *	vdst - virtual address of the destination of the transfer.
+ *	psrc - physical address of the source of the transfer.
+ *	len - number of bytes to transfer from source to destination.
+ *
+ * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
+ */
+static enum xp_retval
+xp_remote_memcpy_sn2(void *vdst, const void *psrc, size_t len)
+{
+	bte_result_t ret;
+	u64 pdst = ia64_tpa(vdst);
+	/* >>> What are the rules governing the src and dst addresses passed in?
+	 * >>> Currently we're assuming that dst is a virtual address and src
+	 * >>> is a physical address, is this appropriate? Can we allow them to
+	 * >>> be whatever and we make the change here without damaging the
+	 * >>> addresses?
+	 */
+
+	/*
+	 * 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((u64)psrc, pdst, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+	if (ret == BTE_SUCCESS)
+		return xpSuccess;
+
+	if (is_shub2())
+		dev_err(xp, "bte_copy() on shub2 failed, error=0x%x\n", ret);
+	else
+		dev_err(xp, "bte_copy() failed, error=%d\n", ret);
+
+	return xpBteCopyError;
+}
+
 enum xp_retval
 xp_init_sn2(void)
 {
@@ -79,6 +123,8 @@ xp_init_sn2(void)
 
 	xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
 
+	xp_remote_memcpy = xp_remote_memcpy_sn2;
+
 	return xp_register_nofault_code_sn2();
 }
 
Index: linux-2.6/drivers/misc/sgi-xp/xp_uv.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xp_uv.c	2008-05-30 13:55:49.713318402 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xp_uv.c	2008-05-30 13:56:05.935352162 -0500
@@ -15,12 +15,23 @@
 
 #include "xp.h"
 
+static enum xp_retval
+xp_remote_memcpy_uv(void *vdst, const void *psrc, size_t len)
+{
+	/* >>> this function needs fleshing out */
+	return xpUnsupported;
+}
+
 enum xp_retval
 xp_init_uv(void)
 {
 	BUG_ON(!is_uv());
 
 	xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
+
+	xp_remote_memcpy = xp_remote_memcpy_uv;
+
+	return xpSuccess;
 }
 
 void
Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc.h	2008-05-30 13:55:49.561299343 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc.h	2008-05-30 13:56:05.955354669 -0500
@@ -20,7 +20,6 @@
 #include <linux/completion.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/clksupport.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/mspec.h>
@@ -1125,12 +1124,6 @@ xpc_IPI_init(int index)
 	return amo;
 }
 
-static inline enum xp_retval
-xpc_map_bte_errors(bte_result_t error)
-{
-	return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
-}
-
 /*
  * Check to see if there is any channel activity to/from the specified
  * partition.
Index: linux-2.6/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_channel.c	2008-05-30 13:55:49.609305362 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_channel.c	2008-05-30 13:56:05.975357177 -0500
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/completion.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/sn_sal.h>
 #include "xpc.h"
 
@@ -252,13 +251,13 @@ xpc_setup_infrastructure(struct xpc_part
  *
  * src must be a cacheline aligned physical address on the remote partition.
  * dst must be a cacheline aligned virtual address on this partition.
- * cnt must be an cacheline sized
+ * cnt must be cacheline sized
  */
 static enum xp_retval
 xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
 			   const void *src, size_t cnt)
 {
-	bte_result_t bte_ret;
+	enum xp_retval ret;
 
 	DBUG_ON((u64)src != L1_CACHE_ALIGN((u64)src));
 	DBUG_ON((u64)dst != L1_CACHE_ALIGN((u64)dst));
@@ -267,15 +266,12 @@ xpc_pull_remote_cachelines(struct xpc_pa
 	if (part->act_state == XPC_P_DEACTIVATING)
 		return part->reason;
 
-	bte_ret = xp_bte_copy((u64)src, (u64)dst, (u64)cnt,
-			      (BTE_NORMAL | BTE_WACQUIRE), NULL);
-	if (bte_ret == BTE_SUCCESS)
-		return xpSuccess;
-
-	dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n",
-		XPC_PARTID(part), bte_ret);
-
-	return xpc_map_bte_errors(bte_ret);
+	ret = xp_remote_memcpy(dst, src, cnt);
+	if (ret != xpSuccess) {
+		dev_dbg(xpc_chan, "xp_remote_memcpy() from partition %d failed,"
+			" ret=%d\n", XPC_PARTID(part), ret);
+	}
+	return ret;
 }
 
 /*
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_partition.c	2008-05-30 13:55:49.589302854 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_partition.c	2008-05-30 13:56:05.999360186 -0500
@@ -21,7 +21,6 @@
 #include <linux/mmzone.h>
 #include <linux/nodemask.h>
 #include <asm/uncached.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/nodepda.h>
@@ -92,7 +91,7 @@ xpc_kmalloc_cacheline_aligned(size_t siz
 static u64
 xpc_get_rsvd_page_pa(int nasid)
 {
-	bte_result_t bte_res;
+	enum xp_retval ret;
 	s64 status;
 	u64 cookie = 0;
 	u64 rp_pa = nasid;	/* seed with nasid */
@@ -113,6 +112,7 @@ xpc_get_rsvd_page_pa(int nasid)
 		if (status != SALRET_MORE_PASSES)
 			break;
 
+		/* >>> L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
 		if (L1_CACHE_ALIGN(len) > buf_len) {
 			kfree(buf_base);
 			buf_len = L1_CACHE_ALIGN(len);
@@ -127,10 +127,9 @@ xpc_get_rsvd_page_pa(int nasid)
 			}
 		}
 
-		bte_res = xp_bte_copy(rp_pa, buf, buf_len,
-				      (BTE_NOTIFY | BTE_WACQUIRE), NULL);
-		if (bte_res != BTE_SUCCESS) {
-			dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
+		ret = xp_remote_memcpy((void *)buf, (void *)rp_pa, buf_len);
+		if (ret != xpSuccess) {
+			dev_dbg(xpc_part, "xp_remote_memcpy failed %d\n", ret);
 			status = SALRET_ERROR;
 			break;
 		}
@@ -398,7 +397,7 @@ xpc_check_remote_hb(void)
 	struct xpc_vars *remote_vars;
 	struct xpc_partition *part;
 	short partid;
-	bte_result_t bres;
+	enum xp_retval ret;
 
 	remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
 
@@ -418,13 +417,11 @@ xpc_check_remote_hb(void)
 		}
 
 		/* pull the remote_hb cache line */
-		bres = xp_bte_copy(part->remote_vars_pa,
-				   (u64)remote_vars,
-				   XPC_RP_VARS_SIZE,
-				   (BTE_NOTIFY | BTE_WACQUIRE), NULL);
-		if (bres != BTE_SUCCESS) {
-			XPC_DEACTIVATE_PARTITION(part,
-						 xpc_map_bte_errors(bres));
+		ret = xp_remote_memcpy(remote_vars,
+				       (void *)part->remote_vars_pa,
+				       XPC_RP_VARS_SIZE);
+		if (ret != xpSuccess) {
+			XPC_DEACTIVATE_PARTITION(part, ret);
 			continue;
 		}
 
@@ -457,7 +454,8 @@ static enum xp_retval
 xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
 		  struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
 {
-	int bres, i;
+	int i;
+	enum xp_retval ret;
 
 	/* get the reserved page's physical address */
 
@@ -466,11 +464,10 @@ xpc_get_remote_rp(int nasid, u64 *discov
 		return xpNoRsvdPageAddr;
 
 	/* pull over the reserved page header and part_nasids mask */
-	bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp,
-			   XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
-			   (BTE_NOTIFY | BTE_WACQUIRE), NULL);
-	if (bres != BTE_SUCCESS)
-		return xpc_map_bte_errors(bres);
+	ret = xp_remote_memcpy(remote_rp, (void *)*remote_rp_pa,
+			       XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes);
+	if (ret != xpSuccess)
+		return ret;
 
 	if (discovered_nasids != NULL) {
 		u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
@@ -504,16 +501,16 @@ xpc_get_remote_rp(int nasid, u64 *discov
 static enum xp_retval
 xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
 {
-	int bres;
+	enum xp_retval ret;
 
 	if (remote_vars_pa == 0)
 		return xpVarsNotSet;
 
 	/* pull over the cross partition variables */
-	bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE,
-			   (BTE_NOTIFY | BTE_WACQUIRE), NULL);
-	if (bres != BTE_SUCCESS)
-		return xpc_map_bte_errors(bres);
+	ret = xp_remote_memcpy(remote_vars, (void *)remote_vars_pa,
+			       XPC_RP_VARS_SIZE);
+	if (ret != xpSuccess)
+		return ret;
 
 	if (XPC_VERSION_MAJOR(remote_vars->version) !=
 	    XPC_VERSION_MAJOR(XPC_V_VERSION)) {
@@ -1148,7 +1145,6 @@ xpc_initiate_partid_to_nasids(short part
 {
 	struct xpc_partition *part;
 	u64 part_nasid_pa;
-	int bte_res;
 
 	part = &xpc_partitions[partid];
 	if (part->remote_rp_pa == 0)
@@ -1158,9 +1154,6 @@ xpc_initiate_partid_to_nasids(short part
 
 	part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
 
-	bte_res = xp_bte_copy(part_nasid_pa, (u64)nasid_mask,
-			      xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE),
-			      NULL);
-
-	return xpc_map_bte_errors(bte_res);
+	return xp_remote_memcpy(nasid_mask, (void *)part_nasid_pa,
+				xp_nasid_mask_bytes);
 }
Index: linux-2.6/drivers/misc/sgi-xp/xpnet.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpnet.c	2008-05-30 13:55:49.641309374 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpnet.c	2008-05-30 13:56:06.039365201 -0500
@@ -32,7 +32,6 @@
 #include <linux/mii.h>
 #include <linux/smp.h>
 #include <linux/string.h>
-#include <asm/sn/bte.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/atomic.h>
@@ -169,7 +168,7 @@ static void
 xpnet_receive(short partid, int channel, struct xpnet_message *msg)
 {
 	struct sk_buff *skb;
-	bte_result_t bret;
+	enum xp_retval ret;
 	struct xpnet_dev_private *priv =
 	    (struct xpnet_dev_private *)xpnet_device->priv;
 
@@ -201,7 +200,7 @@ xpnet_receive(short partid, int channel,
 
 	/*
 	 * The allocated skb has some reserved space.
-	 * In order to use bte_copy, we need to get the
+	 * In order to use xp_remote_memcpy(), we need to get the
 	 * skb->data pointer moved forward.
 	 */
 	skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data &
@@ -227,25 +226,24 @@ xpnet_receive(short partid, int channel,
 					(size_t)msg->embedded_bytes);
 	} else {
 		dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
-			"bte_copy(0x%p, 0x%p, %hu)\n", (void *)msg->buf_pa,
-			(void *)__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
-			msg->size);
-
-		bret = bte_copy(msg->buf_pa,
-				__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
-				msg->size, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+			"xp_remote_memcpy(0x%p, 0x%p, %hu)\n", (void *)
+				       ((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+					  (void *)msg->buf_pa, msg->size);
+
+		ret = xp_remote_memcpy((void *)((u64)skb->data &
+				                ~(L1_CACHE_BYTES - 1)),
+				       (void *)msg->buf_pa, msg->size);
 
-		if (bret != BTE_SUCCESS) {
+		if (ret != xpSuccess) {
 			/*
 			 * >>> Need better way of cleaning skb.  Currently skb
 			 * >>> appears in_use and we can't just call
 			 * >>> dev_kfree_skb.
 			 */
-			dev_err(xpnet, "bte_copy(0x%p, 0x%p, 0x%hx) returned "
-				"error=0x%x\n", (void *)msg->buf_pa,
-				(void *)__pa((u64)skb->data &
-					     ~(L1_CACHE_BYTES - 1)),
-				msg->size, bret);
+			dev_err(xpnet, "xp_remote_memcpy(0x%p, 0x%p, 0x%hx) "
+				"returned error=0x%x\n", (void *)
+				((u64)skb->data & ~(L1_CACHE_BYTES - 1)),
+				(void *)msg->buf_pa, msg->size, ret);
 
 			xpc_received(partid, channel, (void *)msg);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ