summaryrefslogtreecommitdiffstats
path: root/vboxguest-fixes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'vboxguest-fixes.patch')
-rw-r--r--vboxguest-fixes.patch843
1 files changed, 0 insertions, 843 deletions
diff --git a/vboxguest-fixes.patch b/vboxguest-fixes.patch
deleted file mode 100644
index 90c95b374..000000000
--- a/vboxguest-fixes.patch
+++ /dev/null
@@ -1,843 +0,0 @@
-From ba5ea5d9d5d2ade5156cf2bc452ff6d1f5c4db37 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 12:21:30 +0200
-Subject: [PATCH 1/8] virt: vbox: Fix VBGL_IOCTL_VMMDEV_REQUEST_BIG and _LOG
- req numbers to match upstream
-
-Until this commit the mainline kernel version (this version) of the
-vboxguest module contained a bug where it defined
-VBGL_IOCTL_VMMDEV_REQUEST_BIG and VBGL_IOCTL_LOG using
-_IOC(_IOC_READ | _IOC_WRITE, 'V', ...) instead of
-_IO(V, ...) as the out of tree VirtualBox upstream version does.
-
-Since the VirtualBox userspace bits are always built against VirtualBox
-upstream's headers, this means that so far the mainline kernel version
-of the vboxguest module has been failing these 2 ioctls with -ENOTTY.
-I guess that VBGL_IOCTL_VMMDEV_REQUEST_BIG is never used causing us to
-not hit that one and sofar the vboxguest driver has failed to actually
-log any log messages passed it through VBGL_IOCTL_LOG.
-
-This commit changes the VBGL_IOCTL_VMMDEV_REQUEST_BIG and VBGL_IOCTL_LOG
-defines to match the out of tree VirtualBox upstream vboxguest version,
-while keeping compatibility with the old wrong request defines so as
-to not break the kernel ABI in case someone has been using the old
-request defines.
-
-Fixes: f6ddd094f579 ("virt: Add vboxguest driver for Virtual Box Guest integration UAPI")
-Cc: stable@vger.kernel.org
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 4 +++-
- drivers/virt/vboxguest/vboxguest_core.h | 15 +++++++++++++++
- drivers/virt/vboxguest/vboxguest_linux.c | 3 ++-
- include/uapi/linux/vboxguest.h | 4 ++--
- 4 files changed, 22 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index b690a8a4bf9e..8fab04e76c14 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -1520,7 +1520,8 @@ int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
-
- /* For VMMDEV_REQUEST hdr->type != VBG_IOCTL_HDR_TYPE_DEFAULT */
- if (req_no_size == VBG_IOCTL_VMMDEV_REQUEST(0) ||
-- req == VBG_IOCTL_VMMDEV_REQUEST_BIG)
-+ req == VBG_IOCTL_VMMDEV_REQUEST_BIG ||
-+ req == VBG_IOCTL_VMMDEV_REQUEST_BIG_ALT)
- return vbg_ioctl_vmmrequest(gdev, session, data);
-
- if (hdr->type != VBG_IOCTL_HDR_TYPE_DEFAULT)
-@@ -1558,6 +1559,7 @@ int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
- case VBG_IOCTL_HGCM_CALL(0):
- return vbg_ioctl_hgcm_call(gdev, session, f32bit, data);
- case VBG_IOCTL_LOG(0):
-+ case VBG_IOCTL_LOG_ALT(0):
- return vbg_ioctl_log(data);
- }
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.h b/drivers/virt/vboxguest/vboxguest_core.h
-index 4188c12b839f..77c3a9c8255d 100644
---- a/drivers/virt/vboxguest/vboxguest_core.h
-+++ b/drivers/virt/vboxguest/vboxguest_core.h
-@@ -15,6 +15,21 @@
- #include <linux/vboxguest.h>
- #include "vmmdev.h"
-
-+/*
-+ * The mainline kernel version (this version) of the vboxguest module
-+ * contained a bug where it defined VBGL_IOCTL_VMMDEV_REQUEST_BIG and
-+ * VBGL_IOCTL_LOG using _IOC(_IOC_READ | _IOC_WRITE, 'V', ...) instead
-+ * of _IO(V, ...) as the out of tree VirtualBox upstream version does.
-+ *
-+ * These _ALT definitions keep compatibility with the wrong defines the
-+ * mainline kernel version used for a while.
-+ * Note the VirtualBox userspace bits have always been built against
-+ * VirtualBox upstream's headers, so this is likely not necessary. But
-+ * we must never break our ABI so we keep these around to be 100% sure.
-+ */
-+#define VBG_IOCTL_VMMDEV_REQUEST_BIG_ALT _IOC(_IOC_READ | _IOC_WRITE, 'V', 3, 0)
-+#define VBG_IOCTL_LOG_ALT(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 9, s)
-+
- struct vbg_session;
-
- /** VBox guest memory balloon. */
-diff --git a/drivers/virt/vboxguest/vboxguest_linux.c b/drivers/virt/vboxguest/vboxguest_linux.c
-index 6e8c0f1c1056..32c2c52f7e84 100644
---- a/drivers/virt/vboxguest/vboxguest_linux.c
-+++ b/drivers/virt/vboxguest/vboxguest_linux.c
-@@ -131,7 +131,8 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
- * the need for a bounce-buffer and another copy later on.
- */
- is_vmmdev_req = (req & ~IOCSIZE_MASK) == VBG_IOCTL_VMMDEV_REQUEST(0) ||
-- req == VBG_IOCTL_VMMDEV_REQUEST_BIG;
-+ req == VBG_IOCTL_VMMDEV_REQUEST_BIG ||
-+ req == VBG_IOCTL_VMMDEV_REQUEST_BIG_ALT;
-
- if (is_vmmdev_req)
- buf = vbg_req_alloc(size, VBG_IOCTL_HDR_TYPE_DEFAULT,
-diff --git a/include/uapi/linux/vboxguest.h b/include/uapi/linux/vboxguest.h
-index 9cec58a6a5ea..f79d7abe27db 100644
---- a/include/uapi/linux/vboxguest.h
-+++ b/include/uapi/linux/vboxguest.h
-@@ -103,7 +103,7 @@ VMMDEV_ASSERT_SIZE(vbg_ioctl_driver_version_info, 24 + 20);
-
-
- /* IOCTL to perform a VMM Device request larger then 1KB. */
--#define VBG_IOCTL_VMMDEV_REQUEST_BIG _IOC(_IOC_READ | _IOC_WRITE, 'V', 3, 0)
-+#define VBG_IOCTL_VMMDEV_REQUEST_BIG _IO('V', 3)
-
-
- /** VBG_IOCTL_HGCM_CONNECT data structure. */
-@@ -198,7 +198,7 @@ struct vbg_ioctl_log {
- } u;
- };
-
--#define VBG_IOCTL_LOG(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 9, s)
-+#define VBG_IOCTL_LOG(s) _IO('V', 9)
-
-
- /** VBG_IOCTL_WAIT_FOR_EVENTS data structure. */
---
-2.26.2
-
-From 14dc3b46e666343c55e5b253ed3dd4c57b13e778 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 13:23:06 +0200
-Subject: [PATCH 2/8] virt: vbox: Fix guest capabilities mask check
-
-Check the passed in capabilities against VMMDEV_GUEST_CAPABILITIES_MASK
-instead of against VMMDEV_EVENT_VALID_EVENT_MASK.
-This tightens the allowed mask from 0x7ff to 0x7.
-
-Fixes: 0ba002bc4393 ("virt: Add vboxguest driver for Virtual Box Guest integration")
-Cc: stable@vger.kernel.org
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 2 +-
- drivers/virt/vboxguest/vmmdev.h | 2 ++
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index 8fab04e76c14..18ebd7a6af98 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -1444,7 +1444,7 @@ static int vbg_ioctl_change_guest_capabilities(struct vbg_dev *gdev,
- or_mask = caps->u.in.or_mask;
- not_mask = caps->u.in.not_mask;
-
-- if ((or_mask | not_mask) & ~VMMDEV_EVENT_VALID_EVENT_MASK)
-+ if ((or_mask | not_mask) & ~VMMDEV_GUEST_CAPABILITIES_MASK)
- return -EINVAL;
-
- ret = vbg_set_session_capabilities(gdev, session, or_mask, not_mask,
-diff --git a/drivers/virt/vboxguest/vmmdev.h b/drivers/virt/vboxguest/vmmdev.h
-index 6337b8d75d96..21f408120e3f 100644
---- a/drivers/virt/vboxguest/vmmdev.h
-+++ b/drivers/virt/vboxguest/vmmdev.h
-@@ -206,6 +206,8 @@ VMMDEV_ASSERT_SIZE(vmmdev_mask, 24 + 8);
- * not.
- */
- #define VMMDEV_GUEST_SUPPORTS_GRAPHICS BIT(2)
-+/* The mask of valid capabilities, for sanity checking. */
-+#define VMMDEV_GUEST_CAPABILITIES_MASK 0x00000007U
-
- /** struct vmmdev_hypervisorinfo - Hypervisor info structure. */
- struct vmmdev_hypervisorinfo {
---
-2.26.2
-
-From 172353a61c23015611a341c2f3f4888d866a560b Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 14:33:13 +0200
-Subject: [PATCH 3/8] virt: vbox: Rename guest_caps struct members to
- set_guest_caps
-
-Rename guest_caps[_tracker] struct members to set_guest_caps[_tracker]
-this is a preparation patch for adding support for the
-VBGL_IOCTL_GUEST_CAPS_ACQUIRE ioctl.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 20 ++++++++++----------
- drivers/virt/vboxguest/vboxguest_core.h | 9 +++++----
- 2 files changed, 15 insertions(+), 14 deletions(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index 18ebd7a6af98..aee5eff229f2 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -699,17 +699,17 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
- mutex_lock(&gdev->session_mutex);
-
- /* Apply the changes to the session mask. */
-- previous = session->guest_caps;
-- session->guest_caps |= or_mask;
-- session->guest_caps &= ~not_mask;
-+ previous = session->set_guest_caps;
-+ session->set_guest_caps |= or_mask;
-+ session->set_guest_caps &= ~not_mask;
-
- /* If anything actually changed, update the global usage counters. */
-- changed = previous ^ session->guest_caps;
-+ changed = previous ^ session->set_guest_caps;
- if (!changed)
- goto out;
-
-- vbg_track_bit_usage(&gdev->guest_caps_tracker, changed, previous);
-- or_mask = gdev->guest_caps_tracker.mask;
-+ 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;
-@@ -726,9 +726,9 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
- if (session_termination)
- goto out;
-
-- vbg_track_bit_usage(&gdev->guest_caps_tracker, changed,
-- session->guest_caps);
-- session->guest_caps = previous;
-+ vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed,
-+ session->set_guest_caps);
-+ session->set_guest_caps = previous;
- }
-
- out:
-@@ -1452,7 +1452,7 @@ static int vbg_ioctl_change_guest_capabilities(struct vbg_dev *gdev,
- if (ret)
- return ret;
-
-- caps->u.out.session_caps = session->guest_caps;
-+ caps->u.out.session_caps = session->set_guest_caps;
- caps->u.out.global_caps = gdev->guest_caps_host;
-
- return 0;
-diff --git a/drivers/virt/vboxguest/vboxguest_core.h b/drivers/virt/vboxguest/vboxguest_core.h
-index 77c3a9c8255d..dc745a033164 100644
---- a/drivers/virt/vboxguest/vboxguest_core.h
-+++ b/drivers/virt/vboxguest/vboxguest_core.h
-@@ -118,11 +118,12 @@ struct vbg_dev {
- u32 event_filter_host;
-
- /**
-- * Usage counters for guest capabilities. Indexed by capability bit
-+ * Usage counters for guest capabilities requested through
-+ * vbg_set_session_capabilities(). Indexed by capability bit
- * number, one count per session using a capability.
- * Protected by session_mutex.
- */
-- struct vbg_bit_usage_tracker guest_caps_tracker;
-+ struct vbg_bit_usage_tracker set_guest_caps_tracker;
- /**
- * The guest capabilities last reported to the host (or UINT32_MAX).
- * Protected by session_mutex.
-@@ -164,11 +165,11 @@ struct vbg_session {
- */
- u32 event_filter;
- /**
-- * Guest capabilities for this session.
-+ * Guest capabilities set through vbg_set_session_capabilities().
- * A capability claimed by any guest session will be reported to the
- * host. Protected by vbg_gdev.session_mutex.
- */
-- u32 guest_caps;
-+ u32 set_guest_caps;
- /** VMMDEV_REQUESTOR_* flags */
- u32 requestor;
- /** Set on CANCEL_ALL_WAITEVENTS, protected by vbg_devevent_spinlock. */
---
-2.26.2
-
-From c5cf459d4d98a7993f5e00d5d2b826c55bbce562 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 15:30:29 +0200
-Subject: [PATCH 4/8] 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.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 79 ++++++++++++++-----------
- 1 file changed, 46 insertions(+), 33 deletions(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index aee5eff229f2..15b3cb618c6e 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -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;
- }
---
-2.26.2
-
-From 2f33e58bcc8c69f938629dc57c8ad631724f02f0 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 18:04:30 +0200
-Subject: [PATCH 5/8] virt: vbox: Add support for the new
- VBG_IOCTL_ACQUIRE_GUEST_CAPABILITIES ioctl
-
-Add support for the new VBG_IOCTL_ACQUIRE_GUEST_CAPABILITIES ioctl, this
-is necessary for automatic resizing of the guest resolution to match the
-VM-window size to work with the new VMSVGA virtual GPU which is now the
-new default in VirtualBox.
-
-BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1789545
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 163 +++++++++++++++++++++++-
- drivers/virt/vboxguest/vboxguest_core.h | 14 ++
- include/uapi/linux/vboxguest.h | 24 ++++
- 3 files changed, 200 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index 15b3cb618c6e..4f1addaa3f6f 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -679,7 +679,7 @@ static int vbg_set_host_capabilities(struct vbg_dev *gdev,
-
- WARN_ON(!mutex_is_locked(&gdev->session_mutex));
-
-- caps = gdev->set_guest_caps_tracker.mask;
-+ caps = gdev->acquired_guest_caps | gdev->set_guest_caps_tracker.mask;
-
- if (gdev->guest_caps_host == caps)
- return 0;
-@@ -703,6 +703,113 @@ static int vbg_set_host_capabilities(struct vbg_dev *gdev,
- return vbg_status_code_to_errno(rc);
- }
-
-+/**
-+ * Acquire (get exclusive access) guest capabilities for a session.
-+ * Takes the session mutex.
-+ * Return: 0 or negative errno value.
-+ * @gdev: The Guest extension device.
-+ * @session: The session.
-+ * @flags: Flags (VBGL_IOC_AGC_FLAGS_XXX).
-+ * @or_mask: The capabilities to add.
-+ * @not_mask: The capabilities to remove.
-+ * @session_termination: Set if we're called by the session cleanup code.
-+ * This tweaks the error handling so we perform
-+ * proper session cleanup even if the host
-+ * misbehaves.
-+ */
-+static int vbg_acquire_session_capabilities(struct vbg_dev *gdev,
-+ struct vbg_session *session,
-+ u32 or_mask, u32 not_mask,
-+ u32 flags, bool session_termination)
-+{
-+ unsigned long irqflags;
-+ bool wakeup = false;
-+ int ret = 0;
-+
-+ mutex_lock(&gdev->session_mutex);
-+
-+ if (gdev->set_guest_caps_tracker.mask & or_mask) {
-+ vbg_err("%s error: cannot acquire caps which are currently set\n",
-+ __func__);
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ /*
-+ * Mark any caps in the or_mask as now being in acquire-mode. Note
-+ * once caps are in acquire_mode they always stay in this mode.
-+ * This impacts event handling, so we take the event-lock.
-+ */
-+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
-+ gdev->acquire_mode_guest_caps |= or_mask;
-+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
-+
-+ /* If we only have to switch the caps to acquire mode, we're done. */
-+ if (flags & VBGL_IOC_AGC_FLAGS_CONFIG_ACQUIRE_MODE)
-+ goto out;
-+
-+ not_mask &= ~or_mask; /* or_mask takes priority over not_mask */
-+ not_mask &= session->acquired_guest_caps;
-+ or_mask &= ~session->acquired_guest_caps;
-+
-+ if (or_mask == 0 && not_mask == 0)
-+ goto out;
-+
-+ if (gdev->acquired_guest_caps & or_mask) {
-+ ret = -EBUSY;
-+ goto out;
-+ }
-+
-+ gdev->acquired_guest_caps |= or_mask;
-+ gdev->acquired_guest_caps &= ~not_mask;
-+ /* session->acquired_guest_caps impacts event handling, take the lock */
-+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
-+ session->acquired_guest_caps |= or_mask;
-+ session->acquired_guest_caps &= ~not_mask;
-+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
-+
-+ ret = vbg_set_host_capabilities(gdev, session, session_termination);
-+ /* Roll back on failure, unless it's session termination time. */
-+ if (ret < 0 && !session_termination) {
-+ gdev->acquired_guest_caps &= ~or_mask;
-+ gdev->acquired_guest_caps |= not_mask;
-+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
-+ session->acquired_guest_caps &= ~or_mask;
-+ session->acquired_guest_caps |= not_mask;
-+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
-+ }
-+
-+ /*
-+ * If we added a capability, check if that means some other thread in
-+ * our session should be unblocked because there are events pending
-+ * (the result of vbg_get_allowed_event_mask_for_session() may change).
-+ *
-+ * HACK ALERT! When the seamless support capability is added we generate
-+ * a seamless change event so that the ring-3 client can sync with
-+ * the seamless state.
-+ */
-+ if (ret == 0 && or_mask != 0) {
-+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
-+
-+ if (or_mask & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
-+ gdev->pending_events |=
-+ VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
-+
-+ if (gdev->pending_events)
-+ wakeup = true;
-+
-+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
-+
-+ if (wakeup)
-+ wake_up(&gdev->event_wq);
-+ }
-+
-+out:
-+ mutex_unlock(&gdev->session_mutex);
-+
-+ return ret;
-+}
-+
- /**
- * Sets the guest capabilities for a session. Takes the session spinlock.
- * Return: 0 or negative errno value.
-@@ -725,6 +832,13 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
-
- mutex_lock(&gdev->session_mutex);
-
-+ if (gdev->acquire_mode_guest_caps & or_mask) {
-+ vbg_err("%s error: cannot set caps which are in acquire_mode\n",
-+ __func__);
-+ ret = -EBUSY;
-+ goto out;
-+ }
-+
- /* Apply the changes to the session mask. */
- previous = session->set_guest_caps;
- session->set_guest_caps |= or_mask;
-@@ -962,6 +1076,7 @@ void vbg_core_close_session(struct vbg_session *session)
- struct vbg_dev *gdev = session->gdev;
- int i, rc;
-
-+ vbg_acquire_session_capabilities(gdev, session, 0, U32_MAX, 0, true);
- vbg_set_session_capabilities(gdev, session, 0, U32_MAX, true);
- vbg_set_session_event_filter(gdev, session, 0, U32_MAX, true);
-
-@@ -1019,6 +1134,25 @@ static int vbg_ioctl_driver_version_info(
- return 0;
- }
-
-+/* Must be called with the event_lock held */
-+static u32 vbg_get_allowed_event_mask_for_session(struct vbg_dev *gdev,
-+ struct vbg_session *session)
-+{
-+ u32 acquire_mode_caps = gdev->acquire_mode_guest_caps;
-+ u32 session_acquired_caps = session->acquired_guest_caps;
-+ u32 allowed_events = VMMDEV_EVENT_VALID_EVENT_MASK;
-+
-+ if ((acquire_mode_caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS) &&
-+ !(session_acquired_caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS))
-+ allowed_events &= ~VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
-+
-+ if ((acquire_mode_caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS) &&
-+ !(session_acquired_caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS))
-+ allowed_events &= ~VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
-+
-+ return allowed_events;
-+}
-+
- static bool vbg_wait_event_cond(struct vbg_dev *gdev,
- struct vbg_session *session,
- u32 event_mask)
-@@ -1030,6 +1164,7 @@ static bool vbg_wait_event_cond(struct vbg_dev *gdev,
- spin_lock_irqsave(&gdev->event_spinlock, flags);
-
- events = gdev->pending_events & event_mask;
-+ events &= vbg_get_allowed_event_mask_for_session(gdev, session);
- wakeup = events || session->cancel_waiters;
-
- spin_unlock_irqrestore(&gdev->event_spinlock, flags);
-@@ -1044,6 +1179,7 @@ static u32 vbg_consume_events_locked(struct vbg_dev *gdev,
- {
- u32 events = gdev->pending_events & event_mask;
-
-+ events &= vbg_get_allowed_event_mask_for_session(gdev, session);
- gdev->pending_events &= ~events;
- return events;
- }
-@@ -1445,6 +1581,29 @@ static int vbg_ioctl_change_filter_mask(struct vbg_dev *gdev,
- false);
- }
-
-+static int vbg_ioctl_acquire_guest_capabilities(struct vbg_dev *gdev,
-+ struct vbg_session *session,
-+ struct vbg_ioctl_acquire_guest_caps *caps)
-+{
-+ u32 flags, or_mask, not_mask;
-+
-+ if (vbg_ioctl_chk(&caps->hdr, sizeof(caps->u.in), 0))
-+ return -EINVAL;
-+
-+ flags = caps->u.in.flags;
-+ or_mask = caps->u.in.or_mask;
-+ not_mask = caps->u.in.not_mask;
-+
-+ if (flags & ~VBGL_IOC_AGC_FLAGS_VALID_MASK)
-+ return -EINVAL;
-+
-+ if ((or_mask | not_mask) & ~VMMDEV_GUEST_CAPABILITIES_MASK)
-+ return -EINVAL;
-+
-+ return vbg_acquire_session_capabilities(gdev, session, or_mask,
-+ not_mask, flags, false);
-+}
-+
- static int vbg_ioctl_change_guest_capabilities(struct vbg_dev *gdev,
- struct vbg_session *session, struct vbg_ioctl_set_guest_caps *caps)
- {
-@@ -1554,6 +1713,8 @@ int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
- return vbg_ioctl_interrupt_all_wait_events(gdev, session, data);
- case VBG_IOCTL_CHANGE_FILTER_MASK:
- return vbg_ioctl_change_filter_mask(gdev, session, data);
-+ case VBG_IOCTL_ACQUIRE_GUEST_CAPABILITIES:
-+ return vbg_ioctl_acquire_guest_capabilities(gdev, session, data);
- case VBG_IOCTL_CHANGE_GUEST_CAPABILITIES:
- return vbg_ioctl_change_guest_capabilities(gdev, session, data);
- case VBG_IOCTL_CHECK_BALLOON:
-diff --git a/drivers/virt/vboxguest/vboxguest_core.h b/drivers/virt/vboxguest/vboxguest_core.h
-index dc745a033164..ab4bf64e2cec 100644
---- a/drivers/virt/vboxguest/vboxguest_core.h
-+++ b/drivers/virt/vboxguest/vboxguest_core.h
-@@ -117,6 +117,15 @@ struct vbg_dev {
- */
- u32 event_filter_host;
-
-+ /**
-+ * Guest capabilities which have been switched to acquire_mode.
-+ */
-+ u32 acquire_mode_guest_caps;
-+ /**
-+ * Guest capabilities acquired by vbg_acquire_session_capabilities().
-+ * Only one session can acquire a capability at a time.
-+ */
-+ u32 acquired_guest_caps;
- /**
- * Usage counters for guest capabilities requested through
- * vbg_set_session_capabilities(). Indexed by capability bit
-@@ -164,6 +173,11 @@ struct vbg_session {
- * host filter. Protected by vbg_gdev.session_mutex.
- */
- u32 event_filter;
-+ /**
-+ * Guest capabilities acquired by vbg_acquire_session_capabilities().
-+ * Only one session can acquire a capability at a time.
-+ */
-+ u32 acquired_guest_caps;
- /**
- * Guest capabilities set through vbg_set_session_capabilities().
- * A capability claimed by any guest session will be reported to the
-diff --git a/include/uapi/linux/vboxguest.h b/include/uapi/linux/vboxguest.h
-index f79d7abe27db..15125f6ec60d 100644
---- a/include/uapi/linux/vboxguest.h
-+++ b/include/uapi/linux/vboxguest.h
-@@ -257,6 +257,30 @@ VMMDEV_ASSERT_SIZE(vbg_ioctl_change_filter, 24 + 8);
- _IOWR('V', 12, struct vbg_ioctl_change_filter)
-
-
-+/** VBG_IOCTL_ACQUIRE_GUEST_CAPABILITIES data structure. */
-+struct vbg_ioctl_acquire_guest_caps {
-+ /** The header. */
-+ struct vbg_ioctl_hdr hdr;
-+ union {
-+ struct {
-+ /** Flags (VBGL_IOC_AGC_FLAGS_XXX). */
-+ __u32 flags;
-+ /** Capabilities to set (VMMDEV_GUEST_SUPPORTS_XXX). */
-+ __u32 or_mask;
-+ /** Capabilities to drop (VMMDEV_GUEST_SUPPORTS_XXX). */
-+ __u32 not_mask;
-+ } in;
-+ } u;
-+};
-+VMMDEV_ASSERT_SIZE(vbg_ioctl_acquire_guest_caps, 24 + 12);
-+
-+#define VBGL_IOC_AGC_FLAGS_CONFIG_ACQUIRE_MODE 0x00000001
-+#define VBGL_IOC_AGC_FLAGS_VALID_MASK 0x00000001
-+
-+#define VBG_IOCTL_ACQUIRE_GUEST_CAPABILITIES \
-+ _IOWR('V', 13, struct vbg_ioctl_acquire_guest_caps)
-+
-+
- /** VBG_IOCTL_CHANGE_GUEST_CAPABILITIES data structure. */
- struct vbg_ioctl_set_guest_caps {
- /** The header. */
---
-2.26.2
-
-From d34852680360e52c39ea901fbc3778d28f229852 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 11:05:40 +0200
-Subject: [PATCH 6/8] virt: vbox: Add a few new vmmdev request types to the
- userspace whitelist
-
-Upstream VirtualBox has defined and is using a few new request types for
-vmmdev requests passed through /dev/vboxguest to the hypervisor.
-
-Add the defines for these to vbox_vmmdev_types.h and add add them to the
-whitelists of vmmdev requests which userspace is allowed to make.
-
-BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1789545
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 2 ++
- include/uapi/linux/vbox_vmmdev_types.h | 3 +++
- 2 files changed, 5 insertions(+)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index 4f1addaa3f6f..ffd76b949276 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -1299,7 +1299,9 @@ static int vbg_req_allowed(struct vbg_dev *gdev, struct vbg_session *session,
- case VMMDEVREQ_VIDEO_ACCEL_ENABLE:
- case VMMDEVREQ_VIDEO_ACCEL_FLUSH:
- case VMMDEVREQ_VIDEO_SET_VISIBLE_REGION:
-+ case VMMDEVREQ_VIDEO_UPDATE_MONITOR_POSITIONS:
- case VMMDEVREQ_GET_DISPLAY_CHANGE_REQEX:
-+ case VMMDEVREQ_GET_DISPLAY_CHANGE_REQ_MULTI:
- case VMMDEVREQ_GET_SEAMLESS_CHANGE_REQ:
- case VMMDEVREQ_GET_VRDPCHANGE_REQ:
- case VMMDEVREQ_LOG_STRING:
-diff --git a/include/uapi/linux/vbox_vmmdev_types.h b/include/uapi/linux/vbox_vmmdev_types.h
-index c27289fd619a..f8a8d6b3c521 100644
---- a/include/uapi/linux/vbox_vmmdev_types.h
-+++ b/include/uapi/linux/vbox_vmmdev_types.h
-@@ -63,6 +63,7 @@ enum vmmdev_request_type {
- VMMDEVREQ_SET_GUEST_CAPABILITIES = 56,
- VMMDEVREQ_VIDEMODE_SUPPORTED2 = 57, /* since version 3.2.0 */
- VMMDEVREQ_GET_DISPLAY_CHANGE_REQEX = 80, /* since version 4.2.4 */
-+ VMMDEVREQ_GET_DISPLAY_CHANGE_REQ_MULTI = 81,
- VMMDEVREQ_HGCM_CONNECT = 60,
- VMMDEVREQ_HGCM_DISCONNECT = 61,
- VMMDEVREQ_HGCM_CALL32 = 62,
-@@ -92,6 +93,8 @@ enum vmmdev_request_type {
- VMMDEVREQ_WRITE_COREDUMP = 218,
- VMMDEVREQ_GUEST_HEARTBEAT = 219,
- VMMDEVREQ_HEARTBEAT_CONFIGURE = 220,
-+ VMMDEVREQ_NT_BUG_CHECK = 221,
-+ VMMDEVREQ_VIDEO_UPDATE_MONITOR_POSITIONS = 222,
- /* Ensure the enum is a 32 bit data-type */
- VMMDEVREQ_SIZEHACK = 0x7fffffff
- };
---
-2.26.2
-
-From 92887e49b5f83dd802f3486143a9b619c7b56947 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 11:24:43 +0200
-Subject: [PATCH 7/8] virt: vbox: Log unknown ioctl requests as error
-
-Every now and then upstream adds new ioctls without notifying us,
-log unknown ioctl requests as an error to catch these.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index ffd76b949276..e0e343d0ba93 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -1739,7 +1739,7 @@ int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
- return vbg_ioctl_log(data);
- }
-
-- vbg_debug("VGDrvCommonIoCtl: Unknown req %#08x\n", req);
-+ vbg_err("Userspace made an unknown ioctl req %#08x\n", req);
- return -ENOTTY;
- }
-
---
-2.26.2
-
-From 10a3a8c4a13e608d24db0a4ed4a284470025346d Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 19 May 2020 18:08:07 +0200
-Subject: [PATCH 8/8] virt: vbox: Fix some comments which talk about the
- "session spinlock"
-
-The session lock is a mutex, not a spinlock, fix the comments to match.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/virt/vboxguest/vboxguest_core.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c
-index e0e343d0ba93..d99c19551d04 100644
---- a/drivers/virt/vboxguest/vboxguest_core.c
-+++ b/drivers/virt/vboxguest/vboxguest_core.c
-@@ -559,7 +559,7 @@ static int vbg_reset_host_event_filter(struct vbg_dev *gdev,
- * Changes the event filter mask for the given session.
- *
- * This is called in response to VBG_IOCTL_CHANGE_FILTER_MASK as well as to
-- * do session cleanup. Takes the session spinlock.
-+ * do session cleanup. Takes the session mutex.
- *
- * Return: 0 or negative errno value.
- * @gdev: The Guest extension device.
-@@ -811,7 +811,7 @@ static int vbg_acquire_session_capabilities(struct vbg_dev *gdev,
- }
-
- /**
-- * Sets the guest capabilities for a session. Takes the session spinlock.
-+ * Sets the guest capabilities for a session. Takes the session mutex.
- * Return: 0 or negative errno value.
- * @gdev: The Guest extension device.
- * @session: The session.
---
-2.26.2
-