Merge branch 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / drivers / gpu / drm / vmwgfx / vmwgfx_msg.c
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3  * Copyright 2016 VMware, Inc., Palo Alto, CA., USA
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23  * USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  */
26
27 #include <linux/objtool.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/slab.h>
31 #include <linux/mem_encrypt.h>
32
33 #include <asm/hypervisor.h>
34
35 #include "vmwgfx_drv.h"
36 #include "vmwgfx_msg_x86.h"
37 #include "vmwgfx_msg_arm64.h"
38
39 #define MESSAGE_STATUS_SUCCESS  0x0001
40 #define MESSAGE_STATUS_DORECV   0x0002
41 #define MESSAGE_STATUS_CPT      0x0010
42 #define MESSAGE_STATUS_HB       0x0080
43
44 #define RPCI_PROTOCOL_NUM       0x49435052
45 #define GUESTMSG_FLAG_COOKIE    0x80000000
46
47 #define RETRIES                 3
48
49 #define VMW_HYPERVISOR_MAGIC    0x564D5868
50
51 #define VMW_PORT_CMD_MSG        30
52 #define VMW_PORT_CMD_HB_MSG     0
53 #define VMW_PORT_CMD_OPEN_CHANNEL  (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
54 #define VMW_PORT_CMD_CLOSE_CHANNEL (MSG_TYPE_CLOSE << 16 | VMW_PORT_CMD_MSG)
55 #define VMW_PORT_CMD_SENDSIZE   (MSG_TYPE_SENDSIZE << 16 | VMW_PORT_CMD_MSG)
56 #define VMW_PORT_CMD_RECVSIZE   (MSG_TYPE_RECVSIZE << 16 | VMW_PORT_CMD_MSG)
57 #define VMW_PORT_CMD_RECVSTATUS (MSG_TYPE_RECVSTATUS << 16 | VMW_PORT_CMD_MSG)
58
59 #define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16)
60
61 #define MAX_USER_MSG_LENGTH     PAGE_SIZE
62
63 static u32 vmw_msg_enabled = 1;
64
65 enum rpc_msg_type {
66         MSG_TYPE_OPEN,
67         MSG_TYPE_SENDSIZE,
68         MSG_TYPE_SENDPAYLOAD,
69         MSG_TYPE_RECVSIZE,
70         MSG_TYPE_RECVPAYLOAD,
71         MSG_TYPE_RECVSTATUS,
72         MSG_TYPE_CLOSE,
73 };
74
75 struct rpc_channel {
76         u16 channel_id;
77         u32 cookie_high;
78         u32 cookie_low;
79 };
80
81
82
83 /**
84  * vmw_open_channel
85  *
86  * @channel: RPC channel
87  * @protocol:
88  *
89  * Returns: 0 on success
90  */
91 static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
92 {
93         unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
94
95         VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
96                 (protocol | GUESTMSG_FLAG_COOKIE), si, di,
97                 0,
98                 VMW_HYPERVISOR_MAGIC,
99                 eax, ebx, ecx, edx, si, di);
100
101         if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
102                 return -EINVAL;
103
104         channel->channel_id  = HIGH_WORD(edx);
105         channel->cookie_high = si;
106         channel->cookie_low  = di;
107
108         return 0;
109 }
110
111
112
113 /**
114  * vmw_close_channel
115  *
116  * @channel: RPC channel
117  *
118  * Returns: 0 on success
119  */
120 static int vmw_close_channel(struct rpc_channel *channel)
121 {
122         unsigned long eax, ebx, ecx, edx, si, di;
123
124         /* Set up additional parameters */
125         si  = channel->cookie_high;
126         di  = channel->cookie_low;
127
128         VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
129                 0, si, di,
130                 channel->channel_id << 16,
131                 VMW_HYPERVISOR_MAGIC,
132                 eax, ebx, ecx, edx, si, di);
133
134         if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
135                 return -EINVAL;
136
137         return 0;
138 }
139
140 /**
141  * vmw_port_hb_out - Send the message payload either through the
142  * high-bandwidth port if available, or through the backdoor otherwise.
143  * @channel: The rpc channel.
144  * @msg: NULL-terminated message.
145  * @hb: Whether the high-bandwidth port is available.
146  *
147  * Return: The port status.
148  */
149 static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
150                                      const char *msg, bool hb)
151 {
152         unsigned long si, di, eax, ebx, ecx, edx;
153         unsigned long msg_len = strlen(msg);
154
155         /* HB port can't access encrypted memory. */
156         if (hb && !mem_encrypt_active()) {
157                 unsigned long bp = channel->cookie_high;
158
159                 si = (uintptr_t) msg;
160                 di = channel->cookie_low;
161
162                 VMW_PORT_HB_OUT(
163                         (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
164                         msg_len, si, di,
165                         VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) |
166                         VMWARE_HYPERVISOR_OUT,
167                         VMW_HYPERVISOR_MAGIC, bp,
168                         eax, ebx, ecx, edx, si, di);
169
170                 return ebx;
171         }
172
173         /* HB port not available. Send the message 4 bytes at a time. */
174         ecx = MESSAGE_STATUS_SUCCESS << 16;
175         while (msg_len && (HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS)) {
176                 unsigned int bytes = min_t(size_t, msg_len, 4);
177                 unsigned long word = 0;
178
179                 memcpy(&word, msg, bytes);
180                 msg_len -= bytes;
181                 msg += bytes;
182                 si = channel->cookie_high;
183                 di = channel->cookie_low;
184
185                 VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
186                          word, si, di,
187                          channel->channel_id << 16,
188                          VMW_HYPERVISOR_MAGIC,
189                          eax, ebx, ecx, edx, si, di);
190         }
191
192         return ecx;
193 }
194
195 /**
196  * vmw_port_hb_in - Receive the message payload either through the
197  * high-bandwidth port if available, or through the backdoor otherwise.
198  * @channel: The rpc channel.
199  * @reply: Pointer to buffer holding reply.
200  * @reply_len: Length of the reply.
201  * @hb: Whether the high-bandwidth port is available.
202  *
203  * Return: The port status.
204  */
205 static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
206                                     unsigned long reply_len, bool hb)
207 {
208         unsigned long si, di, eax, ebx, ecx, edx;
209
210         /* HB port can't access encrypted memory */
211         if (hb && !mem_encrypt_active()) {
212                 unsigned long bp = channel->cookie_low;
213
214                 si = channel->cookie_high;
215                 di = (uintptr_t) reply;
216
217                 VMW_PORT_HB_IN(
218                         (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
219                         reply_len, si, di,
220                         VMWARE_HYPERVISOR_HB | (channel->channel_id << 16),
221                         VMW_HYPERVISOR_MAGIC, bp,
222                         eax, ebx, ecx, edx, si, di);
223
224                 return ebx;
225         }
226
227         /* HB port not available. Retrieve the message 4 bytes at a time. */
228         ecx = MESSAGE_STATUS_SUCCESS << 16;
229         while (reply_len) {
230                 unsigned int bytes = min_t(unsigned long, reply_len, 4);
231
232                 si = channel->cookie_high;
233                 di = channel->cookie_low;
234
235                 VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16),
236                          MESSAGE_STATUS_SUCCESS, si, di,
237                          channel->channel_id << 16,
238                          VMW_HYPERVISOR_MAGIC,
239                          eax, ebx, ecx, edx, si, di);
240
241                 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
242                         break;
243
244                 memcpy(reply, &ebx, bytes);
245                 reply_len -= bytes;
246                 reply += bytes;
247         }
248
249         return ecx;
250 }
251
252
253 /**
254  * vmw_send_msg: Sends a message to the host
255  *
256  * @channel: RPC channel
257  * @msg: NULL terminated string
258  *
259  * Returns: 0 on success
260  */
261 static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
262 {
263         unsigned long eax, ebx, ecx, edx, si, di;
264         size_t msg_len = strlen(msg);
265         int retries = 0;
266
267         while (retries < RETRIES) {
268                 retries++;
269
270                 /* Set up additional parameters */
271                 si  = channel->cookie_high;
272                 di  = channel->cookie_low;
273
274                 VMW_PORT(VMW_PORT_CMD_SENDSIZE,
275                         msg_len, si, di,
276                         channel->channel_id << 16,
277                         VMW_HYPERVISOR_MAGIC,
278                         eax, ebx, ecx, edx, si, di);
279
280                 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
281                         /* Expected success. Give up. */
282                         return -EINVAL;
283                 }
284
285                 /* Send msg */
286                 ebx = vmw_port_hb_out(channel, msg,
287                                       !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
288
289                 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) {
290                         return 0;
291                 } else if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) {
292                         /* A checkpoint occurred. Retry. */
293                         continue;
294                 } else {
295                         break;
296                 }
297         }
298
299         return -EINVAL;
300 }
301 STACK_FRAME_NON_STANDARD(vmw_send_msg);
302
303
304 /**
305  * vmw_recv_msg: Receives a message from the host
306  *
307  * Note:  It is the caller's responsibility to call kfree() on msg.
308  *
309  * @channel:  channel opened by vmw_open_channel
310  * @msg:  [OUT] message received from the host
311  * @msg_len: message length
312  */
313 static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
314                         size_t *msg_len)
315 {
316         unsigned long eax, ebx, ecx, edx, si, di;
317         char *reply;
318         size_t reply_len;
319         int retries = 0;
320
321
322         *msg_len = 0;
323         *msg = NULL;
324
325         while (retries < RETRIES) {
326                 retries++;
327
328                 /* Set up additional parameters */
329                 si  = channel->cookie_high;
330                 di  = channel->cookie_low;
331
332                 VMW_PORT(VMW_PORT_CMD_RECVSIZE,
333                         0, si, di,
334                         channel->channel_id << 16,
335                         VMW_HYPERVISOR_MAGIC,
336                         eax, ebx, ecx, edx, si, di);
337
338                 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
339                         DRM_ERROR("Failed to get reply size for host message.\n");
340                         return -EINVAL;
341                 }
342
343                 /* No reply available.  This is okay. */
344                 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_DORECV) == 0)
345                         return 0;
346
347                 reply_len = ebx;
348                 reply     = kzalloc(reply_len + 1, GFP_KERNEL);
349                 if (!reply) {
350                         DRM_ERROR("Cannot allocate memory for host message reply.\n");
351                         return -ENOMEM;
352                 }
353
354
355                 /* Receive buffer */
356                 ebx = vmw_port_hb_in(channel, reply, reply_len,
357                                      !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
358                 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) {
359                         kfree(reply);
360                         reply = NULL;
361                         if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) {
362                                 /* A checkpoint occurred. Retry. */
363                                 continue;
364                         }
365
366                         return -EINVAL;
367                 }
368
369                 reply[reply_len] = '\0';
370
371
372                 /* Ack buffer */
373                 si  = channel->cookie_high;
374                 di  = channel->cookie_low;
375
376                 VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
377                         MESSAGE_STATUS_SUCCESS, si, di,
378                         channel->channel_id << 16,
379                         VMW_HYPERVISOR_MAGIC,
380                         eax, ebx, ecx, edx, si, di);
381
382                 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
383                         kfree(reply);
384                         reply = NULL;
385                         if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) {
386                                 /* A checkpoint occurred. Retry. */
387                                 continue;
388                         }
389
390                         return -EINVAL;
391                 }
392
393                 break;
394         }
395
396         if (!reply)
397                 return -EINVAL;
398
399         *msg_len = reply_len;
400         *msg     = reply;
401
402         return 0;
403 }
404 STACK_FRAME_NON_STANDARD(vmw_recv_msg);
405
406
407 /**
408  * vmw_host_get_guestinfo: Gets a GuestInfo parameter
409  *
410  * Gets the value of a  GuestInfo.* parameter.  The value returned will be in
411  * a string, and it is up to the caller to post-process.
412  *
413  * @guest_info_param:  Parameter to get, e.g. GuestInfo.svga.gl3
414  * @buffer: if NULL, *reply_len will contain reply size.
415  * @length: size of the reply_buf.  Set to size of reply upon return
416  *
417  * Returns: 0 on success
418  */
419 int vmw_host_get_guestinfo(const char *guest_info_param,
420                            char *buffer, size_t *length)
421 {
422         struct rpc_channel channel;
423         char *msg, *reply = NULL;
424         size_t reply_len = 0;
425
426         if (!vmw_msg_enabled)
427                 return -ENODEV;
428
429         if (!guest_info_param || !length)
430                 return -EINVAL;
431
432         msg = kasprintf(GFP_KERNEL, "info-get %s", guest_info_param);
433         if (!msg) {
434                 DRM_ERROR("Cannot allocate memory to get guest info \"%s\".",
435                           guest_info_param);
436                 return -ENOMEM;
437         }
438
439         if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM))
440                 goto out_open;
441
442         if (vmw_send_msg(&channel, msg) ||
443             vmw_recv_msg(&channel, (void *) &reply, &reply_len))
444                 goto out_msg;
445
446         vmw_close_channel(&channel);
447         if (buffer && reply && reply_len > 0) {
448                 /* Remove reply code, which are the first 2 characters of
449                  * the reply
450                  */
451                 reply_len = max(reply_len - 2, (size_t) 0);
452                 reply_len = min(reply_len, *length);
453
454                 if (reply_len > 0)
455                         memcpy(buffer, reply + 2, reply_len);
456         }
457
458         *length = reply_len;
459
460         kfree(reply);
461         kfree(msg);
462
463         return 0;
464
465 out_msg:
466         vmw_close_channel(&channel);
467         kfree(reply);
468 out_open:
469         *length = 0;
470         kfree(msg);
471         DRM_ERROR("Failed to get guest info \"%s\".", guest_info_param);
472
473         return -EINVAL;
474 }
475
476
477 /**
478  * vmw_host_printf: Sends a log message to the host
479  *
480  * @fmt: Regular printf format string and arguments
481  *
482  * Returns: 0 on success
483  */
484 __printf(1, 2)
485 int vmw_host_printf(const char *fmt, ...)
486 {
487         va_list ap;
488         struct rpc_channel channel;
489         char *msg;
490         char *log;
491         int ret = 0;
492
493         if (!vmw_msg_enabled)
494                 return -ENODEV;
495
496         if (!fmt)
497                 return ret;
498
499         va_start(ap, fmt);
500         log = kvasprintf(GFP_KERNEL, fmt, ap);
501         va_end(ap);
502         if (!log) {
503                 DRM_ERROR("Cannot allocate memory for the log message.\n");
504                 return -ENOMEM;
505         }
506
507         msg = kasprintf(GFP_KERNEL, "log %s", log);
508         if (!msg) {
509                 DRM_ERROR("Cannot allocate memory for host log message.\n");
510                 kfree(log);
511                 return -ENOMEM;
512         }
513
514         if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM))
515                 goto out_open;
516
517         if (vmw_send_msg(&channel, msg))
518                 goto out_msg;
519
520         vmw_close_channel(&channel);
521         kfree(msg);
522         kfree(log);
523
524         return 0;
525
526 out_msg:
527         vmw_close_channel(&channel);
528 out_open:
529         kfree(msg);
530         kfree(log);
531         DRM_ERROR("Failed to send host log message.\n");
532
533         return -EINVAL;
534 }
535
536
537 /**
538  * vmw_msg_ioctl: Sends and receveives a message to/from host from/to user-space
539  *
540  * Sends a message from user-space to host.
541  * Can also receive a result from host and return that to user-space.
542  *
543  * @dev: Identifies the drm device.
544  * @data: Pointer to the ioctl argument.
545  * @file_priv: Identifies the caller.
546  * Return: Zero on success, negative error code on error.
547  */
548
549 int vmw_msg_ioctl(struct drm_device *dev, void *data,
550                   struct drm_file *file_priv)
551 {
552         struct drm_vmw_msg_arg *arg =
553                         (struct drm_vmw_msg_arg *)data;
554         struct rpc_channel channel;
555         char *msg;
556         int length;
557
558         msg = kmalloc(MAX_USER_MSG_LENGTH, GFP_KERNEL);
559         if (!msg) {
560                 DRM_ERROR("Cannot allocate memory for log message.\n");
561                 return -ENOMEM;
562         }
563
564         length = strncpy_from_user(msg, (void __user *)((unsigned long)arg->send),
565                                    MAX_USER_MSG_LENGTH);
566         if (length < 0 || length >= MAX_USER_MSG_LENGTH) {
567                 DRM_ERROR("Userspace message access failure.\n");
568                 kfree(msg);
569                 return -EINVAL;
570         }
571
572
573         if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) {
574                 DRM_ERROR("Failed to open channel.\n");
575                 goto out_open;
576         }
577
578         if (vmw_send_msg(&channel, msg)) {
579                 DRM_ERROR("Failed to send message to host.\n");
580                 goto out_msg;
581         }
582
583         if (!arg->send_only) {
584                 char *reply = NULL;
585                 size_t reply_len = 0;
586
587                 if (vmw_recv_msg(&channel, (void *) &reply, &reply_len)) {
588                         DRM_ERROR("Failed to receive message from host.\n");
589                         goto out_msg;
590                 }
591                 if (reply && reply_len > 0) {
592                         if (copy_to_user((void __user *)((unsigned long)arg->receive),
593                                          reply, reply_len)) {
594                                 DRM_ERROR("Failed to copy message to userspace.\n");
595                                 kfree(reply);
596                                 goto out_msg;
597                         }
598                         arg->receive_len = (__u32)reply_len;
599                 }
600                 kfree(reply);
601         }
602
603         vmw_close_channel(&channel);
604         kfree(msg);
605
606         return 0;
607
608 out_msg:
609         vmw_close_channel(&channel);
610 out_open:
611         kfree(msg);
612
613         return -EINVAL;
614 }