| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * VMware VMCI Driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2012 VMware, Inc. All rights reserved. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 8 | | - * Free Software Foundation version 2 and no later version. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|---|
| 12 | | - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|---|
| 13 | | - * for more details. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | |
|---|
| 16 | 8 | #include <linux/vmw_vmci_defs.h> |
|---|
| .. | .. |
|---|
| 435 | 427 | void *cons_q, |
|---|
| 436 | 428 | u64 num_consume_pages, struct ppn_set *ppn_set) |
|---|
| 437 | 429 | { |
|---|
| 438 | | - u32 *produce_ppns; |
|---|
| 439 | | - u32 *consume_ppns; |
|---|
| 430 | + u64 *produce_ppns; |
|---|
| 431 | + u64 *consume_ppns; |
|---|
| 440 | 432 | struct vmci_queue *produce_q = prod_q; |
|---|
| 441 | 433 | struct vmci_queue *consume_q = cons_q; |
|---|
| 442 | 434 | u64 i; |
|---|
| .. | .. |
|---|
| 462 | 454 | return VMCI_ERROR_NO_MEM; |
|---|
| 463 | 455 | } |
|---|
| 464 | 456 | |
|---|
| 465 | | - for (i = 0; i < num_produce_pages; i++) { |
|---|
| 466 | | - unsigned long pfn; |
|---|
| 467 | | - |
|---|
| 457 | + for (i = 0; i < num_produce_pages; i++) |
|---|
| 468 | 458 | produce_ppns[i] = |
|---|
| 469 | 459 | produce_q->kernel_if->u.g.pas[i] >> PAGE_SHIFT; |
|---|
| 470 | | - pfn = produce_ppns[i]; |
|---|
| 471 | 460 | |
|---|
| 472 | | - /* Fail allocation if PFN isn't supported by hypervisor. */ |
|---|
| 473 | | - if (sizeof(pfn) > sizeof(*produce_ppns) |
|---|
| 474 | | - && pfn != produce_ppns[i]) |
|---|
| 475 | | - goto ppn_error; |
|---|
| 476 | | - } |
|---|
| 477 | | - |
|---|
| 478 | | - for (i = 0; i < num_consume_pages; i++) { |
|---|
| 479 | | - unsigned long pfn; |
|---|
| 480 | | - |
|---|
| 461 | + for (i = 0; i < num_consume_pages; i++) |
|---|
| 481 | 462 | consume_ppns[i] = |
|---|
| 482 | 463 | consume_q->kernel_if->u.g.pas[i] >> PAGE_SHIFT; |
|---|
| 483 | | - pfn = consume_ppns[i]; |
|---|
| 484 | | - |
|---|
| 485 | | - /* Fail allocation if PFN isn't supported by hypervisor. */ |
|---|
| 486 | | - if (sizeof(pfn) > sizeof(*consume_ppns) |
|---|
| 487 | | - && pfn != consume_ppns[i]) |
|---|
| 488 | | - goto ppn_error; |
|---|
| 489 | | - } |
|---|
| 490 | 464 | |
|---|
| 491 | 465 | ppn_set->num_produce_pages = num_produce_pages; |
|---|
| 492 | 466 | ppn_set->num_consume_pages = num_consume_pages; |
|---|
| .. | .. |
|---|
| 494 | 468 | ppn_set->consume_ppns = consume_ppns; |
|---|
| 495 | 469 | ppn_set->initialized = true; |
|---|
| 496 | 470 | return VMCI_SUCCESS; |
|---|
| 497 | | - |
|---|
| 498 | | - ppn_error: |
|---|
| 499 | | - kfree(produce_ppns); |
|---|
| 500 | | - kfree(consume_ppns); |
|---|
| 501 | | - return VMCI_ERROR_INVALID_ARGS; |
|---|
| 502 | 471 | } |
|---|
| 503 | 472 | |
|---|
| 504 | 473 | /* |
|---|
| .. | .. |
|---|
| 520 | 489 | */ |
|---|
| 521 | 490 | static int qp_populate_ppn_set(u8 *call_buf, const struct ppn_set *ppn_set) |
|---|
| 522 | 491 | { |
|---|
| 523 | | - memcpy(call_buf, ppn_set->produce_ppns, |
|---|
| 524 | | - ppn_set->num_produce_pages * sizeof(*ppn_set->produce_ppns)); |
|---|
| 525 | | - memcpy(call_buf + |
|---|
| 526 | | - ppn_set->num_produce_pages * sizeof(*ppn_set->produce_ppns), |
|---|
| 527 | | - ppn_set->consume_ppns, |
|---|
| 528 | | - ppn_set->num_consume_pages * sizeof(*ppn_set->consume_ppns)); |
|---|
| 492 | + if (vmci_use_ppn64()) { |
|---|
| 493 | + memcpy(call_buf, ppn_set->produce_ppns, |
|---|
| 494 | + ppn_set->num_produce_pages * |
|---|
| 495 | + sizeof(*ppn_set->produce_ppns)); |
|---|
| 496 | + memcpy(call_buf + |
|---|
| 497 | + ppn_set->num_produce_pages * |
|---|
| 498 | + sizeof(*ppn_set->produce_ppns), |
|---|
| 499 | + ppn_set->consume_ppns, |
|---|
| 500 | + ppn_set->num_consume_pages * |
|---|
| 501 | + sizeof(*ppn_set->consume_ppns)); |
|---|
| 502 | + } else { |
|---|
| 503 | + int i; |
|---|
| 504 | + u32 *ppns = (u32 *) call_buf; |
|---|
| 505 | + |
|---|
| 506 | + for (i = 0; i < ppn_set->num_produce_pages; i++) |
|---|
| 507 | + ppns[i] = (u32) ppn_set->produce_ppns[i]; |
|---|
| 508 | + |
|---|
| 509 | + ppns = &ppns[ppn_set->num_produce_pages]; |
|---|
| 510 | + |
|---|
| 511 | + for (i = 0; i < ppn_set->num_consume_pages; i++) |
|---|
| 512 | + ppns[i] = (u32) ppn_set->consume_ppns[i]; |
|---|
| 513 | + } |
|---|
| 529 | 514 | |
|---|
| 530 | 515 | return VMCI_SUCCESS; |
|---|
| 531 | 516 | } |
|---|
| .. | .. |
|---|
| 669 | 654 | int err = VMCI_SUCCESS; |
|---|
| 670 | 655 | |
|---|
| 671 | 656 | retval = get_user_pages_fast((uintptr_t) produce_uva, |
|---|
| 672 | | - produce_q->kernel_if->num_pages, 1, |
|---|
| 657 | + produce_q->kernel_if->num_pages, |
|---|
| 658 | + FOLL_WRITE, |
|---|
| 673 | 659 | produce_q->kernel_if->u.h.header_page); |
|---|
| 674 | 660 | if (retval < (int)produce_q->kernel_if->num_pages) { |
|---|
| 675 | 661 | pr_debug("get_user_pages_fast(produce) failed (retval=%d)", |
|---|
| .. | .. |
|---|
| 682 | 668 | } |
|---|
| 683 | 669 | |
|---|
| 684 | 670 | retval = get_user_pages_fast((uintptr_t) consume_uva, |
|---|
| 685 | | - consume_q->kernel_if->num_pages, 1, |
|---|
| 671 | + consume_q->kernel_if->num_pages, |
|---|
| 672 | + FOLL_WRITE, |
|---|
| 686 | 673 | consume_q->kernel_if->u.h.header_page); |
|---|
| 687 | 674 | if (retval < (int)consume_q->kernel_if->num_pages) { |
|---|
| 688 | 675 | pr_debug("get_user_pages_fast(consume) failed (retval=%d)", |
|---|
| .. | .. |
|---|
| 865 | 852 | u32 context_id = vmci_get_context_id(); |
|---|
| 866 | 853 | struct vmci_event_qp ev; |
|---|
| 867 | 854 | |
|---|
| 855 | + memset(&ev, 0, sizeof(ev)); |
|---|
| 868 | 856 | ev.msg.hdr.dst = vmci_make_handle(context_id, VMCI_EVENT_HANDLER); |
|---|
| 869 | 857 | ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, |
|---|
| 870 | 858 | VMCI_CONTEXT_RESOURCE_ID); |
|---|
| .. | .. |
|---|
| 956 | 944 | { |
|---|
| 957 | 945 | struct vmci_qp_alloc_msg *alloc_msg; |
|---|
| 958 | 946 | size_t msg_size; |
|---|
| 947 | + size_t ppn_size; |
|---|
| 959 | 948 | int result; |
|---|
| 960 | 949 | |
|---|
| 961 | 950 | if (!entry || entry->num_ppns <= 2) |
|---|
| 962 | 951 | return VMCI_ERROR_INVALID_ARGS; |
|---|
| 963 | 952 | |
|---|
| 953 | + ppn_size = vmci_use_ppn64() ? sizeof(u64) : sizeof(u32); |
|---|
| 964 | 954 | msg_size = sizeof(*alloc_msg) + |
|---|
| 965 | | - (size_t) entry->num_ppns * sizeof(u32); |
|---|
| 955 | + (size_t) entry->num_ppns * ppn_size; |
|---|
| 966 | 956 | alloc_msg = kmalloc(msg_size, GFP_KERNEL); |
|---|
| 967 | 957 | if (!alloc_msg) |
|---|
| 968 | 958 | return VMCI_ERROR_NO_MEM; |
|---|
| .. | .. |
|---|
| 1476 | 1466 | * kernel. |
|---|
| 1477 | 1467 | */ |
|---|
| 1478 | 1468 | |
|---|
| 1469 | + memset(&ev, 0, sizeof(ev)); |
|---|
| 1479 | 1470 | ev.msg.hdr.dst = vmci_make_handle(peer_id, VMCI_EVENT_HANDLER); |
|---|
| 1480 | 1471 | ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, |
|---|
| 1481 | 1472 | VMCI_CONTEXT_RESOURCE_ID); |
|---|
| .. | .. |
|---|
| 3037 | 3028 | if (!qpair || !buf) |
|---|
| 3038 | 3029 | return VMCI_ERROR_INVALID_ARGS; |
|---|
| 3039 | 3030 | |
|---|
| 3040 | | - iov_iter_kvec(&from, WRITE | ITER_KVEC, &v, 1, buf_size); |
|---|
| 3031 | + iov_iter_kvec(&from, WRITE, &v, 1, buf_size); |
|---|
| 3041 | 3032 | |
|---|
| 3042 | 3033 | qp_lock(qpair); |
|---|
| 3043 | 3034 | |
|---|
| .. | .. |
|---|
| 3081 | 3072 | if (!qpair || !buf) |
|---|
| 3082 | 3073 | return VMCI_ERROR_INVALID_ARGS; |
|---|
| 3083 | 3074 | |
|---|
| 3084 | | - iov_iter_kvec(&to, READ | ITER_KVEC, &v, 1, buf_size); |
|---|
| 3075 | + iov_iter_kvec(&to, READ, &v, 1, buf_size); |
|---|
| 3085 | 3076 | |
|---|
| 3086 | 3077 | qp_lock(qpair); |
|---|
| 3087 | 3078 | |
|---|
| .. | .. |
|---|
| 3126 | 3117 | if (!qpair || !buf) |
|---|
| 3127 | 3118 | return VMCI_ERROR_INVALID_ARGS; |
|---|
| 3128 | 3119 | |
|---|
| 3129 | | - iov_iter_kvec(&to, READ | ITER_KVEC, &v, 1, buf_size); |
|---|
| 3120 | + iov_iter_kvec(&to, READ, &v, 1, buf_size); |
|---|
| 3130 | 3121 | |
|---|
| 3131 | 3122 | qp_lock(qpair); |
|---|
| 3132 | 3123 | |
|---|