diff options
author | Hans de Goede <hdegoede@redhat.com> | 2018-04-18 09:24:48 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-04-23 07:41:55 -0400 |
commit | f6f9885b0531163f72c7bf898a0ab1ba4c7d5de6 (patch) | |
tree | dd2cc4cab83c58a8943ffa8357a3fbe3e969c7aa /drivers | |
parent | 02cfde67df1f440c7c3c7038cc97992afb81804f (diff) |
virt: vbox: Add vbg_req_free() helper function
This is a preparation patch for fixing issues on x86_64 virtual-machines
with more then 4G of RAM, atm we pass __GFP_DMA32 to kmalloc, but kmalloc
does not honor that, so we need to switch to get_pages, which means we
will not be able to use kfree to free memory allocated with vbg_alloc_req.
While at it also remove a comment on a vbg_alloc_req call which talks
about Windows (inherited from the vbox upstream cross-platform code).
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/virt/vboxguest/vboxguest_core.c | 66 | ||||
-rw-r--r-- | drivers/virt/vboxguest/vboxguest_core.h | 1 | ||||
-rw-r--r-- | drivers/virt/vboxguest/vboxguest_utils.c | 14 |
3 files changed, 47 insertions, 34 deletions
diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c index 190dbf8cfcb5..7411a535fda2 100644 --- a/drivers/virt/vboxguest/vboxguest_core.c +++ b/drivers/virt/vboxguest/vboxguest_core.c | |||
@@ -114,7 +114,7 @@ static void vbg_guest_mappings_init(struct vbg_dev *gdev) | |||
114 | } | 114 | } |
115 | 115 | ||
116 | out: | 116 | out: |
117 | kfree(req); | 117 | vbg_req_free(req, sizeof(*req)); |
118 | kfree(pages); | 118 | kfree(pages); |
119 | } | 119 | } |
120 | 120 | ||
@@ -144,7 +144,7 @@ static void vbg_guest_mappings_exit(struct vbg_dev *gdev) | |||
144 | 144 | ||
145 | rc = vbg_req_perform(gdev, req); | 145 | rc = vbg_req_perform(gdev, req); |
146 | 146 | ||
147 | kfree(req); | 147 | vbg_req_free(req, sizeof(*req)); |
148 | 148 | ||
149 | if (rc < 0) { | 149 | if (rc < 0) { |
150 | vbg_err("%s error: %d\n", __func__, rc); | 150 | vbg_err("%s error: %d\n", __func__, rc); |
@@ -214,8 +214,8 @@ static int vbg_report_guest_info(struct vbg_dev *gdev) | |||
214 | ret = vbg_status_code_to_errno(rc); | 214 | ret = vbg_status_code_to_errno(rc); |
215 | 215 | ||
216 | out_free: | 216 | out_free: |
217 | kfree(req2); | 217 | vbg_req_free(req2, sizeof(*req2)); |
218 | kfree(req1); | 218 | vbg_req_free(req1, sizeof(*req1)); |
219 | return ret; | 219 | return ret; |
220 | } | 220 | } |
221 | 221 | ||
@@ -245,7 +245,7 @@ static int vbg_report_driver_status(struct vbg_dev *gdev, bool active) | |||
245 | if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */ | 245 | if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */ |
246 | rc = VINF_SUCCESS; | 246 | rc = VINF_SUCCESS; |
247 | 247 | ||
248 | kfree(req); | 248 | vbg_req_free(req, sizeof(*req)); |
249 | 249 | ||
250 | return vbg_status_code_to_errno(rc); | 250 | return vbg_status_code_to_errno(rc); |
251 | } | 251 | } |
@@ -431,7 +431,7 @@ static int vbg_heartbeat_host_config(struct vbg_dev *gdev, bool enabled) | |||
431 | rc = vbg_req_perform(gdev, req); | 431 | rc = vbg_req_perform(gdev, req); |
432 | do_div(req->interval_ns, 1000000); /* ns -> ms */ | 432 | do_div(req->interval_ns, 1000000); /* ns -> ms */ |
433 | gdev->heartbeat_interval_ms = req->interval_ns; | 433 | gdev->heartbeat_interval_ms = req->interval_ns; |
434 | kfree(req); | 434 | vbg_req_free(req, sizeof(*req)); |
435 | 435 | ||
436 | return vbg_status_code_to_errno(rc); | 436 | return vbg_status_code_to_errno(rc); |
437 | } | 437 | } |
@@ -454,12 +454,6 @@ static int vbg_heartbeat_init(struct vbg_dev *gdev) | |||
454 | if (ret < 0) | 454 | if (ret < 0) |
455 | return ret; | 455 | return ret; |
456 | 456 | ||
457 | /* | ||
458 | * Preallocate the request to use it from the timer callback because: | ||
459 | * 1) on Windows vbg_req_alloc must be called at IRQL <= APC_LEVEL | ||
460 | * and the timer callback runs at DISPATCH_LEVEL; | ||
461 | * 2) avoid repeated allocations. | ||
462 | */ | ||
463 | gdev->guest_heartbeat_req = vbg_req_alloc( | 457 | gdev->guest_heartbeat_req = vbg_req_alloc( |
464 | sizeof(*gdev->guest_heartbeat_req), | 458 | sizeof(*gdev->guest_heartbeat_req), |
465 | VMMDEVREQ_GUEST_HEARTBEAT); | 459 | VMMDEVREQ_GUEST_HEARTBEAT); |
@@ -481,8 +475,8 @@ static void vbg_heartbeat_exit(struct vbg_dev *gdev) | |||
481 | { | 475 | { |
482 | del_timer_sync(&gdev->heartbeat_timer); | 476 | del_timer_sync(&gdev->heartbeat_timer); |
483 | vbg_heartbeat_host_config(gdev, false); | 477 | vbg_heartbeat_host_config(gdev, false); |
484 | kfree(gdev->guest_heartbeat_req); | 478 | vbg_req_free(gdev->guest_heartbeat_req, |
485 | 479 | sizeof(*gdev->guest_heartbeat_req)); | |
486 | } | 480 | } |
487 | 481 | ||
488 | /** | 482 | /** |
@@ -543,7 +537,7 @@ static int vbg_reset_host_event_filter(struct vbg_dev *gdev, | |||
543 | if (rc < 0) | 537 | if (rc < 0) |
544 | vbg_err("%s error, rc: %d\n", __func__, rc); | 538 | vbg_err("%s error, rc: %d\n", __func__, rc); |
545 | 539 | ||
546 | kfree(req); | 540 | vbg_req_free(req, sizeof(*req)); |
547 | return vbg_status_code_to_errno(rc); | 541 | return vbg_status_code_to_errno(rc); |
548 | } | 542 | } |
549 | 543 | ||
@@ -617,7 +611,7 @@ static int vbg_set_session_event_filter(struct vbg_dev *gdev, | |||
617 | 611 | ||
618 | out: | 612 | out: |
619 | mutex_unlock(&gdev->session_mutex); | 613 | mutex_unlock(&gdev->session_mutex); |
620 | kfree(req); | 614 | vbg_req_free(req, sizeof(*req)); |
621 | 615 | ||
622 | return ret; | 616 | return ret; |
623 | } | 617 | } |
@@ -642,7 +636,7 @@ static int vbg_reset_host_capabilities(struct vbg_dev *gdev) | |||
642 | if (rc < 0) | 636 | if (rc < 0) |
643 | vbg_err("%s error, rc: %d\n", __func__, rc); | 637 | vbg_err("%s error, rc: %d\n", __func__, rc); |
644 | 638 | ||
645 | kfree(req); | 639 | vbg_req_free(req, sizeof(*req)); |
646 | return vbg_status_code_to_errno(rc); | 640 | return vbg_status_code_to_errno(rc); |
647 | } | 641 | } |
648 | 642 | ||
@@ -712,7 +706,7 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev, | |||
712 | 706 | ||
713 | out: | 707 | out: |
714 | mutex_unlock(&gdev->session_mutex); | 708 | mutex_unlock(&gdev->session_mutex); |
715 | kfree(req); | 709 | vbg_req_free(req, sizeof(*req)); |
716 | 710 | ||
717 | return ret; | 711 | return ret; |
718 | } | 712 | } |
@@ -749,7 +743,7 @@ static int vbg_query_host_version(struct vbg_dev *gdev) | |||
749 | } | 743 | } |
750 | 744 | ||
751 | out: | 745 | out: |
752 | kfree(req); | 746 | vbg_req_free(req, sizeof(*req)); |
753 | return ret; | 747 | return ret; |
754 | } | 748 | } |
755 | 749 | ||
@@ -847,11 +841,16 @@ int vbg_core_init(struct vbg_dev *gdev, u32 fixed_events) | |||
847 | return 0; | 841 | return 0; |
848 | 842 | ||
849 | err_free_reqs: | 843 | err_free_reqs: |
850 | kfree(gdev->mouse_status_req); | 844 | vbg_req_free(gdev->mouse_status_req, |
851 | kfree(gdev->ack_events_req); | 845 | sizeof(*gdev->mouse_status_req)); |
852 | kfree(gdev->cancel_req); | 846 | vbg_req_free(gdev->ack_events_req, |
853 | kfree(gdev->mem_balloon.change_req); | 847 | sizeof(*gdev->ack_events_req)); |
854 | kfree(gdev->mem_balloon.get_req); | 848 | vbg_req_free(gdev->cancel_req, |
849 | sizeof(*gdev->cancel_req)); | ||
850 | vbg_req_free(gdev->mem_balloon.change_req, | ||
851 | sizeof(*gdev->mem_balloon.change_req)); | ||
852 | vbg_req_free(gdev->mem_balloon.get_req, | ||
853 | sizeof(*gdev->mem_balloon.get_req)); | ||
855 | return ret; | 854 | return ret; |
856 | } | 855 | } |
857 | 856 | ||
@@ -872,11 +871,16 @@ void vbg_core_exit(struct vbg_dev *gdev) | |||
872 | vbg_reset_host_capabilities(gdev); | 871 | vbg_reset_host_capabilities(gdev); |
873 | vbg_core_set_mouse_status(gdev, 0); | 872 | vbg_core_set_mouse_status(gdev, 0); |
874 | 873 | ||
875 | kfree(gdev->mouse_status_req); | 874 | vbg_req_free(gdev->mouse_status_req, |
876 | kfree(gdev->ack_events_req); | 875 | sizeof(*gdev->mouse_status_req)); |
877 | kfree(gdev->cancel_req); | 876 | vbg_req_free(gdev->ack_events_req, |
878 | kfree(gdev->mem_balloon.change_req); | 877 | sizeof(*gdev->ack_events_req)); |
879 | kfree(gdev->mem_balloon.get_req); | 878 | vbg_req_free(gdev->cancel_req, |
879 | sizeof(*gdev->cancel_req)); | ||
880 | vbg_req_free(gdev->mem_balloon.change_req, | ||
881 | sizeof(*gdev->mem_balloon.change_req)); | ||
882 | vbg_req_free(gdev->mem_balloon.get_req, | ||
883 | sizeof(*gdev->mem_balloon.get_req)); | ||
880 | } | 884 | } |
881 | 885 | ||
882 | /** | 886 | /** |
@@ -1415,7 +1419,7 @@ static int vbg_ioctl_write_core_dump(struct vbg_dev *gdev, | |||
1415 | req->flags = dump->u.in.flags; | 1419 | req->flags = dump->u.in.flags; |
1416 | dump->hdr.rc = vbg_req_perform(gdev, req); | 1420 | dump->hdr.rc = vbg_req_perform(gdev, req); |
1417 | 1421 | ||
1418 | kfree(req); | 1422 | vbg_req_free(req, sizeof(*req)); |
1419 | return 0; | 1423 | return 0; |
1420 | } | 1424 | } |
1421 | 1425 | ||
@@ -1513,7 +1517,7 @@ int vbg_core_set_mouse_status(struct vbg_dev *gdev, u32 features) | |||
1513 | if (rc < 0) | 1517 | if (rc < 0) |
1514 | vbg_err("%s error, rc: %d\n", __func__, rc); | 1518 | vbg_err("%s error, rc: %d\n", __func__, rc); |
1515 | 1519 | ||
1516 | kfree(req); | 1520 | vbg_req_free(req, sizeof(*req)); |
1517 | return vbg_status_code_to_errno(rc); | 1521 | return vbg_status_code_to_errno(rc); |
1518 | } | 1522 | } |
1519 | 1523 | ||
diff --git a/drivers/virt/vboxguest/vboxguest_core.h b/drivers/virt/vboxguest/vboxguest_core.h index 39ed85cf9244..7ad9ec45bfa9 100644 --- a/drivers/virt/vboxguest/vboxguest_core.h +++ b/drivers/virt/vboxguest/vboxguest_core.h | |||
@@ -173,6 +173,7 @@ void vbg_linux_mouse_event(struct vbg_dev *gdev); | |||
173 | 173 | ||
174 | /* Private (non exported) functions form vboxguest_utils.c */ | 174 | /* Private (non exported) functions form vboxguest_utils.c */ |
175 | void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type); | 175 | void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type); |
176 | void vbg_req_free(void *req, size_t len); | ||
176 | int vbg_req_perform(struct vbg_dev *gdev, void *req); | 177 | int vbg_req_perform(struct vbg_dev *gdev, void *req); |
177 | int vbg_hgcm_call32( | 178 | int vbg_hgcm_call32( |
178 | struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms, | 179 | struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms, |
diff --git a/drivers/virt/vboxguest/vboxguest_utils.c b/drivers/virt/vboxguest/vboxguest_utils.c index 0f0dab8023cf..bad915463359 100644 --- a/drivers/virt/vboxguest/vboxguest_utils.c +++ b/drivers/virt/vboxguest/vboxguest_utils.c | |||
@@ -82,6 +82,14 @@ void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type) | |||
82 | return req; | 82 | return req; |
83 | } | 83 | } |
84 | 84 | ||
85 | void vbg_req_free(void *req, size_t len) | ||
86 | { | ||
87 | if (!req) | ||
88 | return; | ||
89 | |||
90 | kfree(req); | ||
91 | } | ||
92 | |||
85 | /* Note this function returns a VBox status code, not a negative errno!! */ | 93 | /* Note this function returns a VBox status code, not a negative errno!! */ |
86 | int vbg_req_perform(struct vbg_dev *gdev, void *req) | 94 | int vbg_req_perform(struct vbg_dev *gdev, void *req) |
87 | { | 95 | { |
@@ -137,7 +145,7 @@ int vbg_hgcm_connect(struct vbg_dev *gdev, | |||
137 | rc = hgcm_connect->header.result; | 145 | rc = hgcm_connect->header.result; |
138 | } | 146 | } |
139 | 147 | ||
140 | kfree(hgcm_connect); | 148 | vbg_req_free(hgcm_connect, sizeof(*hgcm_connect)); |
141 | 149 | ||
142 | *vbox_status = rc; | 150 | *vbox_status = rc; |
143 | return 0; | 151 | return 0; |
@@ -166,7 +174,7 @@ int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 client_id, int *vbox_status) | |||
166 | if (rc >= 0) | 174 | if (rc >= 0) |
167 | rc = hgcm_disconnect->header.result; | 175 | rc = hgcm_disconnect->header.result; |
168 | 176 | ||
169 | kfree(hgcm_disconnect); | 177 | vbg_req_free(hgcm_disconnect, sizeof(*hgcm_disconnect)); |
170 | 178 | ||
171 | *vbox_status = rc; | 179 | *vbox_status = rc; |
172 | return 0; | 180 | return 0; |
@@ -623,7 +631,7 @@ int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function, | |||
623 | } | 631 | } |
624 | 632 | ||
625 | if (!leak_it) | 633 | if (!leak_it) |
626 | kfree(call); | 634 | vbg_req_free(call, size); |
627 | 635 | ||
628 | free_bounce_bufs: | 636 | free_bounce_bufs: |
629 | if (bounce_bufs) { | 637 | if (bounce_bufs) { |