diff options
Diffstat (limited to 'vboxguest-fixes.patch')
-rw-r--r-- | vboxguest-fixes.patch | 843 |
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 - |