<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.2900.3243" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial size=2><SPAN class=795061514-25032009>This patch fixes 
several bugs that show up upon low resources.</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=795061514-25032009>(found with the help 
of Verifier with error injection)</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Index: 
hw/mlx4/kernel/bus/core/cache.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/core/cache.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/core/cache.c (working copy)<BR>@@ -366,48 +366,38 
@@<BR>  int p;<BR>  int 
port_num;<BR>  <BR>+ shutter_init( 
&device->cache.x.work_thread 
);<BR>  rwlock_init(&device->cache.lock);<BR>+ INIT_IB_EVENT_HANDLER(&device->cache.event_handler,<BR>+         
device, ib_cache_event, NULL, NULL, 
0);<BR>+ ib_register_event_handler(&device->cache.event_handler);<BR>+<BR>  port_num 
= end_port(device) - start_port(device) + 1;<BR>- <BR>  if 
(port_num > 0 ) { <BR>   // if port_num ==0   ==> 
there are no IB ports<BR>   device->cache.pkey_cache 
=<BR>    kmalloc(sizeof *device->cache.pkey_cache * 
port_num, GFP_KERNEL);<BR>   device->cache.gid_cache 
=<BR>    kmalloc(sizeof *device->cache.gid_cache * 
port_num, GFP_KERNEL);<BR>-<BR>   device->cache.lmc_cache = 
kmalloc(sizeof *device->cache.lmc_cache 
*<BR>-        port_num, 
GFP_KERNEL);<BR>+   port_num, 
GFP_KERNEL);<BR> <BR>   if (!device->cache.pkey_cache || 
!device->cache.gid_cache ||<BR>-      
!device->cache.lmc_cache) 
{<BR>+   !device->cache.lmc_cache) 
{<BR>    printk(KERN_WARNING "Couldn't allocate cache 
"<BR>-          "for %s\n", 
device->name);<BR>+    "for %s\n", 
device->name);<BR>    goto 
err;<BR>   }<BR>  }<BR> <BR>- shutter_init( 
&device->cache.x.work_thread );<BR>-<BR>  for (p = 0; p < 
port_num; ++p) {<BR>   device->cache.pkey_cache[p] = 
NULL;<BR>   device->cache.gid_cache [p] = 
NULL;<BR>   ib_cache_update(device, (u8)(p + 
start_port(device)));<BR>  }<BR> <BR>- INIT_IB_EVENT_HANDLER(&device->cache.event_handler,<BR>-         
device, ib_cache_event, NULL, NULL, 0);<BR>- if 
(ib_register_event_handler(&device->cache.event_handler))<BR>-  goto 
err_cache;<BR>-<BR>  return;<BR> <BR>-err_cache:<BR>- for (p 
= 0; p <= end_port(device) - start_port(device); ++p) 
{<BR>-  kfree(device->cache.pkey_cache[p]);<BR>-  kfree(device->cache.gid_cache[p]);<BR>- }<BR>-<BR> err:<BR>  kfree(device->cache.pkey_cache);<BR>  kfree(device->cache.gid_cache);<BR>@@ 
-422,6 +412,7 @@<BR> {<BR>  int 
p;<BR> <BR>+ ASSERT(device->cache.event_handler.device);<BR>  ib_unregister_event_handler(&device->cache.event_handler);<BR>  // 
instead of Linux flush_scheduled_work(): wait for them to 
quit<BR>  shutter_shut( &device->cache.x.work_thread 
);<BR>Index: 
hw/mlx4/kernel/bus/core/device.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/core/device.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/core/device.c (working copy)<BR>@@ -302,17 +302,23 
@@<BR>   goto 
out;<BR>  }<BR> <BR>- list_add_tail(&device->core_list, 
&device_list);<BR>-<BR>- device->reg_state = 
IB_DEV_REGISTERED;<BR>-<BR>  {<BR>   struct ib_client 
*client;<BR> <BR>-  list_for_each_entry(client, &client_list, 
list, struct ib_client)<BR>-   if (client->add && 
!add_client_context(device, client))<BR>+  list_for_each_entry(client, 
&client_list, list, struct ib_client) {<BR>+   if ( 
add_client_context(device, client) ) 
{<BR>+    printk(KERN_WARNING "add_client_context failed for 
device %s\n",<BR>+        
device->name);<BR>+    ret = 
-EFAULT;<BR>+    goto 
out;<BR>+   }<BR>+   if 
(client->add)<BR>     client->add(device);<BR>+  }<BR>  }<BR>+    
<BR>+ list_add_tail(&device->core_list, 
&device_list);<BR>+ device->reg_state = 
IB_DEV_REGISTERED;<BR> <BR>  
out:<BR>  mutex_unlock(&device_mutex);<BR>@@ -381,17 +387,25 
@@<BR> int ib_register_client(struct ib_client 
*client)<BR> {<BR>  struct ib_device *device;<BR>+ int ret = 
0;<BR> <BR>  mutex_lock(&device_mutex);<BR> <BR>- list_add_tail(&client->list, 
&client_list);<BR>- list_for_each_entry(device, &device_list, 
core_list, struct ib_device)<BR>-  if (client->add && 
!add_client_context(device, client))<BR>+ list_for_each_entry(device, 
&device_list, core_list, struct ib_device) {<BR>+  if ( 
add_client_context(device, client) ) {<BR>+   printk(KERN_WARNING 
"add_client_context failed for device 
%s\n",<BR>+       
device->name);<BR>+   ret = 
-EFAULT;<BR>+   goto out;<BR>+  }<BR>+  if 
(client->add)<BR>    client->add(device);<BR>-<BR>+ }<BR>+    
<BR>+    list_add_tail(&client->list, 
&client_list);<BR>+out:<BR>  mutex_unlock(&device_mutex);<BR>-<BR>- return 
0;<BR>+ return 
ret;<BR> }<BR> EXPORT_SYMBOL(ib_register_client);<BR> <BR>Index: 
hw/mlx4/kernel/bus/drv/drv.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/drv/drv.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/drv/drv.c (working copy)<BR>@@ -323,10 +323,12 
@@<BR> <BR>  p_fdo->bus_ib_ifc.pdev = 
&p_fdo->pci_dev;<BR>  p_fdo->bus_ib_ifc.p_ibdev = 
p_fdo->pci_dev.ib_dev;<BR>- p_fdo->bus_ib_ifc.pmlx4_dev = 
to_mdev(p_fdo->pci_dev.ib_dev)->dev;<BR>- p_fdo->bus_ib_ifc.is_livefish 
= mlx4_is_livefish(p_fdo->pci_dev.dev);<BR>- if ( 
p_fdo->bus_ib_ifc.pmlx4_dev->flags & MLX4_FLAG_MSI_X 
)<BR>-  p_fdo->bus_ib_ifc.n_msi_vectors = 
p_fdo->pci_dev.n_msi_vectors - 2;<BR>+    
p_fdo->bus_ib_ifc.is_livefish = 
mlx4_is_livefish(p_fdo->pci_dev.dev);    
<BR>+    if ( p_fdo->bus_ib_ifc.is_livefish == 0 ) 
{<BR>+        p_fdo->bus_ib_ifc.pmlx4_dev 
= to_mdev(p_fdo->pci_dev.ib_dev)->dev;    
<BR>+     if ( p_fdo->bus_ib_ifc.pmlx4_dev->flags 
& MLX4_FLAG_MSI_X )<BR>+      
p_fdo->bus_ib_ifc.n_msi_vectors = p_fdo->pci_dev.n_msi_vectors - 
2;<BR>+    }<BR> <BR>  p_fdo->card_started = 
TRUE;<BR> <BR>@@ -572,13 +574,13 
@@<BR>      pdev->int_info = 
*desc;<BR>     if (desc->Flags & 
CM_RESOURCE_INTERRUPT_MESSAGE) 
{<BR>      pdev->n_msi_vectors_alloc = 
(u8)(pdev->n_msi_vectors_alloc+desc_raw->u.MessageInterrupt.Raw.MessageCount);<BR>-     MLX4_PRINT(TRACE_LEVEL_WARNING, 
MLX4_DBG_DRV,<BR>+     MLX4_PRINT(TRACE_LEVEL_VERBOSE, 
MLX4_DBG_DRV,<BR>       ("EvtPrepareHardware: 
Desc %d: MsiInterrupt: Share %d, Flags %#x, Level %d, Vector %#x, Affinity 
%#x\n", <BR>       i, 
desc->ShareDisposition, 
desc->Flags,<BR>       desc->u.MessageInterrupt.Translated.Level, 
<BR>       desc->u.MessageInterrupt.Translated.Vector, 
<BR>       (u32)desc->u.MessageInterrupt.Translated.Affinity 
));<BR>-     MLX4_PRINT(TRACE_LEVEL_WARNING, 
MLX4_DBG_DRV,<BR>+     MLX4_PRINT(TRACE_LEVEL_VERBOSE, 
MLX4_DBG_DRV,<BR>       ("EvtPrepareHardware: 
Desc %d: RawMsiInterrupt: Share %d, Flags %#x, MessageCount %#hx, Vector %#x, 
Affinity %#x\n", <BR>       i, 
desc_raw->ShareDisposition, 
desc_raw->Flags,<BR>       desc_raw->u.MessageInterrupt.Raw.MessageCount, 
<BR>@@ -586,7 +588,7 
@@<BR>       (u32)desc_raw->u.MessageInterrupt.Raw.Affinity 
));<BR>     }<BR>     else { 
// line-based 
interrupt<BR>-     MLX4_PRINT(TRACE_LEVEL_WARNING, 
MLX4_DBG_DRV,<BR>+     MLX4_PRINT(TRACE_LEVEL_VERBOSE, 
MLX4_DBG_DRV,<BR>       ("EvtPrepareHardware: 
Desc %d: LineInterrupt: Share %d, Flags %#x, Level %d, Vector %#x, Affinity 
%#x\n", <BR>       i, 
desc->ShareDisposition, 
desc->Flags,<BR>       desc->u.Interrupt.Level, 
desc->u.Interrupt.Vector, <BR>@@ -774,14 +776,14 
@@<BR> }<BR> <BR> NTSTATUS<BR>-EvtDeviceAdd(<BR>+EvtDriverDeviceAdd(<BR>  IN 
WDFDRIVER        Driver,<BR>  IN 
PWDFDEVICE_INIT  DeviceInit<BR>  )<BR> /*++<BR> Routine 
Description:<BR> <BR>- EvtDeviceAdd is called by the framework in 
response to AddDevice<BR>+ EvtDriverDeviceAdd is called by the framework in 
response to AddDevice<BR>  call from the PnP manager. We create and 
initialize a device object to<BR>  represent a new instance of mxe 
bus.<BR> <BR>@@ -1191,7 +1193,7 
@@<BR>  //<BR> <BR>  WDF_DRIVER_CONFIG_INIT(<BR>-  &config, 
EvtDeviceAdd );<BR>+  &config, EvtDriverDeviceAdd 
);<BR>  config.EvtDriverUnload = 
EvtDriverUnload;<BR> <BR>  //<BR>Index: 
hw/mlx4/kernel/bus/drv/drv.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/drv/drv.h (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/drv/drv.h (working copy)<BR>@@ -155,7 +155,7 
@@<BR>  );<BR>  <BR> NTSTATUS<BR>-EvtDeviceAdd(<BR>+EvtDriverDeviceAdd(<BR>  IN 
WDFDRIVER        Driver,<BR>  IN 
PWDFDEVICE_INIT  DeviceInit<BR>  );<BR>Index: 
hw/mlx4/kernel/bus/drv/pci.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/drv/pci.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/drv/pci.c (working copy)<BR>@@ -541,7 +541,7 
@@<BR>    p_vector = ka;<BR>    /* print 
(allocated+2) vectors */<BR>    for (i=0; 
i<pdev->n_msi_vectors_alloc+2; i++) 
{<BR>-    MLX4_PRINT( TRACE_LEVEL_WARNING  
,MLX4_DBG_PNP  ,<BR>+    MLX4_PRINT( 
TRACE_LEVEL_VERBOSE  ,MLX4_DBG_PNP  
,<BR>      ("MSI-X Vectors: Id %d, Masked %d, Addr 
%#I64x, Data %#x\n",<BR>      i, 
MSIX_VECTOR_MASKED(p_vector[i].Flags),<BR>      p_vector[i].Addr, 
p_vector[i].Data ));<BR>@@ -587,7 +587,7 
@@<BR> )<BR> {<BR>  u32       sem;<BR>- NTSTATUS     status 
= STATUS_SUCCESS;<BR>+ NTSTATUS     status = 
STATUS_SUCCESS, status1;<BR>  PBUS_INTERFACE_STANDARD  p_ifc 

&pdev->bus_pci_ifc;<BR>  PCI_COMMON_CONFIG*   p_cfg 
= &pdev->pci_cfg_space;<BR>  struct msix_saved_info 
  msix_info;<BR>@@ -703,19 +703,19 
@@<BR>   }<BR>  }<BR> <BR>+ status = 
STATUS_SUCCESS;<BR>+<BR>+err:<BR>  /* restore MSI-X info after reset 
*/<BR>- status = __pci_restore_msix_info( pdev, &msix_info 
);<BR>- if (!NT_SUCCESS(status))<BR>-  goto 
err;<BR>+ status1 = __pci_restore_msix_info( pdev, &msix_info 
);<BR>+ status = (!status) ? status1 : status; /* return the only or 
the first error */<BR>+ if( NT_SUCCESS( status ) ) 
{<BR>+  MLX4_PRINT( TRACE_LEVEL_WARNING ,MLX4_DBG_PNP , ("HCA has been 
reset ! \n"));<BR>+ }<BR> <BR>- /* check, whether MSI-X 
capabilities were restore */<BR>+ /* check, whether MSI-X capabilities have 
been restored */<BR>  pci_get_msi_info( pdev, p_cfg, 
&pdev->uplink_info );<BR> <BR>- MLX4_PRINT( TRACE_LEVEL_WARNING 
,MLX4_DBG_PNP , ("HCA has been reset ! \n"));<BR>-<BR>- status = 
STATUS_SUCCESS;<BR>-<BR>-err:<BR>  if (pdev->msix_info.valid) 
<BR>   pci_free_msix_info_resources(&pdev->msix_info);<BR>  MLX4_EXIT( 
MLX4_DBG_PNP );<BR>Index: 
hw/mlx4/kernel/bus/ib/main.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/ib/main.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/ib/main.c (working copy)<BR>@@ -611,6 +611,7 
@@<BR>  mlx4_pd_free(dev, 
ibdev->priv_pdn);<BR> <BR> err_dealloc:<BR>+ ibdev->ib_dev.reg_state 

IB_DEV_UNINITIALIZED;<BR>  ib_dealloc_device(&ibdev->ib_dev);<BR> <BR>  return 
NULL;<BR>Index: 
hw/mlx4/kernel/bus/net/catas.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/catas.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/net/catas.c (working copy)<BR>@@ -370,6 +370,7 
@@<BR>   // to allow for end of operations that are in 
progress<BR>   reset_work = IoAllocateWorkItem( 
dev->pdev->p_self_do );<BR>   if (!reset_work) 
{<BR>+            
spin_unlock_irqrestore(&ibdev->event_handler_lock, 
flags);<BR>    mlx4_err(dev, "mlx4_reset_request 
IoAllocateWorkItem failed, reset will not be 
propagated\n");<BR>    err = 
-EFAULT;<BR>    goto err_workitem;<BR>Index: 
hw/mlx4/kernel/bus/net/cmd.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/cmd.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/net/cmd.c (working copy)<BR>@@ -337,9 +337,15 
@@<BR>     mlx4_dispatch_reset_event(dev->pdev->ib_dev, 
IB_EVENT_RESET_DRIVER);<BR>    }<BR>   }<BR>+  else 
{<BR>+   err = -EFAULT;<BR>+   mlx4_err(dev, 
"mlx4_cmd_wait: Unexpected end of waiting for a comand 
\n");<BR>+   ASSERT(0);<BR>+  }<BR>  }<BR>-<BR>- err 
= context->result;<BR>+ else<BR>+  err = 
context->result;<BR>+ <BR>  if (err)<BR>   goto 
out;<BR> <BR>Index: 
hw/mlx4/kernel/bus/net/intf.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/intf.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/net/intf.c (working copy)<BR>@@ -43,13 +43,13 
@@<BR> static LIST_HEAD(dev_list);<BR> static 
DEFINE_MUTEX(intf_mutex);<BR> <BR>-static void mlx4_add_device(struct 
mlx4_interface *intf, struct mlx4_priv *priv)<BR>+static int 
mlx4_add_device(struct mlx4_interface *intf, struct mlx4_priv 
*priv)<BR> {<BR>  struct mlx4_device_context 
*dev_ctx;<BR> <BR>  dev_ctx = kmalloc(sizeof *dev_ctx, 
GFP_KERNEL);<BR>  if 
(!dev_ctx)<BR>-  return;<BR>+  return 
-EFAULT;<BR> <BR>  dev_ctx->intf    = 
intf;<BR>  dev_ctx->context = 
intf->add(&priv->dev);<BR>@@ -59,8 +59,11 
@@<BR>   spin_lock_irq(&priv->ctx_lock);<BR>   list_add_tail(&dev_ctx->list, 
&priv->ctx_list);<BR>   spin_unlock_irq(&priv->ctx_lock);<BR>- } 
else<BR>+ } else 
{<BR>   kfree(dev_ctx);<BR>+  return 
-EFAULT;<BR>+ }<BR>+ return 0;<BR> }<BR> <BR> static 
void mlx4_remove_device(struct mlx4_interface *intf, struct mlx4_priv 
*priv)<BR>@@ -82,19 +85,25 @@<BR> int mlx4_register_interface(struct 
mlx4_interface *intf)<BR> {<BR>  struct mlx4_priv 
*priv;<BR>+ int err = 0;<BR> <BR>  if (!intf->add || 
!intf->remove)<BR>   return 
-EINVAL;<BR> <BR>  mutex_lock(&intf_mutex);<BR> <BR>- list_add_tail(&intf->list, 
&intf_list);<BR>- list_for_each_entry(priv, &dev_list, dev_list, 
struct mlx4_priv)<BR>-  mlx4_add_device(intf, 
priv);<BR>+ list_for_each_entry(priv, &dev_list, dev_list, struct 
mlx4_priv) {<BR>+  if (mlx4_add_device(intf, priv)) 
{<BR>+   err = -EFAULT;<BR>+   goto 
end;<BR>+  }<BR>+ }<BR> <BR>+    
list_add_tail(&intf->list, 
&intf_list);<BR>+<BR>+end:<BR>  mutex_unlock(&intf_mutex);<BR>-<BR>- return 
0;<BR>+ return 
err;<BR> }<BR> EXPORT_SYMBOL_GPL(mlx4_register_interface);<BR> <BR>@@ 
-137,12 +146,18 
@@<BR> <BR>  mutex_lock(&intf_mutex);<BR> <BR>+ list_for_each_entry(intf, 
&intf_list, list, struct mlx4_interface) {<BR>+  if 
(mlx4_add_device(intf, priv)) {<BR>+   err = 
-EFAULT;<BR>+   goto 
end;<BR>+  }<BR>+ }<BR>+    
<BR>  list_add_tail(&priv->dev_list, 
&dev_list);<BR>- list_for_each_entry(intf, &intf_list, list, struct 
mlx4_interface)<BR>-  mlx4_add_device(intf, 
priv);<BR>-<BR>+    
<BR>+end:<BR>  mutex_unlock(&intf_mutex);<BR>- if 
(!mlx4_is_livefish(dev))<BR>+ if (!err && 
!mlx4_is_livefish(dev))<BR>   err = 
mlx4_start_catas_poll(dev);<BR> <BR>  return err;<BR>Index: 
hw/mlx4/kernel/bus/net/main.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/main.c (revision 2055)<BR>+++ 
hw/mlx4/kernel/bus/net/main.c (working copy)<BR>@@ -956,9 +956,11 
@@<BR>     ("mlx4_register_device for livefish failed, 
return with error.\n"));<BR>    pdev->dev = 
NULL;<BR>    kfree(priv);<BR>+  } 
<BR>+  else {<BR>+    
  MLX4_PRINT(TRACE_LEVEL_ERROR ,MLX4_DBG_LOW ,<BR>+    
   ("MLX4_BUS started in \"livefish\" mode 
!!!.\n"));<BR>   }<BR>-  MLX4_PRINT(TRACE_LEVEL_ERROR 
,MLX4_DBG_LOW ,<BR>-   ("MLX4_BUS started in \"livefish\" mode 
!!!.\n"));<BR>   goto end;<BR>  }<BR> <BR>@@ 
-1064,8 +1066,8 
@@<BR>   mlx4_close_hca(dev);<BR>   mlx4_cmd_cleanup(dev);<BR> <BR>-  if 
(reset)<BR>-   mlx4_reset(dev);<BR>+  if (reset 
&& mlx4_reset(dev))<BR>+   mlx4_err(dev, "Failed to reset 
HCA\n");<BR>   mlx4_dbg(dev, "MLX4_BUS: NET device (dev_id=%d) is 
REMOVED ! \n", (int)pdev->dev_id);<BR>   pdev->dev = 
NULL;<BR> done:<BR>Index: 
hw/mthca/kernel/mt_cache.c<BR>===================================================================<BR>--- 
hw/mthca/kernel/mt_cache.c (revision 2055)<BR>+++ 
hw/mthca/kernel/mt_cache.c (working copy)<BR>@@ -341,6 +341,9 
@@<BR>  u8 
p;<BR> <BR>  rwlock_init(&device->cache.lock);<BR>+ INIT_IB_EVENT_HANDLER(&device->cache.event_handler,<BR>+         
device, 
ib_cache_event);<BR>+ ib_register_event_handler(&device->cache.event_handler);<BR> <BR>  device->cache.pkey_cache 
=<BR>   kmalloc(sizeof *device->cache.pkey_cache *<BR>@@ 
-361,19 +364,8 @@<BR>   ib_cache_update(device, p + 
start_port(device));<BR>  }<BR> <BR>- INIT_IB_EVENT_HANDLER(&device->cache.event_handler,<BR>-         
device, ib_cache_event);<BR>- if 
(ib_register_event_handler(&device->cache.event_handler))<BR>-  goto 
err_cache;<BR>-<BR>  return;<BR> <BR>-err_cache:<BR>- for (p 
= 0; p <= end_port(device) - start_port(device); ++p) 
{<BR>-  kfree(device->cache.pkey_cache[p]);<BR>-  kfree(device->cache.gid_cache[p]);<BR>- }<BR>-<BR> err:<BR>  kfree(device->cache.pkey_cache);<BR>  kfree(device->cache.gid_cache);<BR></FONT></DIV></BODY></HTML>