.. | .. |
---|
50 | 50 | #include <rdma/ib_smi.h> |
---|
51 | 51 | #include <rdma/ib_user_verbs.h> |
---|
52 | 52 | #include <rdma/vmw_pvrdma-abi.h> |
---|
| 53 | +#include <rdma/uverbs_ioctl.h> |
---|
53 | 54 | |
---|
54 | 55 | #include "pvrdma.h" |
---|
55 | 56 | |
---|
.. | .. |
---|
69 | 70 | |
---|
70 | 71 | if (uhw->inlen || uhw->outlen) |
---|
71 | 72 | return -EINVAL; |
---|
72 | | - |
---|
73 | | - memset(props, 0, sizeof(*props)); |
---|
74 | 73 | |
---|
75 | 74 | props->fw_ver = dev->dsr->caps.fw_ver; |
---|
76 | 75 | props->sys_image_guid = dev->dsr->caps.sys_image_guid; |
---|
.. | .. |
---|
306 | 305 | |
---|
307 | 306 | /** |
---|
308 | 307 | * pvrdma_alloc_ucontext - allocate ucontext |
---|
309 | | - * @ibdev: the IB device |
---|
| 308 | + * @uctx: the uverbs countext |
---|
310 | 309 | * @udata: user data |
---|
311 | 310 | * |
---|
312 | | - * @return: the ib_ucontext pointer on success, otherwise errno. |
---|
| 311 | + * @return: zero on success, otherwise errno. |
---|
313 | 312 | */ |
---|
314 | | -struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev, |
---|
315 | | - struct ib_udata *udata) |
---|
| 313 | +int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) |
---|
316 | 314 | { |
---|
| 315 | + struct ib_device *ibdev = uctx->device; |
---|
317 | 316 | struct pvrdma_dev *vdev = to_vdev(ibdev); |
---|
318 | | - struct pvrdma_ucontext *context; |
---|
319 | | - union pvrdma_cmd_req req; |
---|
320 | | - union pvrdma_cmd_resp rsp; |
---|
| 317 | + struct pvrdma_ucontext *context = to_vucontext(uctx); |
---|
| 318 | + union pvrdma_cmd_req req = {}; |
---|
| 319 | + union pvrdma_cmd_resp rsp = {}; |
---|
321 | 320 | struct pvrdma_cmd_create_uc *cmd = &req.create_uc; |
---|
322 | 321 | struct pvrdma_cmd_create_uc_resp *resp = &rsp.create_uc_resp; |
---|
323 | | - struct pvrdma_alloc_ucontext_resp uresp = {0}; |
---|
| 322 | + struct pvrdma_alloc_ucontext_resp uresp = {}; |
---|
324 | 323 | int ret; |
---|
325 | | - void *ptr; |
---|
326 | 324 | |
---|
327 | 325 | if (!vdev->ib_active) |
---|
328 | | - return ERR_PTR(-EAGAIN); |
---|
329 | | - |
---|
330 | | - context = kmalloc(sizeof(*context), GFP_KERNEL); |
---|
331 | | - if (!context) |
---|
332 | | - return ERR_PTR(-ENOMEM); |
---|
| 326 | + return -EAGAIN; |
---|
333 | 327 | |
---|
334 | 328 | context->dev = vdev; |
---|
335 | 329 | ret = pvrdma_uar_alloc(vdev, &context->uar); |
---|
336 | | - if (ret) { |
---|
337 | | - kfree(context); |
---|
338 | | - return ERR_PTR(-ENOMEM); |
---|
339 | | - } |
---|
| 330 | + if (ret) |
---|
| 331 | + return -ENOMEM; |
---|
340 | 332 | |
---|
341 | 333 | /* get ctx_handle from host */ |
---|
342 | | - memset(cmd, 0, sizeof(*cmd)); |
---|
343 | | - cmd->pfn = context->uar.pfn; |
---|
| 334 | + if (vdev->dsr_version < PVRDMA_PPN64_VERSION) |
---|
| 335 | + cmd->pfn = context->uar.pfn; |
---|
| 336 | + else |
---|
| 337 | + cmd->pfn64 = context->uar.pfn; |
---|
| 338 | + |
---|
344 | 339 | cmd->hdr.cmd = PVRDMA_CMD_CREATE_UC; |
---|
345 | 340 | ret = pvrdma_cmd_post(vdev, &req, &rsp, PVRDMA_CMD_CREATE_UC_RESP); |
---|
346 | 341 | if (ret < 0) { |
---|
347 | 342 | dev_warn(&vdev->pdev->dev, |
---|
348 | 343 | "could not create ucontext, error: %d\n", ret); |
---|
349 | | - ptr = ERR_PTR(ret); |
---|
350 | 344 | goto err; |
---|
351 | 345 | } |
---|
352 | 346 | |
---|
.. | .. |
---|
357 | 351 | ret = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); |
---|
358 | 352 | if (ret) { |
---|
359 | 353 | pvrdma_uar_free(vdev, &context->uar); |
---|
360 | | - context->ibucontext.device = ibdev; |
---|
361 | 354 | pvrdma_dealloc_ucontext(&context->ibucontext); |
---|
362 | | - return ERR_PTR(-EFAULT); |
---|
| 355 | + return -EFAULT; |
---|
363 | 356 | } |
---|
364 | 357 | |
---|
365 | | - return &context->ibucontext; |
---|
| 358 | + return 0; |
---|
366 | 359 | |
---|
367 | 360 | err: |
---|
368 | 361 | pvrdma_uar_free(vdev, &context->uar); |
---|
369 | | - kfree(context); |
---|
370 | | - return ptr; |
---|
| 362 | + return ret; |
---|
371 | 363 | } |
---|
372 | 364 | |
---|
373 | 365 | /** |
---|
374 | 366 | * pvrdma_dealloc_ucontext - deallocate ucontext |
---|
375 | 367 | * @ibcontext: the ucontext |
---|
376 | | - * |
---|
377 | | - * @return: 0 on success, otherwise errno. |
---|
378 | 368 | */ |
---|
379 | | -int pvrdma_dealloc_ucontext(struct ib_ucontext *ibcontext) |
---|
| 369 | +void pvrdma_dealloc_ucontext(struct ib_ucontext *ibcontext) |
---|
380 | 370 | { |
---|
381 | 371 | struct pvrdma_ucontext *context = to_vucontext(ibcontext); |
---|
382 | | - union pvrdma_cmd_req req; |
---|
| 372 | + union pvrdma_cmd_req req = {}; |
---|
383 | 373 | struct pvrdma_cmd_destroy_uc *cmd = &req.destroy_uc; |
---|
384 | 374 | int ret; |
---|
385 | 375 | |
---|
386 | | - memset(cmd, 0, sizeof(*cmd)); |
---|
387 | 376 | cmd->hdr.cmd = PVRDMA_CMD_DESTROY_UC; |
---|
388 | 377 | cmd->ctx_handle = context->ctx_handle; |
---|
389 | 378 | |
---|
.. | .. |
---|
394 | 383 | |
---|
395 | 384 | /* Free the UAR even if the device command failed */ |
---|
396 | 385 | pvrdma_uar_free(to_vdev(ibcontext->device), &context->uar); |
---|
397 | | - kfree(context); |
---|
398 | | - |
---|
399 | | - return ret; |
---|
400 | 386 | } |
---|
401 | 387 | |
---|
402 | 388 | /** |
---|
.. | .. |
---|
433 | 419 | |
---|
434 | 420 | /** |
---|
435 | 421 | * pvrdma_alloc_pd - allocate protection domain |
---|
436 | | - * @ibdev: the IB device |
---|
437 | | - * @context: user context |
---|
| 422 | + * @ibpd: PD pointer |
---|
438 | 423 | * @udata: user data |
---|
439 | 424 | * |
---|
440 | 425 | * @return: the ib_pd protection domain pointer on success, otherwise errno. |
---|
441 | 426 | */ |
---|
442 | | -struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev, |
---|
443 | | - struct ib_ucontext *context, |
---|
444 | | - struct ib_udata *udata) |
---|
| 427 | +int pvrdma_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) |
---|
445 | 428 | { |
---|
446 | | - struct pvrdma_pd *pd; |
---|
| 429 | + struct ib_device *ibdev = ibpd->device; |
---|
| 430 | + struct pvrdma_pd *pd = to_vpd(ibpd); |
---|
447 | 431 | struct pvrdma_dev *dev = to_vdev(ibdev); |
---|
448 | | - union pvrdma_cmd_req req; |
---|
449 | | - union pvrdma_cmd_resp rsp; |
---|
| 432 | + union pvrdma_cmd_req req = {}; |
---|
| 433 | + union pvrdma_cmd_resp rsp = {}; |
---|
450 | 434 | struct pvrdma_cmd_create_pd *cmd = &req.create_pd; |
---|
451 | 435 | struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp; |
---|
452 | 436 | struct pvrdma_alloc_pd_resp pd_resp = {0}; |
---|
453 | 437 | int ret; |
---|
454 | | - void *ptr; |
---|
| 438 | + struct pvrdma_ucontext *context = rdma_udata_to_drv_context( |
---|
| 439 | + udata, struct pvrdma_ucontext, ibucontext); |
---|
455 | 440 | |
---|
456 | 441 | /* Check allowed max pds */ |
---|
457 | 442 | if (!atomic_add_unless(&dev->num_pds, 1, dev->dsr->caps.max_pd)) |
---|
458 | | - return ERR_PTR(-ENOMEM); |
---|
| 443 | + return -ENOMEM; |
---|
459 | 444 | |
---|
460 | | - pd = kmalloc(sizeof(*pd), GFP_KERNEL); |
---|
461 | | - if (!pd) { |
---|
462 | | - ptr = ERR_PTR(-ENOMEM); |
---|
463 | | - goto err; |
---|
464 | | - } |
---|
465 | | - |
---|
466 | | - memset(cmd, 0, sizeof(*cmd)); |
---|
467 | 445 | cmd->hdr.cmd = PVRDMA_CMD_CREATE_PD; |
---|
468 | | - cmd->ctx_handle = (context) ? to_vucontext(context)->ctx_handle : 0; |
---|
| 446 | + cmd->ctx_handle = context ? context->ctx_handle : 0; |
---|
469 | 447 | ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_PD_RESP); |
---|
470 | 448 | if (ret < 0) { |
---|
471 | 449 | dev_warn(&dev->pdev->dev, |
---|
472 | 450 | "failed to allocate protection domain, error: %d\n", |
---|
473 | 451 | ret); |
---|
474 | | - ptr = ERR_PTR(ret); |
---|
475 | | - goto freepd; |
---|
| 452 | + goto err; |
---|
476 | 453 | } |
---|
477 | 454 | |
---|
478 | | - pd->privileged = !context; |
---|
| 455 | + pd->privileged = !udata; |
---|
479 | 456 | pd->pd_handle = resp->pd_handle; |
---|
480 | 457 | pd->pdn = resp->pd_handle; |
---|
481 | 458 | pd_resp.pdn = resp->pd_handle; |
---|
482 | 459 | |
---|
483 | | - if (context) { |
---|
| 460 | + if (udata) { |
---|
484 | 461 | if (ib_copy_to_udata(udata, &pd_resp, sizeof(pd_resp))) { |
---|
485 | 462 | dev_warn(&dev->pdev->dev, |
---|
486 | 463 | "failed to copy back protection domain\n"); |
---|
487 | | - pvrdma_dealloc_pd(&pd->ibpd); |
---|
488 | | - return ERR_PTR(-EFAULT); |
---|
| 464 | + pvrdma_dealloc_pd(&pd->ibpd, udata); |
---|
| 465 | + return -EFAULT; |
---|
489 | 466 | } |
---|
490 | 467 | } |
---|
491 | 468 | |
---|
492 | 469 | /* u32 pd handle */ |
---|
493 | | - return &pd->ibpd; |
---|
| 470 | + return 0; |
---|
494 | 471 | |
---|
495 | | -freepd: |
---|
496 | | - kfree(pd); |
---|
497 | 472 | err: |
---|
498 | 473 | atomic_dec(&dev->num_pds); |
---|
499 | | - return ptr; |
---|
| 474 | + return ret; |
---|
500 | 475 | } |
---|
501 | 476 | |
---|
502 | 477 | /** |
---|
503 | 478 | * pvrdma_dealloc_pd - deallocate protection domain |
---|
504 | 479 | * @pd: the protection domain to be released |
---|
| 480 | + * @udata: user data or null for kernel object |
---|
505 | 481 | * |
---|
506 | | - * @return: 0 on success, otherwise errno. |
---|
| 482 | + * @return: Always 0 |
---|
507 | 483 | */ |
---|
508 | | -int pvrdma_dealloc_pd(struct ib_pd *pd) |
---|
| 484 | +int pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) |
---|
509 | 485 | { |
---|
510 | 486 | struct pvrdma_dev *dev = to_vdev(pd->device); |
---|
511 | | - union pvrdma_cmd_req req; |
---|
| 487 | + union pvrdma_cmd_req req = {}; |
---|
512 | 488 | struct pvrdma_cmd_destroy_pd *cmd = &req.destroy_pd; |
---|
513 | 489 | int ret; |
---|
514 | 490 | |
---|
515 | | - memset(cmd, 0, sizeof(*cmd)); |
---|
516 | 491 | cmd->hdr.cmd = PVRDMA_CMD_DESTROY_PD; |
---|
517 | 492 | cmd->pd_handle = to_vpd(pd)->pd_handle; |
---|
518 | 493 | |
---|
.. | .. |
---|
522 | 497 | "could not dealloc protection domain, error: %d\n", |
---|
523 | 498 | ret); |
---|
524 | 499 | |
---|
525 | | - kfree(to_vpd(pd)); |
---|
526 | 500 | atomic_dec(&dev->num_pds); |
---|
527 | | - |
---|
528 | 501 | return 0; |
---|
529 | 502 | } |
---|
530 | 503 | |
---|
531 | 504 | /** |
---|
532 | 505 | * pvrdma_create_ah - create an address handle |
---|
533 | | - * @pd: the protection domain |
---|
534 | | - * @ah_attr: the attributes of the AH |
---|
535 | | - * @udata: user data blob |
---|
| 506 | + * @ibah: the IB address handle |
---|
| 507 | + * @init_attr: the attributes of the AH |
---|
| 508 | + * @udata: pointer to user data |
---|
536 | 509 | * |
---|
537 | | - * @return: the ib_ah pointer on success, otherwise errno. |
---|
| 510 | + * @return: 0 on success, otherwise errno. |
---|
538 | 511 | */ |
---|
539 | | -struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, |
---|
540 | | - struct ib_udata *udata) |
---|
| 512 | +int pvrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, |
---|
| 513 | + struct ib_udata *udata) |
---|
541 | 514 | { |
---|
542 | | - struct pvrdma_dev *dev = to_vdev(pd->device); |
---|
543 | | - struct pvrdma_ah *ah; |
---|
| 515 | + struct rdma_ah_attr *ah_attr = init_attr->ah_attr; |
---|
| 516 | + struct pvrdma_dev *dev = to_vdev(ibah->device); |
---|
| 517 | + struct pvrdma_ah *ah = to_vah(ibah); |
---|
544 | 518 | const struct ib_global_route *grh; |
---|
545 | 519 | u8 port_num = rdma_ah_get_port_num(ah_attr); |
---|
546 | 520 | |
---|
547 | 521 | if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) |
---|
548 | | - return ERR_PTR(-EINVAL); |
---|
| 522 | + return -EINVAL; |
---|
549 | 523 | |
---|
550 | 524 | grh = rdma_ah_read_grh(ah_attr); |
---|
551 | 525 | if ((ah_attr->type != RDMA_AH_ATTR_TYPE_ROCE) || |
---|
552 | 526 | rdma_is_multicast_addr((struct in6_addr *)grh->dgid.raw)) |
---|
553 | | - return ERR_PTR(-EINVAL); |
---|
| 527 | + return -EINVAL; |
---|
554 | 528 | |
---|
555 | 529 | if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah)) |
---|
556 | | - return ERR_PTR(-ENOMEM); |
---|
| 530 | + return -ENOMEM; |
---|
557 | 531 | |
---|
558 | | - ah = kzalloc(sizeof(*ah), GFP_ATOMIC); |
---|
559 | | - if (!ah) { |
---|
560 | | - atomic_dec(&dev->num_ahs); |
---|
561 | | - return ERR_PTR(-ENOMEM); |
---|
562 | | - } |
---|
563 | | - |
---|
564 | | - ah->av.port_pd = to_vpd(pd)->pd_handle | (port_num << 24); |
---|
| 532 | + ah->av.port_pd = to_vpd(ibah->pd)->pd_handle | (port_num << 24); |
---|
565 | 533 | ah->av.src_path_bits = rdma_ah_get_path_bits(ah_attr); |
---|
566 | 534 | ah->av.src_path_bits |= 0x80; |
---|
567 | 535 | ah->av.gid_index = grh->sgid_index; |
---|
.. | .. |
---|
571 | 539 | memcpy(ah->av.dgid, grh->dgid.raw, 16); |
---|
572 | 540 | memcpy(ah->av.dmac, ah_attr->roce.dmac, ETH_ALEN); |
---|
573 | 541 | |
---|
574 | | - ah->ibah.device = pd->device; |
---|
575 | | - ah->ibah.pd = pd; |
---|
576 | | - ah->ibah.uobject = NULL; |
---|
577 | | - |
---|
578 | | - return &ah->ibah; |
---|
| 542 | + return 0; |
---|
579 | 543 | } |
---|
580 | 544 | |
---|
581 | 545 | /** |
---|
582 | 546 | * pvrdma_destroy_ah - destroy an address handle |
---|
583 | 547 | * @ah: the address handle to destroyed |
---|
| 548 | + * @flags: destroy address handle flags (see enum rdma_destroy_ah_flags) |
---|
584 | 549 | * |
---|
585 | | - * @return: 0 on success. |
---|
586 | 550 | */ |
---|
587 | | -int pvrdma_destroy_ah(struct ib_ah *ah) |
---|
| 551 | +int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags) |
---|
588 | 552 | { |
---|
589 | 553 | struct pvrdma_dev *dev = to_vdev(ah->device); |
---|
590 | 554 | |
---|
591 | | - kfree(to_vah(ah)); |
---|
592 | 555 | atomic_dec(&dev->num_ahs); |
---|
593 | | - |
---|
594 | 556 | return 0; |
---|
595 | 557 | } |
---|