diff options
| -rw-r--r-- | drivers/infiniband/core/user_mad.c | 73 |
1 files changed, 21 insertions, 52 deletions
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index a48166a8e04b..17ec0a19dbc0 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
| @@ -99,7 +99,6 @@ struct ib_umad_packet { | |||
| 99 | struct ib_mad_send_buf *msg; | 99 | struct ib_mad_send_buf *msg; |
| 100 | struct list_head list; | 100 | struct list_head list; |
| 101 | int length; | 101 | int length; |
| 102 | DECLARE_PCI_UNMAP_ADDR(mapping) | ||
| 103 | struct ib_user_mad mad; | 102 | struct ib_user_mad mad; |
| 104 | }; | 103 | }; |
| 105 | 104 | ||
| @@ -145,15 +144,12 @@ static void send_handler(struct ib_mad_agent *agent, | |||
| 145 | ib_free_send_mad(packet->msg); | 144 | ib_free_send_mad(packet->msg); |
| 146 | 145 | ||
| 147 | if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { | 146 | if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { |
| 148 | timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr), | 147 | timeout = kzalloc(sizeof *timeout + IB_MGMT_MAD_HDR, GFP_KERNEL); |
| 149 | GFP_KERNEL); | ||
| 150 | if (!timeout) | 148 | if (!timeout) |
| 151 | goto out; | 149 | goto out; |
| 152 | 150 | ||
| 153 | memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr)); | 151 | timeout->length = IB_MGMT_MAD_HDR; |
| 154 | 152 | timeout->mad.hdr.id = packet->mad.hdr.id; | |
| 155 | timeout->length = sizeof (struct ib_mad_hdr); | ||
| 156 | timeout->mad.hdr.id = packet->mad.hdr.id; | ||
| 157 | timeout->mad.hdr.status = ETIMEDOUT; | 153 | timeout->mad.hdr.status = ETIMEDOUT; |
| 158 | memcpy(timeout->mad.data, packet->mad.data, | 154 | memcpy(timeout->mad.data, packet->mad.data, |
| 159 | sizeof (struct ib_mad_hdr)); | 155 | sizeof (struct ib_mad_hdr)); |
| @@ -176,11 +172,10 @@ static void recv_handler(struct ib_mad_agent *agent, | |||
| 176 | goto out; | 172 | goto out; |
| 177 | 173 | ||
| 178 | length = mad_recv_wc->mad_len; | 174 | length = mad_recv_wc->mad_len; |
| 179 | packet = kmalloc(sizeof *packet + length, GFP_KERNEL); | 175 | packet = kzalloc(sizeof *packet + length, GFP_KERNEL); |
| 180 | if (!packet) | 176 | if (!packet) |
| 181 | goto out; | 177 | goto out; |
| 182 | 178 | ||
| 183 | memset(packet, 0, sizeof *packet + length); | ||
| 184 | packet->length = length; | 179 | packet->length = length; |
| 185 | 180 | ||
| 186 | ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data); | 181 | ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data); |
| @@ -246,7 +241,7 @@ static ssize_t ib_umad_read(struct file *filp, char __user *buf, | |||
| 246 | else | 241 | else |
| 247 | ret = -ENOSPC; | 242 | ret = -ENOSPC; |
| 248 | } else if (copy_to_user(buf, &packet->mad, | 243 | } else if (copy_to_user(buf, &packet->mad, |
| 249 | packet->length + sizeof (struct ib_user_mad))) | 244 | packet->length + sizeof (struct ib_user_mad))) |
| 250 | ret = -EFAULT; | 245 | ret = -EFAULT; |
| 251 | else | 246 | else |
| 252 | ret = packet->length + sizeof (struct ib_user_mad); | 247 | ret = packet->length + sizeof (struct ib_user_mad); |
| @@ -271,22 +266,19 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 271 | struct ib_rmpp_mad *rmpp_mad; | 266 | struct ib_rmpp_mad *rmpp_mad; |
| 272 | u8 method; | 267 | u8 method; |
| 273 | __be64 *tid; | 268 | __be64 *tid; |
| 274 | int ret, length, hdr_len, rmpp_hdr_size; | 269 | int ret, length, hdr_len, copy_offset; |
| 275 | int rmpp_active = 0; | 270 | int rmpp_active = 0; |
| 276 | 271 | ||
| 277 | if (count < sizeof (struct ib_user_mad)) | 272 | if (count < sizeof (struct ib_user_mad)) |
| 278 | return -EINVAL; | 273 | return -EINVAL; |
| 279 | 274 | ||
| 280 | length = count - sizeof (struct ib_user_mad); | 275 | length = count - sizeof (struct ib_user_mad); |
| 281 | packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) + | 276 | packet = kmalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); |
| 282 | sizeof (struct ib_rmpp_hdr), GFP_KERNEL); | ||
| 283 | if (!packet) | 277 | if (!packet) |
| 284 | return -ENOMEM; | 278 | return -ENOMEM; |
| 285 | 279 | ||
| 286 | if (copy_from_user(&packet->mad, buf, | 280 | if (copy_from_user(&packet->mad, buf, |
| 287 | sizeof (struct ib_user_mad) + | 281 | sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)) { |
| 288 | sizeof (struct ib_mad_hdr) + | ||
| 289 | sizeof (struct ib_rmpp_hdr))) { | ||
| 290 | ret = -EFAULT; | 282 | ret = -EFAULT; |
| 291 | goto err; | 283 | goto err; |
| 292 | } | 284 | } |
| @@ -297,8 +289,6 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 297 | goto err; | 289 | goto err; |
| 298 | } | 290 | } |
| 299 | 291 | ||
| 300 | packet->length = length; | ||
| 301 | |||
| 302 | down_read(&file->agent_mutex); | 292 | down_read(&file->agent_mutex); |
| 303 | 293 | ||
| 304 | agent = file->agent[packet->mad.hdr.id]; | 294 | agent = file->agent[packet->mad.hdr.id]; |
| @@ -345,12 +335,10 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 345 | goto err_ah; | 335 | goto err_ah; |
| 346 | } | 336 | } |
| 347 | rmpp_active = 1; | 337 | rmpp_active = 1; |
| 338 | copy_offset = IB_MGMT_RMPP_HDR; | ||
| 348 | } else { | 339 | } else { |
| 349 | if (length > sizeof (struct ib_mad)) { | ||
| 350 | ret = -EINVAL; | ||
| 351 | goto err_ah; | ||
| 352 | } | ||
| 353 | hdr_len = IB_MGMT_MAD_HDR; | 340 | hdr_len = IB_MGMT_MAD_HDR; |
| 341 | copy_offset = IB_MGMT_MAD_HDR; | ||
| 354 | } | 342 | } |
| 355 | 343 | ||
| 356 | packet->msg = ib_create_send_mad(agent, | 344 | packet->msg = ib_create_send_mad(agent, |
| @@ -368,28 +356,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 368 | packet->msg->retries = packet->mad.hdr.retries; | 356 | packet->msg->retries = packet->mad.hdr.retries; |
| 369 | packet->msg->context[0] = packet; | 357 | packet->msg->context[0] = packet; |
| 370 | 358 | ||
| 371 | if (!rmpp_active) { | 359 | /* Copy MAD headers (RMPP header in place) */ |
| 372 | /* Copy message from user into send buffer */ | 360 | memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR); |
| 373 | if (copy_from_user(packet->msg->mad, | 361 | /* Now, copy rest of message from user into send buffer */ |
| 374 | buf + sizeof (struct ib_user_mad), length)) { | 362 | if (copy_from_user(packet->msg->mad + copy_offset, |
| 375 | ret = -EFAULT; | 363 | buf + sizeof (struct ib_user_mad) + copy_offset, |
| 376 | goto err_msg; | 364 | length - copy_offset)) { |
| 377 | } | 365 | ret = -EFAULT; |
| 378 | } else { | 366 | goto err_msg; |
| 379 | rmpp_hdr_size = sizeof (struct ib_mad_hdr) + | ||
| 380 | sizeof (struct ib_rmpp_hdr); | ||
| 381 | |||
| 382 | /* Only copy MAD headers (RMPP header in place) */ | ||
| 383 | memcpy(packet->msg->mad, packet->mad.data, | ||
| 384 | sizeof (struct ib_mad_hdr)); | ||
| 385 | |||
| 386 | /* Now, copy rest of message from user into send buffer */ | ||
| 387 | if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data, | ||
| 388 | buf + sizeof (struct ib_user_mad) + rmpp_hdr_size, | ||
| 389 | length - rmpp_hdr_size)) { | ||
| 390 | ret = -EFAULT; | ||
| 391 | goto err_msg; | ||
| 392 | } | ||
| 393 | } | 367 | } |
| 394 | 368 | ||
| 395 | /* | 369 | /* |
| @@ -414,7 +388,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
| 414 | 388 | ||
| 415 | up_read(&file->agent_mutex); | 389 | up_read(&file->agent_mutex); |
| 416 | 390 | ||
| 417 | return sizeof (struct ib_user_mad_hdr) + packet->length; | 391 | return count; |
| 418 | 392 | ||
| 419 | err_msg: | 393 | err_msg: |
| 420 | ib_free_send_mad(packet->msg); | 394 | ib_free_send_mad(packet->msg); |
| @@ -564,12 +538,10 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
| 564 | container_of(inode->i_cdev, struct ib_umad_port, dev); | 538 | container_of(inode->i_cdev, struct ib_umad_port, dev); |
| 565 | struct ib_umad_file *file; | 539 | struct ib_umad_file *file; |
| 566 | 540 | ||
| 567 | file = kmalloc(sizeof *file, GFP_KERNEL); | 541 | file = kzalloc(sizeof *file, GFP_KERNEL); |
| 568 | if (!file) | 542 | if (!file) |
| 569 | return -ENOMEM; | 543 | return -ENOMEM; |
| 570 | 544 | ||
| 571 | memset(file, 0, sizeof *file); | ||
| 572 | |||
| 573 | spin_lock_init(&file->recv_lock); | 545 | spin_lock_init(&file->recv_lock); |
| 574 | init_rwsem(&file->agent_mutex); | 546 | init_rwsem(&file->agent_mutex); |
| 575 | INIT_LIST_HEAD(&file->recv_list); | 547 | INIT_LIST_HEAD(&file->recv_list); |
| @@ -814,15 +786,12 @@ static void ib_umad_add_one(struct ib_device *device) | |||
| 814 | e = device->phys_port_cnt; | 786 | e = device->phys_port_cnt; |
| 815 | } | 787 | } |
| 816 | 788 | ||
| 817 | umad_dev = kmalloc(sizeof *umad_dev + | 789 | umad_dev = kzalloc(sizeof *umad_dev + |
| 818 | (e - s + 1) * sizeof (struct ib_umad_port), | 790 | (e - s + 1) * sizeof (struct ib_umad_port), |
| 819 | GFP_KERNEL); | 791 | GFP_KERNEL); |
| 820 | if (!umad_dev) | 792 | if (!umad_dev) |
| 821 | return; | 793 | return; |
| 822 | 794 | ||
| 823 | memset(umad_dev, 0, sizeof *umad_dev + | ||
| 824 | (e - s + 1) * sizeof (struct ib_umad_port)); | ||
| 825 | |||
| 826 | kref_init(&umad_dev->ref); | 795 | kref_init(&umad_dev->ref); |
| 827 | 796 | ||
| 828 | umad_dev->start_port = s; | 797 | umad_dev->start_port = s; |
