forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/virt/vboxguest/vboxguest_core.c
....@@ -6,6 +6,7 @@
66 */
77
88 #include <linux/device.h>
9
+#include <linux/io.h>
910 #include <linux/mm.h>
1011 #include <linux/sched.h>
1112 #include <linux/sizes.h>
....@@ -26,6 +27,10 @@
2627 (u8 *)(a) + sizeof(struct vbg_ioctl_hgcm_call)))
2728
2829 #define GUEST_MAPPINGS_TRIES 5
30
+
31
+#define VBG_KERNEL_REQUEST \
32
+ (VMMDEV_REQUESTOR_KERNEL | VMMDEV_REQUESTOR_USR_DRV | \
33
+ VMMDEV_REQUESTOR_CON_DONT_KNOW | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN)
2934
3035 /**
3136 * Reserves memory in which the VMM can relocate any guest mappings
....@@ -48,7 +53,8 @@
4853 int i, rc;
4954
5055 /* Query the required space. */
51
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_GET_HYPERVISOR_INFO);
56
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_GET_HYPERVISOR_INFO,
57
+ VBG_KERNEL_REQUEST);
5258 if (!req)
5359 return;
5460
....@@ -135,7 +141,8 @@
135141 * Tell the host that we're going to free the memory we reserved for
136142 * it, the free it up. (Leak the memory if anything goes wrong here.)
137143 */
138
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_HYPERVISOR_INFO);
144
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_HYPERVISOR_INFO,
145
+ VBG_KERNEL_REQUEST);
139146 if (!req)
140147 return;
141148
....@@ -172,8 +179,10 @@
172179 struct vmmdev_guest_info2 *req2 = NULL;
173180 int rc, ret = -ENOMEM;
174181
175
- req1 = vbg_req_alloc(sizeof(*req1), VMMDEVREQ_REPORT_GUEST_INFO);
176
- req2 = vbg_req_alloc(sizeof(*req2), VMMDEVREQ_REPORT_GUEST_INFO2);
182
+ req1 = vbg_req_alloc(sizeof(*req1), VMMDEVREQ_REPORT_GUEST_INFO,
183
+ VBG_KERNEL_REQUEST);
184
+ req2 = vbg_req_alloc(sizeof(*req2), VMMDEVREQ_REPORT_GUEST_INFO2,
185
+ VBG_KERNEL_REQUEST);
177186 if (!req1 || !req2)
178187 goto out_free;
179188
....@@ -187,8 +196,8 @@
187196 req2->additions_minor = VBG_VERSION_MINOR;
188197 req2->additions_build = VBG_VERSION_BUILD;
189198 req2->additions_revision = VBG_SVN_REV;
190
- /* (no features defined yet) */
191
- req2->additions_features = 0;
199
+ req2->additions_features =
200
+ VMMDEV_GUEST_INFO2_ADDITIONS_FEATURES_REQUESTOR_INFO;
192201 strlcpy(req2->name, VBG_VERSION_STRING,
193202 sizeof(req2->name));
194203
....@@ -230,7 +239,8 @@
230239 struct vmmdev_guest_status *req;
231240 int rc;
232241
233
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_REPORT_GUEST_STATUS);
242
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_REPORT_GUEST_STATUS,
243
+ VBG_KERNEL_REQUEST);
234244 if (!req)
235245 return -ENOMEM;
236246
....@@ -423,7 +433,8 @@
423433 struct vmmdev_heartbeat *req;
424434 int rc;
425435
426
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_HEARTBEAT_CONFIGURE);
436
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_HEARTBEAT_CONFIGURE,
437
+ VBG_KERNEL_REQUEST);
427438 if (!req)
428439 return -ENOMEM;
429440
....@@ -457,7 +468,8 @@
457468
458469 gdev->guest_heartbeat_req = vbg_req_alloc(
459470 sizeof(*gdev->guest_heartbeat_req),
460
- VMMDEVREQ_GUEST_HEARTBEAT);
471
+ VMMDEVREQ_GUEST_HEARTBEAT,
472
+ VBG_KERNEL_REQUEST);
461473 if (!gdev->guest_heartbeat_req)
462474 return -ENOMEM;
463475
....@@ -528,7 +540,8 @@
528540 struct vmmdev_mask *req;
529541 int rc;
530542
531
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_CTL_GUEST_FILTER_MASK);
543
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_CTL_GUEST_FILTER_MASK,
544
+ VBG_KERNEL_REQUEST);
532545 if (!req)
533546 return -ENOMEM;
534547
....@@ -546,7 +559,7 @@
546559 * Changes the event filter mask for the given session.
547560 *
548561 * This is called in response to VBG_IOCTL_CHANGE_FILTER_MASK as well as to
549
- * do session cleanup. Takes the session spinlock.
562
+ * do session cleanup. Takes the session mutex.
550563 *
551564 * Return: 0 or negative errno value.
552565 * @gdev: The Guest extension device.
....@@ -567,8 +580,14 @@
567580 u32 changed, previous;
568581 int rc, ret = 0;
569582
570
- /* Allocate a request buffer before taking the spinlock */
571
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_CTL_GUEST_FILTER_MASK);
583
+ /*
584
+ * Allocate a request buffer before taking the spinlock, when
585
+ * the session is being terminated the requestor is the kernel,
586
+ * as we're cleaning up.
587
+ */
588
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_CTL_GUEST_FILTER_MASK,
589
+ session_termination ? VBG_KERNEL_REQUEST :
590
+ session->requestor);
572591 if (!req) {
573592 if (!session_termination)
574593 return -ENOMEM;
....@@ -627,7 +646,8 @@
627646 struct vmmdev_mask *req;
628647 int rc;
629648
630
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES);
649
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES,
650
+ VBG_KERNEL_REQUEST);
631651 if (!req)
632652 return -ENOMEM;
633653
....@@ -642,7 +662,156 @@
642662 }
643663
644664 /**
645
- * Sets the guest capabilities for a session. Takes the session spinlock.
665
+ * Set guest capabilities on the host.
666
+ * Must be called with gdev->session_mutex hold.
667
+ * Return: 0 or negative errno value.
668
+ * @gdev: The Guest extension device.
669
+ * @session: The session.
670
+ * @session_termination: Set if we're called by the session cleanup code.
671
+ */
672
+static int vbg_set_host_capabilities(struct vbg_dev *gdev,
673
+ struct vbg_session *session,
674
+ bool session_termination)
675
+{
676
+ struct vmmdev_mask *req;
677
+ u32 caps;
678
+ int rc;
679
+
680
+ WARN_ON(!mutex_is_locked(&gdev->session_mutex));
681
+
682
+ caps = gdev->acquired_guest_caps | gdev->set_guest_caps_tracker.mask;
683
+
684
+ if (gdev->guest_caps_host == caps)
685
+ return 0;
686
+
687
+ /* On termination the requestor is the kernel, as we're cleaning up. */
688
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES,
689
+ session_termination ? VBG_KERNEL_REQUEST :
690
+ session->requestor);
691
+ if (!req) {
692
+ gdev->guest_caps_host = U32_MAX;
693
+ return -ENOMEM;
694
+ }
695
+
696
+ req->or_mask = caps;
697
+ req->not_mask = ~caps;
698
+ rc = vbg_req_perform(gdev, req);
699
+ vbg_req_free(req, sizeof(*req));
700
+
701
+ gdev->guest_caps_host = (rc >= 0) ? caps : U32_MAX;
702
+
703
+ return vbg_status_code_to_errno(rc);
704
+}
705
+
706
+/**
707
+ * Acquire (get exclusive access) guest capabilities for a session.
708
+ * Takes the session mutex.
709
+ * Return: 0 or negative errno value.
710
+ * @gdev: The Guest extension device.
711
+ * @session: The session.
712
+ * @flags: Flags (VBGL_IOC_AGC_FLAGS_XXX).
713
+ * @or_mask: The capabilities to add.
714
+ * @not_mask: The capabilities to remove.
715
+ * @session_termination: Set if we're called by the session cleanup code.
716
+ * This tweaks the error handling so we perform
717
+ * proper session cleanup even if the host
718
+ * misbehaves.
719
+ */
720
+static int vbg_acquire_session_capabilities(struct vbg_dev *gdev,
721
+ struct vbg_session *session,
722
+ u32 or_mask, u32 not_mask,
723
+ u32 flags, bool session_termination)
724
+{
725
+ unsigned long irqflags;
726
+ bool wakeup = false;
727
+ int ret = 0;
728
+
729
+ mutex_lock(&gdev->session_mutex);
730
+
731
+ if (gdev->set_guest_caps_tracker.mask & or_mask) {
732
+ vbg_err("%s error: cannot acquire caps which are currently set\n",
733
+ __func__);
734
+ ret = -EINVAL;
735
+ goto out;
736
+ }
737
+
738
+ /*
739
+ * Mark any caps in the or_mask as now being in acquire-mode. Note
740
+ * once caps are in acquire_mode they always stay in this mode.
741
+ * This impacts event handling, so we take the event-lock.
742
+ */
743
+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
744
+ gdev->acquire_mode_guest_caps |= or_mask;
745
+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
746
+
747
+ /* If we only have to switch the caps to acquire mode, we're done. */
748
+ if (flags & VBGL_IOC_AGC_FLAGS_CONFIG_ACQUIRE_MODE)
749
+ goto out;
750
+
751
+ not_mask &= ~or_mask; /* or_mask takes priority over not_mask */
752
+ not_mask &= session->acquired_guest_caps;
753
+ or_mask &= ~session->acquired_guest_caps;
754
+
755
+ if (or_mask == 0 && not_mask == 0)
756
+ goto out;
757
+
758
+ if (gdev->acquired_guest_caps & or_mask) {
759
+ ret = -EBUSY;
760
+ goto out;
761
+ }
762
+
763
+ gdev->acquired_guest_caps |= or_mask;
764
+ gdev->acquired_guest_caps &= ~not_mask;
765
+ /* session->acquired_guest_caps impacts event handling, take the lock */
766
+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
767
+ session->acquired_guest_caps |= or_mask;
768
+ session->acquired_guest_caps &= ~not_mask;
769
+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
770
+
771
+ ret = vbg_set_host_capabilities(gdev, session, session_termination);
772
+ /* Roll back on failure, unless it's session termination time. */
773
+ if (ret < 0 && !session_termination) {
774
+ gdev->acquired_guest_caps &= ~or_mask;
775
+ gdev->acquired_guest_caps |= not_mask;
776
+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
777
+ session->acquired_guest_caps &= ~or_mask;
778
+ session->acquired_guest_caps |= not_mask;
779
+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
780
+ }
781
+
782
+ /*
783
+ * If we added a capability, check if that means some other thread in
784
+ * our session should be unblocked because there are events pending
785
+ * (the result of vbg_get_allowed_event_mask_for_session() may change).
786
+ *
787
+ * HACK ALERT! When the seamless support capability is added we generate
788
+ * a seamless change event so that the ring-3 client can sync with
789
+ * the seamless state.
790
+ */
791
+ if (ret == 0 && or_mask != 0) {
792
+ spin_lock_irqsave(&gdev->event_spinlock, irqflags);
793
+
794
+ if (or_mask & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
795
+ gdev->pending_events |=
796
+ VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
797
+
798
+ if (gdev->pending_events)
799
+ wakeup = true;
800
+
801
+ spin_unlock_irqrestore(&gdev->event_spinlock, irqflags);
802
+
803
+ if (wakeup)
804
+ wake_up(&gdev->event_wq);
805
+ }
806
+
807
+out:
808
+ mutex_unlock(&gdev->session_mutex);
809
+
810
+ return ret;
811
+}
812
+
813
+/**
814
+ * Sets the guest capabilities for a session. Takes the session mutex.
646815 * Return: 0 or negative errno value.
647816 * @gdev: The Guest extension device.
648817 * @session: The session.
....@@ -658,56 +827,40 @@
658827 u32 or_mask, u32 not_mask,
659828 bool session_termination)
660829 {
661
- struct vmmdev_mask *req;
662830 u32 changed, previous;
663
- int rc, ret = 0;
664
-
665
- /* Allocate a request buffer before taking the spinlock */
666
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES);
667
- if (!req) {
668
- if (!session_termination)
669
- return -ENOMEM;
670
- /* Ignore allocation failure, we must do session cleanup. */
671
- }
831
+ int ret = 0;
672832
673833 mutex_lock(&gdev->session_mutex);
674834
835
+ if (gdev->acquire_mode_guest_caps & or_mask) {
836
+ vbg_err("%s error: cannot set caps which are in acquire_mode\n",
837
+ __func__);
838
+ ret = -EBUSY;
839
+ goto out;
840
+ }
841
+
675842 /* Apply the changes to the session mask. */
676
- previous = session->guest_caps;
677
- session->guest_caps |= or_mask;
678
- session->guest_caps &= ~not_mask;
843
+ previous = session->set_guest_caps;
844
+ session->set_guest_caps |= or_mask;
845
+ session->set_guest_caps &= ~not_mask;
679846
680847 /* If anything actually changed, update the global usage counters. */
681
- changed = previous ^ session->guest_caps;
848
+ changed = previous ^ session->set_guest_caps;
682849 if (!changed)
683850 goto out;
684851
685
- vbg_track_bit_usage(&gdev->guest_caps_tracker, changed, previous);
686
- or_mask = gdev->guest_caps_tracker.mask;
852
+ vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed, previous);
687853
688
- if (gdev->guest_caps_host == or_mask || !req)
689
- goto out;
690
-
691
- gdev->guest_caps_host = or_mask;
692
- req->or_mask = or_mask;
693
- req->not_mask = ~or_mask;
694
- rc = vbg_req_perform(gdev, req);
695
- if (rc < 0) {
696
- ret = vbg_status_code_to_errno(rc);
697
-
698
- /* Failed, roll back (unless it's session termination time). */
699
- gdev->guest_caps_host = U32_MAX;
700
- if (session_termination)
701
- goto out;
702
-
703
- vbg_track_bit_usage(&gdev->guest_caps_tracker, changed,
704
- session->guest_caps);
705
- session->guest_caps = previous;
854
+ ret = vbg_set_host_capabilities(gdev, session, session_termination);
855
+ /* Roll back on failure, unless it's session termination time. */
856
+ if (ret < 0 && !session_termination) {
857
+ vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed,
858
+ session->set_guest_caps);
859
+ session->set_guest_caps = previous;
706860 }
707861
708862 out:
709863 mutex_unlock(&gdev->session_mutex);
710
- vbg_req_free(req, sizeof(*req));
711864
712865 return ret;
713866 }
....@@ -722,7 +875,8 @@
722875 struct vmmdev_host_version *req;
723876 int rc, ret;
724877
725
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_GET_HOST_VERSION);
878
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_GET_HOST_VERSION,
879
+ VBG_KERNEL_REQUEST);
726880 if (!req)
727881 return -ENOMEM;
728882
....@@ -783,19 +937,24 @@
783937
784938 gdev->mem_balloon.get_req =
785939 vbg_req_alloc(sizeof(*gdev->mem_balloon.get_req),
786
- VMMDEVREQ_GET_MEMBALLOON_CHANGE_REQ);
940
+ VMMDEVREQ_GET_MEMBALLOON_CHANGE_REQ,
941
+ VBG_KERNEL_REQUEST);
787942 gdev->mem_balloon.change_req =
788943 vbg_req_alloc(sizeof(*gdev->mem_balloon.change_req),
789
- VMMDEVREQ_CHANGE_MEMBALLOON);
944
+ VMMDEVREQ_CHANGE_MEMBALLOON,
945
+ VBG_KERNEL_REQUEST);
790946 gdev->cancel_req =
791947 vbg_req_alloc(sizeof(*(gdev->cancel_req)),
792
- VMMDEVREQ_HGCM_CANCEL2);
948
+ VMMDEVREQ_HGCM_CANCEL2,
949
+ VBG_KERNEL_REQUEST);
793950 gdev->ack_events_req =
794951 vbg_req_alloc(sizeof(*gdev->ack_events_req),
795
- VMMDEVREQ_ACKNOWLEDGE_EVENTS);
952
+ VMMDEVREQ_ACKNOWLEDGE_EVENTS,
953
+ VBG_KERNEL_REQUEST);
796954 gdev->mouse_status_req =
797955 vbg_req_alloc(sizeof(*gdev->mouse_status_req),
798
- VMMDEVREQ_GET_MOUSE_STATUS);
956
+ VMMDEVREQ_GET_MOUSE_STATUS,
957
+ VBG_KERNEL_REQUEST);
799958
800959 if (!gdev->mem_balloon.get_req || !gdev->mem_balloon.change_req ||
801960 !gdev->cancel_req || !gdev->ack_events_req ||
....@@ -892,9 +1051,9 @@
8921051 * vboxguest_linux.c calls this when userspace opens the char-device.
8931052 * Return: A pointer to the new session or an ERR_PTR on error.
8941053 * @gdev: The Guest extension device.
895
- * @user: Set if this is a session for the vboxuser device.
1054
+ * @requestor: VMMDEV_REQUESTOR_* flags
8961055 */
897
-struct vbg_session *vbg_core_open_session(struct vbg_dev *gdev, bool user)
1056
+struct vbg_session *vbg_core_open_session(struct vbg_dev *gdev, u32 requestor)
8981057 {
8991058 struct vbg_session *session;
9001059
....@@ -903,7 +1062,7 @@
9031062 return ERR_PTR(-ENOMEM);
9041063
9051064 session->gdev = gdev;
906
- session->user_session = user;
1065
+ session->requestor = requestor;
9071066
9081067 return session;
9091068 }
....@@ -917,6 +1076,7 @@
9171076 struct vbg_dev *gdev = session->gdev;
9181077 int i, rc;
9191078
1079
+ vbg_acquire_session_capabilities(gdev, session, 0, U32_MAX, 0, true);
9201080 vbg_set_session_capabilities(gdev, session, 0, U32_MAX, true);
9211081 vbg_set_session_event_filter(gdev, session, 0, U32_MAX, true);
9221082
....@@ -924,7 +1084,9 @@
9241084 if (!session->hgcm_client_ids[i])
9251085 continue;
9261086
927
- vbg_hgcm_disconnect(gdev, session->hgcm_client_ids[i], &rc);
1087
+ /* requestor is kernel here, as we're cleaning up. */
1088
+ vbg_hgcm_disconnect(gdev, VBG_KERNEL_REQUEST,
1089
+ session->hgcm_client_ids[i], &rc);
9281090 }
9291091
9301092 kfree(session);
....@@ -972,6 +1134,25 @@
9721134 return 0;
9731135 }
9741136
1137
+/* Must be called with the event_lock held */
1138
+static u32 vbg_get_allowed_event_mask_for_session(struct vbg_dev *gdev,
1139
+ struct vbg_session *session)
1140
+{
1141
+ u32 acquire_mode_caps = gdev->acquire_mode_guest_caps;
1142
+ u32 session_acquired_caps = session->acquired_guest_caps;
1143
+ u32 allowed_events = VMMDEV_EVENT_VALID_EVENT_MASK;
1144
+
1145
+ if ((acquire_mode_caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS) &&
1146
+ !(session_acquired_caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS))
1147
+ allowed_events &= ~VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
1148
+
1149
+ if ((acquire_mode_caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS) &&
1150
+ !(session_acquired_caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS))
1151
+ allowed_events &= ~VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
1152
+
1153
+ return allowed_events;
1154
+}
1155
+
9751156 static bool vbg_wait_event_cond(struct vbg_dev *gdev,
9761157 struct vbg_session *session,
9771158 u32 event_mask)
....@@ -983,6 +1164,7 @@
9831164 spin_lock_irqsave(&gdev->event_spinlock, flags);
9841165
9851166 events = gdev->pending_events & event_mask;
1167
+ events &= vbg_get_allowed_event_mask_for_session(gdev, session);
9861168 wakeup = events || session->cancel_waiters;
9871169
9881170 spin_unlock_irqrestore(&gdev->event_spinlock, flags);
....@@ -997,6 +1179,7 @@
9971179 {
9981180 u32 events = gdev->pending_events & event_mask;
9991181
1182
+ events &= vbg_get_allowed_event_mask_for_session(gdev, session);
10001183 gdev->pending_events &= ~events;
10011184 return events;
10021185 }
....@@ -1116,7 +1299,9 @@
11161299 case VMMDEVREQ_VIDEO_ACCEL_ENABLE:
11171300 case VMMDEVREQ_VIDEO_ACCEL_FLUSH:
11181301 case VMMDEVREQ_VIDEO_SET_VISIBLE_REGION:
1302
+ case VMMDEVREQ_VIDEO_UPDATE_MONITOR_POSITIONS:
11191303 case VMMDEVREQ_GET_DISPLAY_CHANGE_REQEX:
1304
+ case VMMDEVREQ_GET_DISPLAY_CHANGE_REQ_MULTI:
11201305 case VMMDEVREQ_GET_SEAMLESS_CHANGE_REQ:
11211306 case VMMDEVREQ_GET_VRDPCHANGE_REQ:
11221307 case VMMDEVREQ_LOG_STRING:
....@@ -1152,7 +1337,8 @@
11521337 return -EPERM;
11531338 }
11541339
1155
- if (trusted_apps_only && session->user_session) {
1340
+ if (trusted_apps_only &&
1341
+ (session->requestor & VMMDEV_REQUESTOR_USER_DEVICE)) {
11561342 vbg_err("Denying userspace vmm call type %#08x through vboxuser device node\n",
11571343 req->request_type);
11581344 return -EPERM;
....@@ -1209,8 +1395,8 @@
12091395 if (i >= ARRAY_SIZE(session->hgcm_client_ids))
12101396 return -EMFILE;
12111397
1212
- ret = vbg_hgcm_connect(gdev, &conn->u.in.loc, &client_id,
1213
- &conn->hdr.rc);
1398
+ ret = vbg_hgcm_connect(gdev, session->requestor, &conn->u.in.loc,
1399
+ &client_id, &conn->hdr.rc);
12141400
12151401 mutex_lock(&gdev->session_mutex);
12161402 if (ret == 0 && conn->hdr.rc >= 0) {
....@@ -1251,7 +1437,8 @@
12511437 if (i >= ARRAY_SIZE(session->hgcm_client_ids))
12521438 return -EINVAL;
12531439
1254
- ret = vbg_hgcm_disconnect(gdev, client_id, &disconn->hdr.rc);
1440
+ ret = vbg_hgcm_disconnect(gdev, session->requestor, client_id,
1441
+ &disconn->hdr.rc);
12551442
12561443 mutex_lock(&gdev->session_mutex);
12571444 if (ret == 0 && disconn->hdr.rc >= 0)
....@@ -1344,12 +1531,12 @@
13441531 }
13451532
13461533 if (IS_ENABLED(CONFIG_COMPAT) && f32bit)
1347
- ret = vbg_hgcm_call32(gdev, client_id,
1534
+ ret = vbg_hgcm_call32(gdev, session->requestor, client_id,
13481535 call->function, call->timeout_ms,
13491536 VBG_IOCTL_HGCM_CALL_PARMS32(call),
13501537 call->parm_count, &call->hdr.rc);
13511538 else
1352
- ret = vbg_hgcm_call(gdev, client_id,
1539
+ ret = vbg_hgcm_call(gdev, session->requestor, client_id,
13531540 call->function, call->timeout_ms,
13541541 VBG_IOCTL_HGCM_CALL_PARMS(call),
13551542 call->parm_count, &call->hdr.rc);
....@@ -1396,6 +1583,29 @@
13961583 false);
13971584 }
13981585
1586
+static int vbg_ioctl_acquire_guest_capabilities(struct vbg_dev *gdev,
1587
+ struct vbg_session *session,
1588
+ struct vbg_ioctl_acquire_guest_caps *caps)
1589
+{
1590
+ u32 flags, or_mask, not_mask;
1591
+
1592
+ if (vbg_ioctl_chk(&caps->hdr, sizeof(caps->u.in), 0))
1593
+ return -EINVAL;
1594
+
1595
+ flags = caps->u.in.flags;
1596
+ or_mask = caps->u.in.or_mask;
1597
+ not_mask = caps->u.in.not_mask;
1598
+
1599
+ if (flags & ~VBGL_IOC_AGC_FLAGS_VALID_MASK)
1600
+ return -EINVAL;
1601
+
1602
+ if ((or_mask | not_mask) & ~VMMDEV_GUEST_CAPABILITIES_MASK)
1603
+ return -EINVAL;
1604
+
1605
+ return vbg_acquire_session_capabilities(gdev, session, or_mask,
1606
+ not_mask, flags, false);
1607
+}
1608
+
13991609 static int vbg_ioctl_change_guest_capabilities(struct vbg_dev *gdev,
14001610 struct vbg_session *session, struct vbg_ioctl_set_guest_caps *caps)
14011611 {
....@@ -1416,7 +1626,7 @@
14161626 if (ret)
14171627 return ret;
14181628
1419
- caps->u.out.session_caps = session->guest_caps;
1629
+ caps->u.out.session_caps = session->set_guest_caps;
14201630 caps->u.out.global_caps = gdev->guest_caps_host;
14211631
14221632 return 0;
....@@ -1439,6 +1649,7 @@
14391649 }
14401650
14411651 static int vbg_ioctl_write_core_dump(struct vbg_dev *gdev,
1652
+ struct vbg_session *session,
14421653 struct vbg_ioctl_write_coredump *dump)
14431654 {
14441655 struct vmmdev_write_core_dump *req;
....@@ -1446,7 +1657,8 @@
14461657 if (vbg_ioctl_chk(&dump->hdr, sizeof(dump->u.in), 0))
14471658 return -EINVAL;
14481659
1449
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_WRITE_COREDUMP);
1660
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_WRITE_COREDUMP,
1661
+ session->requestor);
14501662 if (!req)
14511663 return -ENOMEM;
14521664
....@@ -1503,12 +1715,14 @@
15031715 return vbg_ioctl_interrupt_all_wait_events(gdev, session, data);
15041716 case VBG_IOCTL_CHANGE_FILTER_MASK:
15051717 return vbg_ioctl_change_filter_mask(gdev, session, data);
1718
+ case VBG_IOCTL_ACQUIRE_GUEST_CAPABILITIES:
1719
+ return vbg_ioctl_acquire_guest_capabilities(gdev, session, data);
15061720 case VBG_IOCTL_CHANGE_GUEST_CAPABILITIES:
15071721 return vbg_ioctl_change_guest_capabilities(gdev, session, data);
15081722 case VBG_IOCTL_CHECK_BALLOON:
15091723 return vbg_ioctl_check_balloon(gdev, data);
15101724 case VBG_IOCTL_WRITE_CORE_DUMP:
1511
- return vbg_ioctl_write_core_dump(gdev, data);
1725
+ return vbg_ioctl_write_core_dump(gdev, session, data);
15121726 }
15131727
15141728 /* Variable sized requests. */
....@@ -1516,7 +1730,7 @@
15161730 #ifdef CONFIG_COMPAT
15171731 case VBG_IOCTL_HGCM_CALL_32(0):
15181732 f32bit = true;
1519
- /* Fall through */
1733
+ fallthrough;
15201734 #endif
15211735 case VBG_IOCTL_HGCM_CALL(0):
15221736 return vbg_ioctl_hgcm_call(gdev, session, f32bit, data);
....@@ -1525,7 +1739,7 @@
15251739 return vbg_ioctl_log(data);
15261740 }
15271741
1528
- vbg_debug("VGDrvCommonIoCtl: Unknown req %#08x\n", req);
1742
+ vbg_err_ratelimited("Userspace made an unknown ioctl req %#08x\n", req);
15291743 return -ENOTTY;
15301744 }
15311745
....@@ -1541,7 +1755,8 @@
15411755 struct vmmdev_mouse_status *req;
15421756 int rc;
15431757
1544
- req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_MOUSE_STATUS);
1758
+ req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_MOUSE_STATUS,
1759
+ VBG_KERNEL_REQUEST);
15451760 if (!req)
15461761 return -ENOMEM;
15471762