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>
This commit is contained in:
parent
02cfde67df
commit
f6f9885b05
|
@ -114,7 +114,7 @@ static void vbg_guest_mappings_init(struct vbg_dev *gdev)
|
|||
}
|
||||
|
||||
out:
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
kfree(pages);
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ static void vbg_guest_mappings_exit(struct vbg_dev *gdev)
|
|||
|
||||
rc = vbg_req_perform(gdev, req);
|
||||
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
if (rc < 0) {
|
||||
vbg_err("%s error: %d\n", __func__, rc);
|
||||
|
@ -214,8 +214,8 @@ static int vbg_report_guest_info(struct vbg_dev *gdev)
|
|||
ret = vbg_status_code_to_errno(rc);
|
||||
|
||||
out_free:
|
||||
kfree(req2);
|
||||
kfree(req1);
|
||||
vbg_req_free(req2, sizeof(*req2));
|
||||
vbg_req_free(req1, sizeof(*req1));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ static int vbg_report_driver_status(struct vbg_dev *gdev, bool active)
|
|||
if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */
|
||||
rc = VINF_SUCCESS;
|
||||
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
@ -431,7 +431,7 @@ static int vbg_heartbeat_host_config(struct vbg_dev *gdev, bool enabled)
|
|||
rc = vbg_req_perform(gdev, req);
|
||||
do_div(req->interval_ns, 1000000); /* ns -> ms */
|
||||
gdev->heartbeat_interval_ms = req->interval_ns;
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
@ -454,12 +454,6 @@ static int vbg_heartbeat_init(struct vbg_dev *gdev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Preallocate the request to use it from the timer callback because:
|
||||
* 1) on Windows vbg_req_alloc must be called at IRQL <= APC_LEVEL
|
||||
* and the timer callback runs at DISPATCH_LEVEL;
|
||||
* 2) avoid repeated allocations.
|
||||
*/
|
||||
gdev->guest_heartbeat_req = vbg_req_alloc(
|
||||
sizeof(*gdev->guest_heartbeat_req),
|
||||
VMMDEVREQ_GUEST_HEARTBEAT);
|
||||
|
@ -481,8 +475,8 @@ static void vbg_heartbeat_exit(struct vbg_dev *gdev)
|
|||
{
|
||||
del_timer_sync(&gdev->heartbeat_timer);
|
||||
vbg_heartbeat_host_config(gdev, false);
|
||||
kfree(gdev->guest_heartbeat_req);
|
||||
|
||||
vbg_req_free(gdev->guest_heartbeat_req,
|
||||
sizeof(*gdev->guest_heartbeat_req));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -543,7 +537,7 @@ static int vbg_reset_host_event_filter(struct vbg_dev *gdev,
|
|||
if (rc < 0)
|
||||
vbg_err("%s error, rc: %d\n", __func__, rc);
|
||||
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
||||
|
@ -617,7 +611,7 @@ static int vbg_set_session_event_filter(struct vbg_dev *gdev,
|
|||
|
||||
out:
|
||||
mutex_unlock(&gdev->session_mutex);
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -642,7 +636,7 @@ static int vbg_reset_host_capabilities(struct vbg_dev *gdev)
|
|||
if (rc < 0)
|
||||
vbg_err("%s error, rc: %d\n", __func__, rc);
|
||||
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
||||
|
@ -712,7 +706,7 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
|
|||
|
||||
out:
|
||||
mutex_unlock(&gdev->session_mutex);
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -749,7 +743,7 @@ static int vbg_query_host_version(struct vbg_dev *gdev)
|
|||
}
|
||||
|
||||
out:
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -847,11 +841,16 @@ int vbg_core_init(struct vbg_dev *gdev, u32 fixed_events)
|
|||
return 0;
|
||||
|
||||
err_free_reqs:
|
||||
kfree(gdev->mouse_status_req);
|
||||
kfree(gdev->ack_events_req);
|
||||
kfree(gdev->cancel_req);
|
||||
kfree(gdev->mem_balloon.change_req);
|
||||
kfree(gdev->mem_balloon.get_req);
|
||||
vbg_req_free(gdev->mouse_status_req,
|
||||
sizeof(*gdev->mouse_status_req));
|
||||
vbg_req_free(gdev->ack_events_req,
|
||||
sizeof(*gdev->ack_events_req));
|
||||
vbg_req_free(gdev->cancel_req,
|
||||
sizeof(*gdev->cancel_req));
|
||||
vbg_req_free(gdev->mem_balloon.change_req,
|
||||
sizeof(*gdev->mem_balloon.change_req));
|
||||
vbg_req_free(gdev->mem_balloon.get_req,
|
||||
sizeof(*gdev->mem_balloon.get_req));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -872,11 +871,16 @@ void vbg_core_exit(struct vbg_dev *gdev)
|
|||
vbg_reset_host_capabilities(gdev);
|
||||
vbg_core_set_mouse_status(gdev, 0);
|
||||
|
||||
kfree(gdev->mouse_status_req);
|
||||
kfree(gdev->ack_events_req);
|
||||
kfree(gdev->cancel_req);
|
||||
kfree(gdev->mem_balloon.change_req);
|
||||
kfree(gdev->mem_balloon.get_req);
|
||||
vbg_req_free(gdev->mouse_status_req,
|
||||
sizeof(*gdev->mouse_status_req));
|
||||
vbg_req_free(gdev->ack_events_req,
|
||||
sizeof(*gdev->ack_events_req));
|
||||
vbg_req_free(gdev->cancel_req,
|
||||
sizeof(*gdev->cancel_req));
|
||||
vbg_req_free(gdev->mem_balloon.change_req,
|
||||
sizeof(*gdev->mem_balloon.change_req));
|
||||
vbg_req_free(gdev->mem_balloon.get_req,
|
||||
sizeof(*gdev->mem_balloon.get_req));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1415,7 +1419,7 @@ static int vbg_ioctl_write_core_dump(struct vbg_dev *gdev,
|
|||
req->flags = dump->u.in.flags;
|
||||
dump->hdr.rc = vbg_req_perform(gdev, req);
|
||||
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1513,7 +1517,7 @@ int vbg_core_set_mouse_status(struct vbg_dev *gdev, u32 features)
|
|||
if (rc < 0)
|
||||
vbg_err("%s error, rc: %d\n", __func__, rc);
|
||||
|
||||
kfree(req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
||||
|
|
|
@ -173,6 +173,7 @@ void vbg_linux_mouse_event(struct vbg_dev *gdev);
|
|||
|
||||
/* Private (non exported) functions form vboxguest_utils.c */
|
||||
void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type);
|
||||
void vbg_req_free(void *req, size_t len);
|
||||
int vbg_req_perform(struct vbg_dev *gdev, void *req);
|
||||
int vbg_hgcm_call32(
|
||||
struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms,
|
||||
|
|
|
@ -82,6 +82,14 @@ void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type)
|
|||
return req;
|
||||
}
|
||||
|
||||
void vbg_req_free(void *req, size_t len)
|
||||
{
|
||||
if (!req)
|
||||
return;
|
||||
|
||||
kfree(req);
|
||||
}
|
||||
|
||||
/* Note this function returns a VBox status code, not a negative errno!! */
|
||||
int vbg_req_perform(struct vbg_dev *gdev, void *req)
|
||||
{
|
||||
|
@ -137,7 +145,7 @@ int vbg_hgcm_connect(struct vbg_dev *gdev,
|
|||
rc = hgcm_connect->header.result;
|
||||
}
|
||||
|
||||
kfree(hgcm_connect);
|
||||
vbg_req_free(hgcm_connect, sizeof(*hgcm_connect));
|
||||
|
||||
*vbox_status = rc;
|
||||
return 0;
|
||||
|
@ -166,7 +174,7 @@ int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 client_id, int *vbox_status)
|
|||
if (rc >= 0)
|
||||
rc = hgcm_disconnect->header.result;
|
||||
|
||||
kfree(hgcm_disconnect);
|
||||
vbg_req_free(hgcm_disconnect, sizeof(*hgcm_disconnect));
|
||||
|
||||
*vbox_status = rc;
|
||||
return 0;
|
||||
|
@ -623,7 +631,7 @@ int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function,
|
|||
}
|
||||
|
||||
if (!leak_it)
|
||||
kfree(call);
|
||||
vbg_req_free(call, size);
|
||||
|
||||
free_bounce_bufs:
|
||||
if (bounce_bufs) {
|
||||
|
|
Loading…
Reference in a new issue