.. | .. |
---|
| 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 | |
---|