.. | .. |
---|
7 | 7 | */ |
---|
8 | 8 | |
---|
9 | 9 | #include <linux/errno.h> |
---|
| 10 | +#include <linux/io.h> |
---|
10 | 11 | #include <linux/kernel.h> |
---|
11 | 12 | #include <linux/mm.h> |
---|
12 | 13 | #include <linux/module.h> |
---|
.. | .. |
---|
58 | 59 | VBG_LOG(vbg_info, pr_info); |
---|
59 | 60 | VBG_LOG(vbg_warn, pr_warn); |
---|
60 | 61 | VBG_LOG(vbg_err, pr_err); |
---|
| 62 | +VBG_LOG(vbg_err_ratelimited, pr_err_ratelimited); |
---|
61 | 63 | #if defined(DEBUG) && !defined(CONFIG_DYNAMIC_DEBUG) |
---|
62 | 64 | VBG_LOG(vbg_debug, pr_debug); |
---|
63 | 65 | #endif |
---|
64 | 66 | |
---|
65 | | -void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type) |
---|
| 67 | +void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type, |
---|
| 68 | + u32 requestor) |
---|
66 | 69 | { |
---|
67 | 70 | struct vmmdev_request_header *req; |
---|
68 | 71 | int order = get_order(PAGE_ALIGN(len)); |
---|
.. | .. |
---|
78 | 81 | req->request_type = req_type; |
---|
79 | 82 | req->rc = VERR_GENERAL_FAILURE; |
---|
80 | 83 | req->reserved1 = 0; |
---|
81 | | - req->reserved2 = 0; |
---|
| 84 | + req->requestor = requestor; |
---|
82 | 85 | |
---|
83 | 86 | return req; |
---|
84 | 87 | } |
---|
.. | .. |
---|
119 | 122 | return done; |
---|
120 | 123 | } |
---|
121 | 124 | |
---|
122 | | -int vbg_hgcm_connect(struct vbg_dev *gdev, |
---|
| 125 | +int vbg_hgcm_connect(struct vbg_dev *gdev, u32 requestor, |
---|
123 | 126 | struct vmmdev_hgcm_service_location *loc, |
---|
124 | 127 | u32 *client_id, int *vbox_status) |
---|
125 | 128 | { |
---|
.. | .. |
---|
127 | 130 | int rc; |
---|
128 | 131 | |
---|
129 | 132 | hgcm_connect = vbg_req_alloc(sizeof(*hgcm_connect), |
---|
130 | | - VMMDEVREQ_HGCM_CONNECT); |
---|
| 133 | + VMMDEVREQ_HGCM_CONNECT, requestor); |
---|
131 | 134 | if (!hgcm_connect) |
---|
132 | 135 | return -ENOMEM; |
---|
133 | 136 | |
---|
.. | .. |
---|
153 | 156 | } |
---|
154 | 157 | EXPORT_SYMBOL(vbg_hgcm_connect); |
---|
155 | 158 | |
---|
156 | | -int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 client_id, int *vbox_status) |
---|
| 159 | +int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 requestor, |
---|
| 160 | + u32 client_id, int *vbox_status) |
---|
157 | 161 | { |
---|
158 | 162 | struct vmmdev_hgcm_disconnect *hgcm_disconnect = NULL; |
---|
159 | 163 | int rc; |
---|
160 | 164 | |
---|
161 | 165 | hgcm_disconnect = vbg_req_alloc(sizeof(*hgcm_disconnect), |
---|
162 | | - VMMDEVREQ_HGCM_DISCONNECT); |
---|
| 166 | + VMMDEVREQ_HGCM_DISCONNECT, |
---|
| 167 | + requestor); |
---|
163 | 168 | if (!hgcm_disconnect) |
---|
164 | 169 | return -ENOMEM; |
---|
165 | 170 | |
---|
.. | .. |
---|
307 | 312 | switch (type) { |
---|
308 | 313 | default: |
---|
309 | 314 | WARN_ON(1); |
---|
310 | | - /* Fall through */ |
---|
| 315 | + fallthrough; |
---|
311 | 316 | case VMMDEV_HGCM_PARM_TYPE_LINADDR: |
---|
312 | 317 | case VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL: |
---|
313 | 318 | return VMMDEV_HGCM_F_PARM_DIRECTION_BOTH; |
---|
.. | .. |
---|
463 | 468 | * Cancellation fun. |
---|
464 | 469 | */ |
---|
465 | 470 | static int vbg_hgcm_do_call(struct vbg_dev *gdev, struct vmmdev_hgcm_call *call, |
---|
466 | | - u32 timeout_ms, bool *leak_it) |
---|
| 471 | + u32 timeout_ms, bool interruptible, bool *leak_it) |
---|
467 | 472 | { |
---|
468 | 473 | int rc, cancel_rc, ret; |
---|
469 | 474 | long timeout; |
---|
.. | .. |
---|
490 | 495 | else |
---|
491 | 496 | timeout = msecs_to_jiffies(timeout_ms); |
---|
492 | 497 | |
---|
493 | | - timeout = wait_event_interruptible_timeout( |
---|
494 | | - gdev->hgcm_wq, |
---|
495 | | - hgcm_req_done(gdev, &call->header), |
---|
496 | | - timeout); |
---|
| 498 | + if (interruptible) { |
---|
| 499 | + timeout = wait_event_interruptible_timeout(gdev->hgcm_wq, |
---|
| 500 | + hgcm_req_done(gdev, &call->header), |
---|
| 501 | + timeout); |
---|
| 502 | + } else { |
---|
| 503 | + timeout = wait_event_timeout(gdev->hgcm_wq, |
---|
| 504 | + hgcm_req_done(gdev, &call->header), |
---|
| 505 | + timeout); |
---|
| 506 | + } |
---|
497 | 507 | |
---|
498 | 508 | /* timeout > 0 means hgcm_req_done has returned true, so success */ |
---|
499 | 509 | if (timeout > 0) |
---|
.. | .. |
---|
594 | 604 | return 0; |
---|
595 | 605 | } |
---|
596 | 606 | |
---|
597 | | -int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function, |
---|
598 | | - u32 timeout_ms, struct vmmdev_hgcm_function_parameter *parms, |
---|
599 | | - u32 parm_count, int *vbox_status) |
---|
| 607 | +int vbg_hgcm_call(struct vbg_dev *gdev, u32 requestor, u32 client_id, |
---|
| 608 | + u32 function, u32 timeout_ms, |
---|
| 609 | + struct vmmdev_hgcm_function_parameter *parms, u32 parm_count, |
---|
| 610 | + int *vbox_status) |
---|
600 | 611 | { |
---|
601 | 612 | struct vmmdev_hgcm_call *call; |
---|
602 | 613 | void **bounce_bufs = NULL; |
---|
.. | .. |
---|
616 | 627 | goto free_bounce_bufs; |
---|
617 | 628 | } |
---|
618 | 629 | |
---|
619 | | - call = vbg_req_alloc(size, VMMDEVREQ_HGCM_CALL); |
---|
| 630 | + call = vbg_req_alloc(size, VMMDEVREQ_HGCM_CALL, requestor); |
---|
620 | 631 | if (!call) { |
---|
621 | 632 | ret = -ENOMEM; |
---|
622 | 633 | goto free_bounce_bufs; |
---|
.. | .. |
---|
625 | 636 | hgcm_call_init_call(call, client_id, function, parms, parm_count, |
---|
626 | 637 | bounce_bufs); |
---|
627 | 638 | |
---|
628 | | - ret = vbg_hgcm_do_call(gdev, call, timeout_ms, &leak_it); |
---|
| 639 | + ret = vbg_hgcm_do_call(gdev, call, timeout_ms, |
---|
| 640 | + requestor & VMMDEV_REQUESTOR_USERMODE, &leak_it); |
---|
629 | 641 | if (ret == 0) { |
---|
630 | 642 | *vbox_status = call->header.result; |
---|
631 | 643 | ret = hgcm_call_copy_back_result(call, parms, parm_count, |
---|
.. | .. |
---|
648 | 660 | |
---|
649 | 661 | #ifdef CONFIG_COMPAT |
---|
650 | 662 | int vbg_hgcm_call32( |
---|
651 | | - struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms, |
---|
652 | | - struct vmmdev_hgcm_function_parameter32 *parm32, u32 parm_count, |
---|
653 | | - int *vbox_status) |
---|
| 663 | + struct vbg_dev *gdev, u32 requestor, u32 client_id, u32 function, |
---|
| 664 | + u32 timeout_ms, struct vmmdev_hgcm_function_parameter32 *parm32, |
---|
| 665 | + u32 parm_count, int *vbox_status) |
---|
654 | 666 | { |
---|
655 | 667 | struct vmmdev_hgcm_function_parameter *parm64 = NULL; |
---|
656 | 668 | u32 i, size; |
---|
.. | .. |
---|
690 | 702 | goto out_free; |
---|
691 | 703 | } |
---|
692 | 704 | |
---|
693 | | - ret = vbg_hgcm_call(gdev, client_id, function, timeout_ms, |
---|
| 705 | + ret = vbg_hgcm_call(gdev, requestor, client_id, function, timeout_ms, |
---|
694 | 706 | parm64, parm_count, vbox_status); |
---|
695 | 707 | if (ret < 0) |
---|
696 | 708 | goto out_free; |
---|