mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 09:44:18 +08:00
virt: vbox: Add vbg_set_host_capabilities() helper function
Add vbg_set_host_capabilities() helper function, this is a preparation patch for adding support for the VBGL_IOCTL_GUEST_CAPS_ACQUIRE ioctl. Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20200709120858.63928-5-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fd01cc5903
commit
412f84cff0
@ -661,6 +661,48 @@ static int vbg_reset_host_capabilities(struct vbg_dev *gdev)
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set guest capabilities on the host.
|
||||
* Must be called with gdev->session_mutex hold.
|
||||
* Return: 0 or negative errno value.
|
||||
* @gdev: The Guest extension device.
|
||||
* @session: The session.
|
||||
* @session_termination: Set if we're called by the session cleanup code.
|
||||
*/
|
||||
static int vbg_set_host_capabilities(struct vbg_dev *gdev,
|
||||
struct vbg_session *session,
|
||||
bool session_termination)
|
||||
{
|
||||
struct vmmdev_mask *req;
|
||||
u32 caps;
|
||||
int rc;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&gdev->session_mutex));
|
||||
|
||||
caps = gdev->set_guest_caps_tracker.mask;
|
||||
|
||||
if (gdev->guest_caps_host == caps)
|
||||
return 0;
|
||||
|
||||
/* On termination the requestor is the kernel, as we're cleaning up. */
|
||||
req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES,
|
||||
session_termination ? VBG_KERNEL_REQUEST :
|
||||
session->requestor);
|
||||
if (!req) {
|
||||
gdev->guest_caps_host = U32_MAX;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
req->or_mask = caps;
|
||||
req->not_mask = ~caps;
|
||||
rc = vbg_req_perform(gdev, req);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
gdev->guest_caps_host = (rc >= 0) ? caps : U32_MAX;
|
||||
|
||||
return vbg_status_code_to_errno(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the guest capabilities for a session. Takes the session spinlock.
|
||||
* Return: 0 or negative errno value.
|
||||
@ -678,23 +720,8 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
|
||||
u32 or_mask, u32 not_mask,
|
||||
bool session_termination)
|
||||
{
|
||||
struct vmmdev_mask *req;
|
||||
u32 changed, previous;
|
||||
int rc, ret = 0;
|
||||
|
||||
/*
|
||||
* Allocate a request buffer before taking the spinlock, when
|
||||
* the session is being terminated the requestor is the kernel,
|
||||
* as we're cleaning up.
|
||||
*/
|
||||
req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES,
|
||||
session_termination ? VBG_KERNEL_REQUEST :
|
||||
session->requestor);
|
||||
if (!req) {
|
||||
if (!session_termination)
|
||||
return -ENOMEM;
|
||||
/* Ignore allocation failure, we must do session cleanup. */
|
||||
}
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&gdev->session_mutex);
|
||||
|
||||
@ -709,23 +736,10 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
|
||||
goto out;
|
||||
|
||||
vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed, previous);
|
||||
or_mask = gdev->set_guest_caps_tracker.mask;
|
||||
|
||||
if (gdev->guest_caps_host == or_mask || !req)
|
||||
goto out;
|
||||
|
||||
gdev->guest_caps_host = or_mask;
|
||||
req->or_mask = or_mask;
|
||||
req->not_mask = ~or_mask;
|
||||
rc = vbg_req_perform(gdev, req);
|
||||
if (rc < 0) {
|
||||
ret = vbg_status_code_to_errno(rc);
|
||||
|
||||
/* Failed, roll back (unless it's session termination time). */
|
||||
gdev->guest_caps_host = U32_MAX;
|
||||
if (session_termination)
|
||||
goto out;
|
||||
|
||||
ret = vbg_set_host_capabilities(gdev, session, session_termination);
|
||||
/* Roll back on failure, unless it's session termination time. */
|
||||
if (ret < 0 && !session_termination) {
|
||||
vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed,
|
||||
session->set_guest_caps);
|
||||
session->set_guest_caps = previous;
|
||||
@ -733,7 +747,6 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
|
||||
|
||||
out:
|
||||
mutex_unlock(&gdev->session_mutex);
|
||||
vbg_req_free(req, sizeof(*req));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user