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/frame.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.h" 37 38 #define MESSAGE_STATUS_SUCCESS 0x0001 39 #define MESSAGE_STATUS_DORECV 0x0002 40 #define MESSAGE_STATUS_CPT 0x0010 41 #define MESSAGE_STATUS_HB 0x0080 42 43 #define RPCI_PROTOCOL_NUM 0x49435052 44 #define GUESTMSG_FLAG_COOKIE 0x80000000 45 46 #define RETRIES 3 47 48 #define VMW_HYPERVISOR_MAGIC 0x564D5868 49 50 #define VMW_PORT_CMD_MSG 30 51 #define VMW_PORT_CMD_HB_MSG 0 52 #define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG) 53 #define VMW_PORT_CMD_CLOSE_CHANNEL (MSG_TYPE_CLOSE << 16 | VMW_PORT_CMD_MSG) 54 #define VMW_PORT_CMD_SENDSIZE (MSG_TYPE_SENDSIZE << 16 | VMW_PORT_CMD_MSG) 55 #define VMW_PORT_CMD_RECVSIZE (MSG_TYPE_RECVSIZE << 16 | VMW_PORT_CMD_MSG) 56 #define VMW_PORT_CMD_RECVSTATUS (MSG_TYPE_RECVSTATUS << 16 | VMW_PORT_CMD_MSG) 57 58 #define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16) 59 60 #define MAX_USER_MSG_LENGTH PAGE_SIZE 61 62 static u32 vmw_msg_enabled = 1; 63 64 enum rpc_msg_type { 65 MSG_TYPE_OPEN, 66 MSG_TYPE_SENDSIZE, 67 MSG_TYPE_SENDPAYLOAD, 68 MSG_TYPE_RECVSIZE, 69 MSG_TYPE_RECVPAYLOAD, 70 MSG_TYPE_RECVSTATUS, 71 MSG_TYPE_CLOSE, 72 }; 73 74 struct rpc_channel { 75 u16 channel_id; 76 u32 cookie_high; 77 u32 cookie_low; 78 }; 79 80 81 82 /** 83 * vmw_open_channel 84 * 85 * @channel: RPC channel 86 * @protocol: 87 * 88 * Returns: 0 on success 89 */ 90 static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol) 91 { 92 unsigned long eax, ebx, ecx, edx, si = 0, di = 0; 93 94 VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL, 95 (protocol | GUESTMSG_FLAG_COOKIE), si, di, 96 0, 97 VMW_HYPERVISOR_MAGIC, 98 eax, ebx, ecx, edx, si, di); 99 100 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) 101 return -EINVAL; 102 103 channel->channel_id = HIGH_WORD(edx); 104 channel->cookie_high = si; 105 channel->cookie_low = di; 106 107 return 0; 108 } 109 110 111 112 /** 113 * vmw_close_channel 114 * 115 * @channel: RPC channel 116 * 117 * Returns: 0 on success 118 */ 119 static int vmw_close_channel(struct rpc_channel *channel) 120 { 121 unsigned long eax, ebx, ecx, edx, si, di; 122 123 /* Set up additional parameters */ 124 si = channel->cookie_high; 125 di = channel->cookie_low; 126 127 VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL, 128 0, si, di, 129 channel->channel_id << 16, 130 VMW_HYPERVISOR_MAGIC, 131 eax, ebx, ecx, edx, si, di); 132 133 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) 134 return -EINVAL; 135 136 return 0; 137 } 138 139 /** 140 * vmw_port_hb_out - Send the message payload either through the 141 * high-bandwidth port if available, or through the backdoor otherwise. 142 * @channel: The rpc channel. 143 * @msg: NULL-terminated message. 144 * @hb: Whether the high-bandwidth port is available. 145 * 146 * Return: The port status. 147 */ 148 static unsigned long vmw_port_hb_out(struct rpc_channel *channel, 149 const char *msg, bool hb) 150 { 151 unsigned long si, di, eax, ebx, ecx, edx; 152 unsigned long msg_len = strlen(msg); 153 154 /* HB port can't access encrypted memory. */ 155 if (hb && !mem_encrypt_active()) { 156 unsigned long bp = channel->cookie_high; 157 158 si = (uintptr_t) msg; 159 di = channel->cookie_low; 160 161 VMW_PORT_HB_OUT( 162 (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, 163 msg_len, si, di, 164 VMWARE_HYPERVISOR_HB | (channel->channel_id << 16) | 165 VMWARE_HYPERVISOR_OUT, 166 VMW_HYPERVISOR_MAGIC, bp, 167 eax, ebx, ecx, edx, si, di); 168 169 return ebx; 170 } 171 172 /* HB port not available. Send the message 4 bytes at a time. */ 173 ecx = MESSAGE_STATUS_SUCCESS << 16; 174 while (msg_len && (HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS)) { 175 unsigned int bytes = min_t(size_t, msg_len, 4); 176 unsigned long word = 0; 177 178 memcpy(&word, msg, bytes); 179 msg_len -= bytes; 180 msg += bytes; 181 si = channel->cookie_high; 182 di = channel->cookie_low; 183 184 VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16), 185 word, si, di, 186 channel->channel_id << 16, 187 VMW_HYPERVISOR_MAGIC, 188 eax, ebx, ecx, edx, si, di); 189 } 190 191 return ecx; 192 } 193 194 /** 195 * vmw_port_hb_in - Receive the message payload either through the 196 * high-bandwidth port if available, or through the backdoor otherwise. 197 * @channel: The rpc channel. 198 * @reply: Pointer to buffer holding reply. 199 * @reply_len: Length of the reply. 200 * @hb: Whether the high-bandwidth port is available. 201 * 202 * Return: The port status. 203 */ 204 static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply, 205 unsigned long reply_len, bool hb) 206 { 207 unsigned long si, di, eax, ebx, ecx, edx; 208 209 /* HB port can't access encrypted memory */ 210 if (hb && !mem_encrypt_active()) { 211 unsigned long bp = channel->cookie_low; 212 213 si = channel->cookie_high; 214 di = (uintptr_t) reply; 215 216 VMW_PORT_HB_IN( 217 (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, 218 reply_len, si, di, 219 VMWARE_HYPERVISOR_HB | (channel->channel_id << 16), 220 VMW_HYPERVISOR_MAGIC, bp, 221 eax, ebx, ecx, edx, si, di); 222 223 return ebx; 224 } 225 226 /* HB port not available. Retrieve the message 4 bytes at a time. */ 227 ecx = MESSAGE_STATUS_SUCCESS << 16; 228 while (reply_len) { 229 unsigned int bytes = min_t(unsigned long, reply_len, 4); 230 231 si = channel->cookie_high; 232 di = channel->cookie_low; 233 234 VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16), 235 MESSAGE_STATUS_SUCCESS, si, di, 236 channel->channel_id << 16, 237 VMW_HYPERVISOR_MAGIC, 238 eax, ebx, ecx, edx, si, di); 239 240 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) 241 break; 242 243 memcpy(reply, &ebx, bytes); 244 reply_len -= bytes; 245 reply += bytes; 246 } 247 248 return ecx; 249 } 250 251 252 /** 253 * vmw_send_msg: Sends a message to the host 254 * 255 * @channel: RPC channel 256 * @logmsg: NULL terminated string 257 * 258 * Returns: 0 on success 259 */ 260 static int vmw_send_msg(struct rpc_channel *channel, const char *msg) 261 { 262 unsigned long eax, ebx, ecx, edx, si, di; 263 size_t msg_len = strlen(msg); 264 int retries = 0; 265 266 while (retries < RETRIES) { 267 retries++; 268 269 /* Set up additional parameters */ 270 si = channel->cookie_high; 271 di = channel->cookie_low; 272 273 VMW_PORT(VMW_PORT_CMD_SENDSIZE, 274 msg_len, si, di, 275 channel->channel_id << 16, 276 VMW_HYPERVISOR_MAGIC, 277 eax, ebx, ecx, edx, si, di); 278 279 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { 280 /* Expected success. Give up. */ 281 return -EINVAL; 282 } 283 284 /* Send msg */ 285 ebx = vmw_port_hb_out(channel, msg, 286 !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); 287 288 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) != 0) { 289 return 0; 290 } else if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) { 291 /* A checkpoint occurred. Retry. */ 292 continue; 293 } else { 294 break; 295 } 296 } 297 298 return -EINVAL; 299 } 300 STACK_FRAME_NON_STANDARD(vmw_send_msg); 301 302 303 /** 304 * vmw_recv_msg: Receives a message from the host 305 * 306 * Note: It is the caller's responsibility to call kfree() on msg. 307 * 308 * @channel: channel opened by vmw_open_channel 309 * @msg: [OUT] message received from the host 310 * @msg_len: message length 311 */ 312 static int vmw_recv_msg(struct rpc_channel *channel, void **msg, 313 size_t *msg_len) 314 { 315 unsigned long eax, ebx, ecx, edx, si, di; 316 char *reply; 317 size_t reply_len; 318 int retries = 0; 319 320 321 *msg_len = 0; 322 *msg = NULL; 323 324 while (retries < RETRIES) { 325 retries++; 326 327 /* Set up additional parameters */ 328 si = channel->cookie_high; 329 di = channel->cookie_low; 330 331 VMW_PORT(VMW_PORT_CMD_RECVSIZE, 332 0, si, di, 333 channel->channel_id << 16, 334 VMW_HYPERVISOR_MAGIC, 335 eax, ebx, ecx, edx, si, di); 336 337 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { 338 DRM_ERROR("Failed to get reply size for host message.\n"); 339 return -EINVAL; 340 } 341 342 /* No reply available. This is okay. */ 343 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_DORECV) == 0) 344 return 0; 345 346 reply_len = ebx; 347 reply = kzalloc(reply_len + 1, GFP_KERNEL); 348 if (!reply) { 349 DRM_ERROR("Cannot allocate memory for host message reply.\n"); 350 return -ENOMEM; 351 } 352 353 354 /* Receive buffer */ 355 ebx = vmw_port_hb_in(channel, reply, reply_len, 356 !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB)); 357 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) { 358 kfree(reply); 359 reply = NULL; 360 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) { 361 /* A checkpoint occurred. Retry. */ 362 continue; 363 } 364 365 return -EINVAL; 366 } 367 368 reply[reply_len] = '\0'; 369 370 371 /* Ack buffer */ 372 si = channel->cookie_high; 373 di = channel->cookie_low; 374 375 VMW_PORT(VMW_PORT_CMD_RECVSTATUS, 376 MESSAGE_STATUS_SUCCESS, si, di, 377 channel->channel_id << 16, 378 VMW_HYPERVISOR_MAGIC, 379 eax, ebx, ecx, edx, si, di); 380 381 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) { 382 kfree(reply); 383 reply = NULL; 384 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) { 385 /* A checkpoint occurred. Retry. */ 386 continue; 387 } 388 389 return -EINVAL; 390 } 391 392 break; 393 } 394 395 if (!reply) 396 return -EINVAL; 397 398 *msg_len = reply_len; 399 *msg = reply; 400 401 return 0; 402 } 403 STACK_FRAME_NON_STANDARD(vmw_recv_msg); 404 405 406 /** 407 * vmw_host_get_guestinfo: Gets a GuestInfo parameter 408 * 409 * Gets the value of a GuestInfo.* parameter. The value returned will be in 410 * a string, and it is up to the caller to post-process. 411 * 412 * @guest_info_param: Parameter to get, e.g. GuestInfo.svga.gl3 413 * @buffer: if NULL, *reply_len will contain reply size. 414 * @length: size of the reply_buf. Set to size of reply upon return 415 * 416 * Returns: 0 on success 417 */ 418 int vmw_host_get_guestinfo(const char *guest_info_param, 419 char *buffer, size_t *length) 420 { 421 struct rpc_channel channel; 422 char *msg, *reply = NULL; 423 size_t reply_len = 0; 424 425 if (!vmw_msg_enabled) 426 return -ENODEV; 427 428 if (!guest_info_param || !length) 429 return -EINVAL; 430 431 msg = kasprintf(GFP_KERNEL, "info-get %s", guest_info_param); 432 if (!msg) { 433 DRM_ERROR("Cannot allocate memory to get guest info \"%s\".", 434 guest_info_param); 435 return -ENOMEM; 436 } 437 438 if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) 439 goto out_open; 440 441 if (vmw_send_msg(&channel, msg) || 442 vmw_recv_msg(&channel, (void *) &reply, &reply_len)) 443 goto out_msg; 444 445 vmw_close_channel(&channel); 446 if (buffer && reply && reply_len > 0) { 447 /* Remove reply code, which are the first 2 characters of 448 * the reply 449 */ 450 reply_len = max(reply_len - 2, (size_t) 0); 451 reply_len = min(reply_len, *length); 452 453 if (reply_len > 0) 454 memcpy(buffer, reply + 2, reply_len); 455 } 456 457 *length = reply_len; 458 459 kfree(reply); 460 kfree(msg); 461 462 return 0; 463 464 out_msg: 465 vmw_close_channel(&channel); 466 kfree(reply); 467 out_open: 468 *length = 0; 469 kfree(msg); 470 DRM_ERROR("Failed to get guest info \"%s\".", guest_info_param); 471 472 return -EINVAL; 473 } 474 475 476 477 /** 478 * vmw_host_log: Sends a log message to the host 479 * 480 * @log: NULL terminated string 481 * 482 * Returns: 0 on success 483 */ 484 int vmw_host_log(const char *log) 485 { 486 struct rpc_channel channel; 487 char *msg; 488 int ret = 0; 489 490 491 if (!vmw_msg_enabled) 492 return -ENODEV; 493 494 if (!log) 495 return ret; 496 497 msg = kasprintf(GFP_KERNEL, "log %s", log); 498 if (!msg) { 499 DRM_ERROR("Cannot allocate memory for host log message.\n"); 500 return -ENOMEM; 501 } 502 503 if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM)) 504 goto out_open; 505 506 if (vmw_send_msg(&channel, msg)) 507 goto out_msg; 508 509 vmw_close_channel(&channel); 510 kfree(msg); 511 512 return 0; 513 514 out_msg: 515 vmw_close_channel(&channel); 516 out_open: 517 kfree(msg); 518 DRM_ERROR("Failed to send host log message.\n"); 519 520 return -EINVAL; 521 } 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 } 602 603