Commit f6f9885b authored by Hans de Goede's avatar Hans de Goede Committed by Greg Kroah-Hartman
Browse files

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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 02cfde67
Loading
Loading
Loading
Loading
+35 −31
Original line number Diff line number Diff line
@@ -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);
}

+1 −0
Original line number Diff line number Diff line
@@ -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,
+11 −3
Original line number Diff line number Diff line
@@ -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) {