--- initial
+++ final
@@ -1,147 +1,145 @@
 struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, u8 port_num, enum ib_qp_type qp_type, struct ib_mad_reg_req *mad_reg_req, u8 rmpp_version, ib_mad_send_handler send_handler, ib_mad_recv_handler recv_handler, void *context) {
   struct ib_mad_port_private *port_priv;
   struct ib_mad_agent *ret = ERR_PTR(-EINVAL);
   struct ib_mad_agent_private *mad_agent_priv;
   struct ib_mad_reg_req *reg_req = NULL;
   struct ib_mad_mgmt_class_table *class;
   struct ib_mad_mgmt_vendor_class_table *vendor;
   struct ib_mad_mgmt_vendor_class *vendor_class;
   struct ib_mad_mgmt_method_table *method;
   int ret2, qpn;
   unsigned long flags;
   u8 mgmt_class, vclass;
   /* Validate parameters */
   qpn = get_spl_qp_index(qp_type);
   if (qpn == -1) goto error1;
   if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION) goto error1;
   /* Validate MAD registration request if supplied */
   if (mad_reg_req) {
     if (mad_reg_req->mgmt_class_version >= MAX_MGMT_VERSION) goto error1;
     if (!recv_handler) goto error1;
     if (mad_reg_req->mgmt_class >= MAX_MGMT_CLASS) {
       /*
        * IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE is the only
        * one in this range currently allowed
        */
       if (mad_reg_req->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) goto error1;
     } else if (mad_reg_req->mgmt_class == 0) {
       /*
        * Class 0 is reserved in IBA and is used for
        * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE
        */
       goto error1;
     } else if (is_vendor_class(mad_reg_req->mgmt_class)) {
       /*
        * If class is in "new" vendor range,
        * ensure supplied OUI is not zero
        */
       if (!is_vendor_oui(mad_reg_req->oui)) goto error1;
     }
     /* Make sure class supplied is consistent with RMPP */
     if (!ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) {
       if (rmpp_version) goto error1;
     }
     /* Make sure class supplied is consistent with QP type */
     if (qp_type == IB_QPT_SMI) {
       if ((mad_reg_req->mgmt_class != IB_MGMT_CLASS_SUBN_LID_ROUTED) && (mad_reg_req->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) goto error1;
     } else {
       if ((mad_reg_req->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED) || (mad_reg_req->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) goto error1;
     }
   } else {
     /* No registration request supplied */
     if (!send_handler) goto error1;
   }
   /* Validate device and port */
   port_priv = ib_get_mad_port(device, port_num);
   if (!port_priv) {
     ret = ERR_PTR(-ENODEV);
     goto error1;
   }
   /* Allocate structures */
   mad_agent_priv = kzalloc(sizeof *mad_agent_priv, GFP_KERNEL);
   if (!mad_agent_priv) {
     ret = ERR_PTR(-ENOMEM);
     goto error1;
   }
   mad_agent_priv->agent.mr = ib_get_dma_mr(port_priv->qp_info[qpn].qp->pd, IB_ACCESS_LOCAL_WRITE);
   if (IS_ERR(mad_agent_priv->agent.mr)) {
     ret = ERR_PTR(-ENOMEM);
     goto error2;
   }
   if (mad_reg_req) {
-    reg_req = kmalloc(sizeof *reg_req, GFP_KERNEL);
+    reg_req = kmemdup(mad_reg_req, sizeof *reg_req, GFP_KERNEL);
     if (!reg_req) {
       ret = ERR_PTR(-ENOMEM);
       goto error3;
     }
-    /* Make a copy of the MAD registration request */
-    memcpy(reg_req, mad_reg_req, sizeof *reg_req);
   }
   /* Now, fill in the various structures */
   mad_agent_priv->qp_info = &port_priv->qp_info[qpn];
   mad_agent_priv->reg_req = reg_req;
   mad_agent_priv->agent.rmpp_version = rmpp_version;
   mad_agent_priv->agent.device = device;
   mad_agent_priv->agent.recv_handler = recv_handler;
   mad_agent_priv->agent.send_handler = send_handler;
   mad_agent_priv->agent.context = context;
   mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
   mad_agent_priv->agent.port_num = port_num;
   spin_lock_init(&mad_agent_priv->lock);
   INIT_LIST_HEAD(&mad_agent_priv->send_list);
   INIT_LIST_HEAD(&mad_agent_priv->wait_list);
   INIT_LIST_HEAD(&mad_agent_priv->done_list);
   INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
   INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
   INIT_LIST_HEAD(&mad_agent_priv->local_list);
   INIT_WORK(&mad_agent_priv->local_work, local_completions);
   atomic_set(&mad_agent_priv->refcount, 1);
   init_completion(&mad_agent_priv->comp);
   spin_lock_irqsave(&port_priv->reg_lock, flags);
   mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
   /*
    * Make sure MAD registration (if supplied)
    * is non overlapping with any existing ones
    */
   if (mad_reg_req) {
     mgmt_class = convert_mgmt_class(mad_reg_req->mgmt_class);
     if (!is_vendor_class(mgmt_class)) {
       class = port_priv->version[mad_reg_req->mgmt_class_version].class;
       if (class) {
         method = class->method_table[mgmt_class];
         if (method) {
           if (method_in_use(&method, mad_reg_req)) goto error4;
         }
       }
       ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv, mgmt_class);
     } else {
       /* "New" vendor class range */
       vendor = port_priv->version[mad_reg_req->mgmt_class_version].vendor;
       if (vendor) {
         vclass = vendor_class_index(mgmt_class);
         vendor_class = vendor->vendor_class[vclass];
         if (vendor_class) {
           if (is_vendor_method_in_use(vendor_class, mad_reg_req)) goto error4;
         }
       }
       ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
     }
     if (ret2) {
       ret = ERR_PTR(ret2);
       goto error4;
     }
   }
   /* Add mad agent into port's agent list */
   list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
   spin_unlock_irqrestore(&port_priv->reg_lock, flags);
   return &mad_agent_priv->agent;
 error4:
   spin_unlock_irqrestore(&port_priv->reg_lock, flags);
   kfree(reg_req);
 error3:
   ib_dereg_mr(mad_agent_priv->agent.mr);
 error2:
   kfree(mad_agent_priv);
 error1:
   return ret;
 }<sep>@@
expression from,to,size,flag;
statement S;
@@
    
-  to = \(kmalloc\|kzalloc\)(size,flag);
+  to = kmemdup(from,size,flag);
       if (to==NULL || ...) S
-  memcpy(to, from, size);