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]
Message-Id: <1440691197-25780-4-git-send-email-jiri@resnulli.us>
Date:	Thu, 27 Aug 2015 17:59:57 +0200
From:	Jiri Pirko <jiri@...nulli.us>
To:	netdev@...r.kernel.org
Cc:	davem@...emloft.net, idosch@...lanox.com, eladr@...lanox.com,
	ogerlitz@...lanox.com, Jiri Pirko <jiri@...lanox.com>
Subject: [patch net-next v2 3/3] mlxsw: Make mailboxes 4KB aligned

From: Ido Schimmel <idosch@...lanox.com>

The HW-SW contract requires mailboxes passed to the firmware to be 4KB
aligned. Previously, these mailboxes were mapped using streaming DMA
routines, which do not guarantee the bus addresses to be 4KB aligned.
Under certain conditions this constraint was indeed violated and errors
were observed.

By using consistent DMA mapping routines together with a mailbox size of
4KB we are guaranteed not to violate the constraint.

Signed-off-by: Ido Schimmel <idosch@...lanox.com>
Signed-off-by: Jiri Pirko <jiri@...lanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/pci.c | 83 +++++++++++++++++++------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 045f98f..462cea3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -46,6 +46,7 @@
 #include <linux/log2.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/string.h>
 
 #include "pci.h"
 #include "core.h"
@@ -174,6 +175,8 @@ struct mlxsw_pci {
 		struct mlxsw_pci_mem_item *items;
 	} fw_area;
 	struct {
+		struct mlxsw_pci_mem_item out_mbox;
+		struct mlxsw_pci_mem_item in_mbox;
 		struct mutex lock; /* Lock access to command registers */
 		bool nopoll;
 		wait_queue_head_t wait;
@@ -1341,6 +1344,32 @@ static irqreturn_t mlxsw_pci_eq_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int mlxsw_pci_mbox_alloc(struct mlxsw_pci *mlxsw_pci,
+				struct mlxsw_pci_mem_item *mbox)
+{
+	struct pci_dev *pdev = mlxsw_pci->pdev;
+	int err = 0;
+
+	mbox->size = MLXSW_CMD_MBOX_SIZE;
+	mbox->buf = pci_alloc_consistent(pdev, MLXSW_CMD_MBOX_SIZE,
+					 &mbox->mapaddr);
+	if (!mbox->buf) {
+		dev_err(&pdev->dev, "Failed allocating memory for mailbox\n");
+		err = -ENOMEM;
+	}
+
+	return err;
+}
+
+static void mlxsw_pci_mbox_free(struct mlxsw_pci *mlxsw_pci,
+				struct mlxsw_pci_mem_item *mbox)
+{
+	struct pci_dev *pdev = mlxsw_pci->pdev;
+
+	pci_free_consistent(pdev, MLXSW_CMD_MBOX_SIZE, mbox->buf,
+			    mbox->mapaddr);
+}
+
 static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
 			  const struct mlxsw_config_profile *profile)
 {
@@ -1358,6 +1387,15 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
 	mbox = mlxsw_cmd_mbox_alloc();
 	if (!mbox)
 		return -ENOMEM;
+
+	err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
+	if (err)
+		goto mbox_put;
+
+	err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
+	if (err)
+		goto err_out_mbox_alloc;
+
 	err = mlxsw_cmd_query_fw(mlxsw_core, mbox);
 	if (err)
 		goto err_query_fw;
@@ -1420,6 +1458,9 @@ err_fw_area_init:
 err_doorbell_page_bar:
 err_iface_rev:
 err_query_fw:
+	mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
+err_out_mbox_alloc:
+	mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
 mbox_put:
 	mlxsw_cmd_mbox_free(mbox);
 	return err;
@@ -1432,6 +1473,8 @@ static void mlxsw_pci_fini(void *bus_priv)
 	free_irq(mlxsw_pci->msix_entry.vector, mlxsw_pci);
 	mlxsw_pci_aqs_fini(mlxsw_pci);
 	mlxsw_pci_fw_area_fini(mlxsw_pci);
+	mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
+	mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
 }
 
 static struct mlxsw_pci_queue *
@@ -1524,8 +1567,8 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 			      u8 *p_status)
 {
 	struct mlxsw_pci *mlxsw_pci = bus_priv;
-	dma_addr_t in_mapaddr = 0;
-	dma_addr_t out_mapaddr = 0;
+	dma_addr_t in_mapaddr = mlxsw_pci->cmd.in_mbox.mapaddr;
+	dma_addr_t out_mapaddr = mlxsw_pci->cmd.out_mbox.mapaddr;
 	bool evreq = mlxsw_pci->cmd.nopoll;
 	unsigned long timeout = msecs_to_jiffies(MLXSW_PCI_CIR_TIMEOUT_MSECS);
 	bool *p_wait_done = &mlxsw_pci->cmd.wait_done;
@@ -1537,27 +1580,11 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 	if (err)
 		return err;
 
-	if (in_mbox) {
-		in_mapaddr = pci_map_single(mlxsw_pci->pdev, in_mbox,
-					    in_mbox_size, PCI_DMA_TODEVICE);
-		if (unlikely(pci_dma_mapping_error(mlxsw_pci->pdev,
-						   in_mapaddr))) {
-			err = -EIO;
-			goto err_in_mbox_map;
-		}
-	}
+	if (in_mbox)
+		memcpy(mlxsw_pci->cmd.in_mbox.buf, in_mbox, in_mbox_size);
 	mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_HI, in_mapaddr >> 32);
 	mlxsw_pci_write32(mlxsw_pci, CIR_IN_PARAM_LO, in_mapaddr);
 
-	if (out_mbox) {
-		out_mapaddr = pci_map_single(mlxsw_pci->pdev, out_mbox,
-					     out_mbox_size, PCI_DMA_FROMDEVICE);
-		if (unlikely(pci_dma_mapping_error(mlxsw_pci->pdev,
-						   out_mapaddr))) {
-			err = -EIO;
-			goto err_out_mbox_map;
-		}
-	}
 	mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_HI, out_mapaddr >> 32);
 	mlxsw_pci_write32(mlxsw_pci, CIR_OUT_PARAM_LO, out_mapaddr);
 
@@ -1601,7 +1628,7 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 	}
 
 	if (!err && out_mbox && out_mbox_direct) {
-		/* Some commands does not use output param as address to mailbox
+		/* Some commands don't use output param as address to mailbox
 		 * but they store output directly into registers. In that case,
 		 * copy registers into mbox buffer.
 		 */
@@ -1615,19 +1642,9 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
 							   CIR_OUT_PARAM_LO));
 			memcpy(out_mbox + sizeof(tmp), &tmp, sizeof(tmp));
 		}
-	}
-
-	if (out_mapaddr)
-		pci_unmap_single(mlxsw_pci->pdev, out_mapaddr, out_mbox_size,
-				 PCI_DMA_FROMDEVICE);
-
-	/* fall through */
+	} else if (!err && out_mbox)
+		memcpy(out_mbox, mlxsw_pci->cmd.out_mbox.buf, out_mbox_size);
 
-err_out_mbox_map:
-	if (in_mapaddr)
-		pci_unmap_single(mlxsw_pci->pdev, in_mapaddr, in_mbox_size,
-				 PCI_DMA_TODEVICE);
-err_in_mbox_map:
 	mutex_unlock(&mlxsw_pci->cmd.lock);
 
 	return err;
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ