From fce24a9d28f8b99fd0eacc14e252ab4fca9527a7 Mon Sep 17 00:00:00 2001 From: Dave Olson Date: Thu, 17 Jun 2010 23:13:44 +0000 Subject: IB/qib: Don't mark VL15 bufs as WC to avoid a rare 7322 chip problem Don't set write combining via PAT on the VL15 buffers to avoid a rare problem with unaligned writes from interrupt-flushed store buffers. Signed-off-by: Dave Olson Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_init.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/infiniband/hw/qib/qib_init.c') diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 9b40f345ac3f..25895991dc52 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -1499,6 +1499,12 @@ bail: return -ENOMEM; } +/* + * Note: Changes to this routine should be mirrored + * for the diagnostics routine qib_remap_ioaddr32(). + * There is also related code for VL15 buffers in qib_init_7322_variables(). + * The teardown code that unmaps is in qib_pcie_ddcleanup() + */ int init_chip_wc_pat(struct qib_devdata *dd, u32 vl15buflen) { u64 __iomem *qib_kregbase = NULL; -- cgit v1.2.2 From 5df4223a444057e433e9e4f2e101ee7159f8c19d Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 17 Jun 2010 23:13:59 +0000 Subject: IB/qib: Clear eager buffer memory for each new process The eager buffers are not being cleared before being mmapped into a new user address space. This is a potential security risk and should be fixed. Note that the eager header queue is already being cleared. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_init.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/infiniband/hw/qib/qib_init.c') diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 25895991dc52..1d4db4b19d76 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -1472,6 +1472,9 @@ int qib_setup_eagerbufs(struct qib_ctxtdata *rcd) dma_addr_t pa = rcd->rcvegrbuf_phys[chunk]; unsigned i; + /* clear for security and sanity on each use */ + memset(rcd->rcvegrbuf[chunk], 0, size); + for (i = 0; e < egrcnt && i < egrperchunk; e++, i++) { dd->f_put_tid(dd, e + egroff + (u64 __iomem *) -- cgit v1.2.2 From 950aff53949268eec4b0f2bd49f700f9585698f7 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 17 Jun 2010 23:14:15 +0000 Subject: IB/qib: Completion queue callback needs to be single threaded Workqueues aren't exactly equivalent to tasklets since the callback function may be called from multiple CPUs before the callback returns. This causes completion notification callbacks to have MT bugs since they weren't expecting this behavior. The fix is to use a single threaded work queue. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/infiniband/hw/qib/qib_init.c') diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 1d4db4b19d76..7831ff835d15 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -1059,7 +1059,7 @@ static int __init qlogic_ib_init(void) goto bail_dev; } - qib_cq_wq = create_workqueue("qib_cq"); + qib_cq_wq = create_singlethread_workqueue("qib_cq"); if (!qib_cq_wq) { ret = -ENOMEM; goto bail_wq; -- cgit v1.2.2 From 756a33b8dc3ed5c27685a130339de8a894d528a7 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 1 Jul 2010 20:25:45 +0000 Subject: IB/qib: Clean up properly if qib_init() fails If qib_init() fails, the driver fails to free memory, unregister device files, and unregister with the PCIe framework. The driver will unload without error but a subsequent driver load will cause the system to panic. This was found by changing the 7220 code to load the serdes microcode separately and not installing the microcode file. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/infiniband/hw/qib/qib_init.c') diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 7831ff835d15..a873dd596e81 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -1289,8 +1289,18 @@ static int __devinit qib_init_one(struct pci_dev *pdev, if (qib_mini_init || initfail || ret) { qib_stop_timers(dd); + flush_scheduled_work(); for (pidx = 0; pidx < dd->num_pports; ++pidx) dd->f_quiet_serdes(dd->pport + pidx); + if (qib_mini_init) + goto bail; + if (!j) { + (void) qibfs_remove(dd); + qib_device_remove(dd); + } + if (!ret) + qib_unregister_ib_device(dd); + qib_postinit_cleanup(dd); if (initfail) ret = initfail; goto bail; -- cgit v1.2.2