aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2018-04-18 09:24:48 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-04-23 07:41:55 -0400
commitf6f9885b0531163f72c7bf898a0ab1ba4c7d5de6 (patch)
treedd2cc4cab83c58a8943ffa8357a3fbe3e969c7aa
parent02cfde67df1f440c7c3c7038cc97992afb81804f (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>
-rw-r--r--drivers/virt/vboxguest/vboxguest_core.c66
-rw-r--r--drivers/virt/vboxguest/vboxguest_core.h1
-rw-r--r--drivers/virt/vboxguest/vboxguest_utils.c14
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
116out: 116out:
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
216out_free: 216out_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
618out: 612out:
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
713out: 707out:
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
751out: 745out:
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
849err_free_reqs: 843err_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 */
175void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type); 175void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type);
176void vbg_req_free(void *req, size_t len);
176int vbg_req_perform(struct vbg_dev *gdev, void *req); 177int vbg_req_perform(struct vbg_dev *gdev, void *req);
177int vbg_hgcm_call32( 178int 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
85void 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!! */
86int vbg_req_perform(struct vbg_dev *gdev, void *req) 94int 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
628free_bounce_bufs: 636free_bounce_bufs:
629 if (bounce_bufs) { 637 if (bounce_bufs) {