Applied to the trunk and the branch (2408, 2411). Sorry for the delay.
> -----Original Message----- > From: Sean Hefty [mailto:[email protected]] > Sent: Wednesday, September 02, 2009 5:53 PM > To: [email protected]; Tzachi Dar; Leonid Keller > Subject: RE: [ofw] [PATCH] mthca/mlx4: allow retrieving CA > attributes withpageable memory > > We are in need of a fix for the 2.1 release. Does this patch > look acceptable? > > >Modify the HCA drivers to support querying for attributes using a > >pageable buffer. Since the query calls block, it seems > appropriate for > >the calls to allow pageable memory, rather than forcing the user to > >allocate a non-paged buffer in order to obtain a list of > attributes. > >The problem stems from the HCA drivers accessing a user's > buffer after acquiring a spinlock that raise IRQL. > > > >This fixes kernel crashes with both the winmad and winverbs drivers. > > > >Signed-off-by: Sean Hefty <[email protected]> > >--- > >The mthca patch is compile tested only. > > > >We need this, or some fix, in winof 2.1. > > > >Index: hw/mlx4/kernel/bus/core/cache.c > >=================================================================== > >--- hw/mlx4/kernel/bus/core/cache.c (revision 2342) > >+++ hw/mlx4/kernel/bus/core/cache.c (working copy) > >@@ -80,9 +80,9 @@ > > int index, > > union ib_gid *gid) > > { > >+ union ib_gid cgid; > > struct ib_gid_cache *cache; > > unsigned long flags; > >- int ret = 0; > > > > if (mlx4_is_barred(device->dma_device)) > > return -EFAULT; > >@@ -94,14 +94,16 @@ > > > > cache = device->cache.gid_cache[port_num - start_port(device)]; > > > >- if (index < 0 || index >= cache->table_len) > >- ret = -EINVAL; > >- else > >- *gid = cache->table[index]; > >- > >+ if (index < 0 || index >= cache->table_len) { > >+ read_unlock_irqrestore(&device->cache.lock, flags); > >+ return -EINVAL; > >+ } > >+ > >+ cgid = cache->table[index]; > > read_unlock_irqrestore(&device->cache.lock, flags); > >+ *gid = cgid; > > > >- return ret; > >+ return 0; > > } > > EXPORT_SYMBOL(ib_get_cached_gid); > > > >@@ -113,33 +115,34 @@ > > struct ib_gid_cache *cache; > > unsigned long flags; > > int p, i; > >- int ret = -ENOENT; > > > > if (mlx4_is_barred(device->dma_device)) > > return -EFAULT; > > > >- *port_num = (u8)-1; > >- if (index) > >- *index = (u16)-1; > >- > > read_lock_irqsave(&device->cache.lock, &flags); > > > > for (p = 0; p <= end_port(device) - start_port(device); ++p) { > > cache = device->cache.gid_cache[p]; > > for (i = 0; i < cache->table_len; ++i) { > > if (!memcmp(gid, &cache->table[i], > sizeof *gid)) { > >- *port_num = (u8)(p + > start_port(device)); > >- if (index) > >- *index = (u16)i; > >- ret = 0; > > goto found; > > } > > } > > } > >+ > >+ read_unlock_irqrestore(&device->cache.lock, flags); > >+ *port_num = (u8)-1; > >+ if (index) > >+ *index = (u16)-1; > >+ return -ENOENT; > >+ > > found: > > read_unlock_irqrestore(&device->cache.lock, flags); > >+ *port_num = (u8)(p + start_port(device)); > >+ if (index) > >+ *index = (u16)i; > > > >- return ret; > >+ return 0; > > } > > EXPORT_SYMBOL(ib_find_cached_gid); > > > >@@ -149,8 +152,8 @@ > > __be16 *pkey) > > { > > struct ib_pkey_cache *cache; > >+ __be16 cpkey; > > unsigned long flags; > >- int ret = 0; > > > > if (mlx4_is_barred(device->dma_device)) > > return -EFAULT; > >@@ -162,14 +165,16 @@ > > > > cache = device->cache.pkey_cache[port_num - start_port(device)]; > > > >- if (index < 0 || index >= cache->table_len) > >- ret = -EINVAL; > >- else > >- *pkey = cache->table[index]; > >+ if (index < 0 || index >= cache->table_len) { > >+ read_unlock_irqrestore(&device->cache.lock, flags); > >+ return -EINVAL; > >+ } > > > >+ cpkey = cache->table[index]; > > read_unlock_irqrestore(&device->cache.lock, flags); > >+ *pkey = cpkey; > > > >- return ret; > >+ return 0; > > } > > EXPORT_SYMBOL(ib_get_cached_pkey); > > > >@@ -181,7 +186,6 @@ > > struct ib_pkey_cache *cache; > > unsigned long flags; > > int i; > >- int ret = -ENOENT; > > > > if (mlx4_is_barred(device->dma_device)) > > return -EFAULT; > >@@ -197,14 +201,17 @@ > > > > for (i = 0; i < cache->table_len; ++i) > > if ((cache->table[i] & 0x7fff) == (pkey & 0x7fff)) { > >- *index = (u16)i; > >- ret = 0; > >- break; > >+ goto found; > > } > > > > read_unlock_irqrestore(&device->cache.lock, flags); > >+ *index = (u16)-1; > >+ return -ENOENT; > > > >- return ret; > >+found: > >+ read_unlock_irqrestore(&device->cache.lock, flags); > >+ *index = (u16)i; > >+ return 0; > > } > > EXPORT_SYMBOL(ib_find_cached_pkey); > > > >@@ -213,14 +220,16 @@ > > u8 *lmc) > > { > > unsigned long flags; > >+ u8 clmc; > > int ret = 0; > > > > if (port_num < start_port(device) || port_num > > end_port(device)) > > return -EINVAL; > > > > read_lock_irqsave(&device->cache.lock, &flags); > >- *lmc = device->cache.lmc_cache[port_num - start_port(device)]; > >+ clmc = device->cache.lmc_cache[port_num - start_port(device)]; > > read_unlock_irqrestore(&device->cache.lock, flags); > >+ *lmc = clmc; > > > > return ret; > > } > >Index: hw/mthca/kernel/mt_cache.c > >=================================================================== > >--- hw/mthca/kernel/mt_cache.c (revision 2342) > >+++ hw/mthca/kernel/mt_cache.c (working copy) > >@@ -71,8 +71,8 @@ > > int index, > > union ib_gid *gid) > > { > >+ union ib_gid cgid; > > struct ib_gid_cache *cache; > >- int ret = 0; > > SPIN_LOCK_PREP(lh); > > > > // sanity checks > >@@ -85,14 +85,16 @@ > > > > cache = device->cache.gid_cache[port_num - start_port(device)]; > > > >- if (index < 0 || index >= cache->table_len) > >- ret = -EINVAL; > >- else > >- *gid = cache->table[index]; > >+ if (index < 0 || index >= cache->table_len) { > >+ read_unlock_irqrestore(&lh); > >+ return -EINVAL; > >+ } > > > >+ cgid = cache->table[index]; > > read_unlock_irqrestore(&lh); > >+ *gid = cgid; > > > >- return ret; > >+ return 0; > > } > > > > int ib_find_cached_gid(struct ib_device *device, @@ -103,31 > +105,32 @@ > > struct ib_gid_cache *cache; > > int i; > > u8 p; > >- int ret = -ENOENT; > > SPIN_LOCK_PREP(lh); > > > >- *port_num = (u8)-1; > >- if (index) > >- *index = (u16)-1; > >- > > read_lock_irqsave(&device->cache.lock, &lh); > > > > for (p = 0; p <= end_port(device) - start_port(device); ++p) { > > cache = device->cache.gid_cache[p]; > > for (i = 0; i < cache->table_len; ++i) { > > if (!memcmp(gid, &cache->table[i], > sizeof *gid)) { > >- *port_num = p + start_port(device); > >- if (index) > >- *index = (u16)i; > >- ret = 0; > > goto found; > > } > > } > > } > >+ > >+ read_unlock_irqrestore(&lh); > >+ *port_num = (u8)-1; > >+ if (index) > >+ *index = (u16)-1; > >+ return -ENOENT; > >+ > > found: > > read_unlock_irqrestore(&lh); > >+ *port_num = p + start_port(device); > >+ if (index) > >+ *index = (u16)i; > > > >- return ret; > >+ return 0; > > } > > > > int ib_get_cached_pkey(struct ib_device *device, @@ -136,7 +139,7 @@ > > __be16 *pkey) > > { > > struct ib_pkey_cache *cache; > >- int ret = 0; > >+ __be16 cpkey; > > SPIN_LOCK_PREP(lh); > > > > // sanity checks > >@@ -149,14 +152,16 @@ > > > > cache = device->cache.pkey_cache[port_num - start_port(device)]; > > > >- if (index < 0 || index >= cache->table_len) > >- ret = -EINVAL; > >- else > >- *pkey = cache->table[index]; > >+ if (index < 0 || index >= cache->table_len) { > >+ read_unlock_irqrestore(&lh); > >+ return -EINVAL; > >+ } > > > >+ cpkey = cache->table[index]; > > read_unlock_irqrestore(&lh); > >+ *pkey = cpkey; > > > >- return ret; > >+ return 0; > > } > > > > int ib_find_cached_pkey(struct ib_device *device, @@ -166,7 > +171,6 @@ > >{ > > struct ib_pkey_cache *cache; > > int i; > >- int ret = -ENOENT; > > SPIN_LOCK_PREP(lh); > > > > if (port_num < start_port(device) || port_num > > end_port(device)) @@ > >-176,18 +180,19 @@ > > > > cache = device->cache.pkey_cache[port_num - start_port(device)]; > > > >- *index = (u16)-1; > >- > > for (i = 0; i < cache->table_len; ++i) > > if ((cache->table[i] & 0x7fff) == (pkey & 0x7fff)) { > >- *index = (u16)i; > >- ret = 0; > >- break; > >+ goto found; > > } > > > > read_unlock_irqrestore(&lh); > >+ *index = (u16)-1; > >+ return -ENOENT; > > > >- return ret; > >+found: > >+ read_unlock_irqrestore(&lh); > >+ *index = (u16)i; > >+ return 0; > > } > > > > static void ib_cache_update(struct ib_device *device, > > > > > _______________________________________________ ofw mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw
