forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
....@@ -24,16 +24,16 @@
2424 *
2525 */
2626
27
-
28
-#include <linux/slab.h>
29
-#include <linux/module.h>
27
+#include <linux/objtool.h>
3028 #include <linux/kernel.h>
31
-#include <linux/frame.h>
29
+#include <linux/module.h>
30
+#include <linux/slab.h>
31
+#include <linux/mem_encrypt.h>
32
+
3233 #include <asm/hypervisor.h>
33
-#include <drm/drmP.h>
34
+
3435 #include "vmwgfx_drv.h"
3536 #include "vmwgfx_msg.h"
36
-
3737
3838 #define MESSAGE_STATUS_SUCCESS 0x0001
3939 #define MESSAGE_STATUS_DORECV 0x0002
....@@ -46,8 +46,6 @@
4646 #define RETRIES 3
4747
4848 #define VMW_HYPERVISOR_MAGIC 0x564D5868
49
-#define VMW_HYPERVISOR_PORT 0x5658
50
-#define VMW_HYPERVISOR_HB_PORT 0x5659
5149
5250 #define VMW_PORT_CMD_MSG 30
5351 #define VMW_PORT_CMD_HB_MSG 0
....@@ -58,6 +56,8 @@
5856 #define VMW_PORT_CMD_RECVSTATUS (MSG_TYPE_RECVSTATUS << 16 | VMW_PORT_CMD_MSG)
5957
6058 #define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16)
59
+
60
+#define MAX_USER_MSG_LENGTH PAGE_SIZE
6161
6262 static u32 vmw_msg_enabled = 1;
6363
....@@ -93,7 +93,7 @@
9393
9494 VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
9595 (protocol | GUESTMSG_FLAG_COOKIE), si, di,
96
- VMW_HYPERVISOR_PORT,
96
+ 0,
9797 VMW_HYPERVISOR_MAGIC,
9898 eax, ebx, ecx, edx, si, di);
9999
....@@ -126,7 +126,7 @@
126126
127127 VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
128128 0, si, di,
129
- (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
129
+ channel->channel_id << 16,
130130 VMW_HYPERVISOR_MAGIC,
131131 eax, ebx, ecx, edx, si, di);
132132
....@@ -151,7 +151,8 @@
151151 unsigned long si, di, eax, ebx, ecx, edx;
152152 unsigned long msg_len = strlen(msg);
153153
154
- if (hb) {
154
+ /* HB port can't access encrypted memory. */
155
+ if (hb && !mem_encrypt_active()) {
155156 unsigned long bp = channel->cookie_high;
156157
157158 si = (uintptr_t) msg;
....@@ -160,7 +161,8 @@
160161 VMW_PORT_HB_OUT(
161162 (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
162163 msg_len, si, di,
163
- VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
164
+ VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) |
165
+ VMWARE_HYPERVISOR_OUT,
164166 VMW_HYPERVISOR_MAGIC, bp,
165167 eax, ebx, ecx, edx, si, di);
166168
....@@ -181,7 +183,7 @@
181183
182184 VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
183185 word, si, di,
184
- VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
186
+ channel->channel_id << 16,
185187 VMW_HYPERVISOR_MAGIC,
186188 eax, ebx, ecx, edx, si, di);
187189 }
....@@ -204,7 +206,8 @@
204206 {
205207 unsigned long si, di, eax, ebx, ecx, edx;
206208
207
- if (hb) {
209
+ /* HB port can't access encrypted memory */
210
+ if (hb && !mem_encrypt_active()) {
208211 unsigned long bp = channel->cookie_low;
209212
210213 si = channel->cookie_high;
....@@ -213,7 +216,7 @@
213216 VMW_PORT_HB_IN(
214217 (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
215218 reply_len, si, di,
216
- VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
219
+ VMWARE_HYPERVISOR_HB | (channel->channel_id << 16),
217220 VMW_HYPERVISOR_MAGIC, bp,
218221 eax, ebx, ecx, edx, si, di);
219222
....@@ -230,7 +233,7 @@
230233
231234 VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16),
232235 MESSAGE_STATUS_SUCCESS, si, di,
233
- VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
236
+ channel->channel_id << 16,
234237 VMW_HYPERVISOR_MAGIC,
235238 eax, ebx, ecx, edx, si, di);
236239
....@@ -269,7 +272,7 @@
269272
270273 VMW_PORT(VMW_PORT_CMD_SENDSIZE,
271274 msg_len, si, di,
272
- VMW_HYPERVISOR_PORT | (channel->channel_id << 16),
275
+ channel->channel_id << 16,
273276 VMW_HYPERVISOR_MAGIC,
274277 eax, ebx, ecx, edx, si, di);
275278
....@@ -327,7 +330,7 @@
327330
328331 VMW_PORT(VMW_PORT_CMD_RECVSIZE,
329332 0, si, di,
330
- (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
333
+ channel->channel_id << 16,
331334 VMW_HYPERVISOR_MAGIC,
332335 eax, ebx, ecx, edx, si, di);
333336
....@@ -371,7 +374,7 @@
371374
372375 VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
373376 MESSAGE_STATUS_SUCCESS, si, di,
374
- (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
377
+ channel->channel_id << 16,
375378 VMW_HYPERVISOR_MAGIC,
376379 eax, ebx, ecx, edx, si, di);
377380
....@@ -516,3 +519,83 @@
516519
517520 return -EINVAL;
518521 }
522
+
523
+
524
+/**
525
+ * vmw_msg_ioctl: Sends and receveives a message to/from host from/to user-space
526
+ *
527
+ * Sends a message from user-space to host.
528
+ * Can also receive a result from host and return that to user-space.
529
+ *
530
+ * @dev: Identifies the drm device.
531
+ * @data: Pointer to the ioctl argument.
532
+ * @file_priv: Identifies the caller.
533
+ * Return: Zero on success, negative error code on error.
534
+ */
535
+
536
+int vmw_msg_ioctl(struct drm_device *dev, void *data,
537
+ struct drm_file *file_priv)
538
+{
539
+ struct drm_vmw_msg_arg *arg =
540
+ (struct drm_vmw_msg_arg *) data;
541
+ struct rpc_channel channel;
542
+ char *msg;
543
+ int length;
544
+
545
+ msg = kmalloc(MAX_USER_MSG_LENGTH, GFP_KERNEL);
546
+ if (!msg) {
547
+ DRM_ERROR("Cannot allocate memory for log message.\n");
548
+ return -ENOMEM;
549
+ }
550
+
551
+ length = strncpy_from_user(msg, (void __user *)((unsigned long)arg->send),
552
+ MAX_USER_MSG_LENGTH);
553
+ if (length < 0 || length >= MAX_USER_MSG_LENGTH) {
554
+ DRM_ERROR("Userspace message access failure.\n");
555
+ kfree(msg);
556
+ return -EINVAL;
557
+ }
558
+
559
+
560
+ if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) {
561
+ DRM_ERROR("Failed to open channel.\n");
562
+ goto out_open;
563
+ }
564
+
565
+ if (vmw_send_msg(&channel, msg)) {
566
+ DRM_ERROR("Failed to send message to host.\n");
567
+ goto out_msg;
568
+ }
569
+
570
+ if (!arg->send_only) {
571
+ char *reply = NULL;
572
+ size_t reply_len = 0;
573
+
574
+ if (vmw_recv_msg(&channel, (void *) &reply, &reply_len)) {
575
+ DRM_ERROR("Failed to receive message from host.\n");
576
+ goto out_msg;
577
+ }
578
+ if (reply && reply_len > 0) {
579
+ if (copy_to_user((void __user *)((unsigned long)arg->receive),
580
+ reply, reply_len)) {
581
+ DRM_ERROR("Failed to copy message to userspace.\n");
582
+ kfree(reply);
583
+ goto out_msg;
584
+ }
585
+ arg->receive_len = (__u32)reply_len;
586
+ }
587
+ kfree(reply);
588
+ }
589
+
590
+ vmw_close_channel(&channel);
591
+ kfree(msg);
592
+
593
+ return 0;
594
+
595
+out_msg:
596
+ vmw_close_channel(&channel);
597
+out_open:
598
+ kfree(msg);
599
+
600
+ return -EINVAL;
601
+}