vmmouse.c (13520B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Driver for Virtual PS/2 Mouse on VMware and QEMU hypervisors. 4 * 5 * Copyright (C) 2014, VMware, Inc. All Rights Reserved. 6 * 7 * Twin device code is hugely inspired by the ALPS driver. 8 * Authors: 9 * Dmitry Torokhov <dmitry.torokhov@gmail.com> 10 * Thomas Hellstrom <thellstrom@vmware.com> 11 */ 12 13#include <linux/input.h> 14#include <linux/serio.h> 15#include <linux/libps2.h> 16#include <linux/slab.h> 17#include <linux/module.h> 18#include <asm/hypervisor.h> 19#include <asm/vmware.h> 20 21#include "psmouse.h" 22#include "vmmouse.h" 23 24#define VMMOUSE_PROTO_MAGIC 0x564D5868U 25 26/* 27 * Main commands supported by the vmmouse hypervisor port. 28 */ 29#define VMMOUSE_PROTO_CMD_GETVERSION 10 30#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39 31#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS 40 32#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41 33#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT 86 34 35/* 36 * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 37 */ 38#define VMMOUSE_CMD_ENABLE 0x45414552U 39#define VMMOUSE_CMD_DISABLE 0x000000f5U 40#define VMMOUSE_CMD_REQUEST_RELATIVE 0x4c455252U 41#define VMMOUSE_CMD_REQUEST_ABSOLUTE 0x53424152U 42 43#define VMMOUSE_ERROR 0xffff0000U 44 45#define VMMOUSE_VERSION_ID 0x3442554aU 46 47#define VMMOUSE_RELATIVE_PACKET 0x00010000U 48 49#define VMMOUSE_LEFT_BUTTON 0x20 50#define VMMOUSE_RIGHT_BUTTON 0x10 51#define VMMOUSE_MIDDLE_BUTTON 0x08 52 53/* 54 * VMMouse Restrict command 55 */ 56#define VMMOUSE_RESTRICT_ANY 0x00 57#define VMMOUSE_RESTRICT_CPL0 0x01 58#define VMMOUSE_RESTRICT_IOPL 0x02 59 60#define VMMOUSE_MAX_X 0xFFFF 61#define VMMOUSE_MAX_Y 0xFFFF 62 63#define VMMOUSE_VENDOR "VMware" 64#define VMMOUSE_NAME "VMMouse" 65 66/** 67 * struct vmmouse_data - private data structure for the vmmouse driver 68 * 69 * @abs_dev: "Absolute" device used to report absolute mouse movement. 70 * @phys: Physical path for the absolute device. 71 * @dev_name: Name attribute name for the absolute device. 72 */ 73struct vmmouse_data { 74 struct input_dev *abs_dev; 75 char phys[32]; 76 char dev_name[128]; 77}; 78 79/* 80 * Hypervisor-specific bi-directional communication channel 81 * implementing the vmmouse protocol. Should never execute on 82 * bare metal hardware. 83 */ 84#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \ 85({ \ 86 unsigned long __dummy1, __dummy2; \ 87 __asm__ __volatile__ (VMWARE_HYPERCALL : \ 88 "=a"(out1), \ 89 "=b"(out2), \ 90 "=c"(out3), \ 91 "=d"(out4), \ 92 "=S"(__dummy1), \ 93 "=D"(__dummy2) : \ 94 "a"(VMMOUSE_PROTO_MAGIC), \ 95 "b"(in1), \ 96 "c"(VMMOUSE_PROTO_CMD_##cmd), \ 97 "d"(0) : \ 98 "memory"); \ 99}) 100 101/** 102 * vmmouse_report_button - report button state on the correct input device 103 * 104 * @psmouse: Pointer to the psmouse struct 105 * @abs_dev: The absolute input device 106 * @rel_dev: The relative input device 107 * @pref_dev: The preferred device for reporting 108 * @code: Button code 109 * @value: Button value 110 * 111 * Report @value and @code on @pref_dev, unless the button is already 112 * pressed on the other device, in which case the state is reported on that 113 * device. 114 */ 115static void vmmouse_report_button(struct psmouse *psmouse, 116 struct input_dev *abs_dev, 117 struct input_dev *rel_dev, 118 struct input_dev *pref_dev, 119 unsigned int code, int value) 120{ 121 if (test_bit(code, abs_dev->key)) 122 pref_dev = abs_dev; 123 else if (test_bit(code, rel_dev->key)) 124 pref_dev = rel_dev; 125 126 input_report_key(pref_dev, code, value); 127} 128 129/** 130 * vmmouse_report_events - process events on the vmmouse communications channel 131 * 132 * @psmouse: Pointer to the psmouse struct 133 * 134 * This function pulls events from the vmmouse communications channel and 135 * reports them on the correct (absolute or relative) input device. When the 136 * communications channel is drained, or if we've processed more than 255 137 * psmouse commands, the function returns PSMOUSE_FULL_PACKET. If there is a 138 * host- or synchronization error, the function returns PSMOUSE_BAD_DATA in 139 * the hope that the caller will reset the communications channel. 140 */ 141static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse) 142{ 143 struct input_dev *rel_dev = psmouse->dev; 144 struct vmmouse_data *priv = psmouse->private; 145 struct input_dev *abs_dev = priv->abs_dev; 146 struct input_dev *pref_dev; 147 u32 status, x, y, z; 148 u32 dummy1, dummy2, dummy3; 149 unsigned int queue_length; 150 unsigned int count = 255; 151 152 while (count--) { 153 /* See if we have motion data. */ 154 VMMOUSE_CMD(ABSPOINTER_STATUS, 0, 155 status, dummy1, dummy2, dummy3); 156 if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) { 157 psmouse_err(psmouse, "failed to fetch status data\n"); 158 /* 159 * After a few attempts this will result in 160 * reconnect. 161 */ 162 return PSMOUSE_BAD_DATA; 163 } 164 165 queue_length = status & 0xffff; 166 if (queue_length == 0) 167 break; 168 169 if (queue_length % 4) { 170 psmouse_err(psmouse, "invalid queue length\n"); 171 return PSMOUSE_BAD_DATA; 172 } 173 174 /* Now get it */ 175 VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z); 176 177 /* 178 * And report what we've got. Prefer to report button 179 * events on the same device where we report motion events. 180 * This doesn't work well with the mouse wheel, though. See 181 * below. Ideally we would want to report that on the 182 * preferred device as well. 183 */ 184 if (status & VMMOUSE_RELATIVE_PACKET) { 185 pref_dev = rel_dev; 186 input_report_rel(rel_dev, REL_X, (s32)x); 187 input_report_rel(rel_dev, REL_Y, -(s32)y); 188 } else { 189 pref_dev = abs_dev; 190 input_report_abs(abs_dev, ABS_X, x); 191 input_report_abs(abs_dev, ABS_Y, y); 192 } 193 194 /* Xorg seems to ignore wheel events on absolute devices */ 195 input_report_rel(rel_dev, REL_WHEEL, -(s8)((u8) z)); 196 197 vmmouse_report_button(psmouse, abs_dev, rel_dev, 198 pref_dev, BTN_LEFT, 199 status & VMMOUSE_LEFT_BUTTON); 200 vmmouse_report_button(psmouse, abs_dev, rel_dev, 201 pref_dev, BTN_RIGHT, 202 status & VMMOUSE_RIGHT_BUTTON); 203 vmmouse_report_button(psmouse, abs_dev, rel_dev, 204 pref_dev, BTN_MIDDLE, 205 status & VMMOUSE_MIDDLE_BUTTON); 206 input_sync(abs_dev); 207 input_sync(rel_dev); 208 } 209 210 return PSMOUSE_FULL_PACKET; 211} 212 213/** 214 * vmmouse_process_byte - process data on the ps/2 channel 215 * 216 * @psmouse: Pointer to the psmouse struct 217 * 218 * When the ps/2 channel indicates that there is vmmouse data available, 219 * call vmmouse channel processing. Otherwise, continue to accept bytes. If 220 * there is a synchronization or communication data error, return 221 * PSMOUSE_BAD_DATA in the hope that the caller will reset the mouse. 222 */ 223static psmouse_ret_t vmmouse_process_byte(struct psmouse *psmouse) 224{ 225 unsigned char *packet = psmouse->packet; 226 227 switch (psmouse->pktcnt) { 228 case 1: 229 return (packet[0] & 0x8) == 0x8 ? 230 PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; 231 232 case 2: 233 return PSMOUSE_GOOD_DATA; 234 235 default: 236 return vmmouse_report_events(psmouse); 237 } 238} 239 240/** 241 * vmmouse_disable - Disable vmmouse 242 * 243 * @psmouse: Pointer to the psmouse struct 244 * 245 * Tries to disable vmmouse mode. 246 */ 247static void vmmouse_disable(struct psmouse *psmouse) 248{ 249 u32 status; 250 u32 dummy1, dummy2, dummy3, dummy4; 251 252 VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE, 253 dummy1, dummy2, dummy3, dummy4); 254 255 VMMOUSE_CMD(ABSPOINTER_STATUS, 0, 256 status, dummy1, dummy2, dummy3); 257 258 if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR) 259 psmouse_warn(psmouse, "failed to disable vmmouse device\n"); 260} 261 262/** 263 * vmmouse_enable - Enable vmmouse and request absolute mode. 264 * 265 * @psmouse: Pointer to the psmouse struct 266 * 267 * Tries to enable vmmouse mode. Performs basic checks and requests 268 * absolute vmmouse mode. 269 * Returns 0 on success, -ENODEV on failure. 270 */ 271static int vmmouse_enable(struct psmouse *psmouse) 272{ 273 u32 status, version; 274 u32 dummy1, dummy2, dummy3, dummy4; 275 276 /* 277 * Try enabling the device. If successful, we should be able to 278 * read valid version ID back from it. 279 */ 280 VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE, 281 dummy1, dummy2, dummy3, dummy4); 282 283 /* 284 * See if version ID can be retrieved. 285 */ 286 VMMOUSE_CMD(ABSPOINTER_STATUS, 0, status, dummy1, dummy2, dummy3); 287 if ((status & 0x0000ffff) == 0) { 288 psmouse_dbg(psmouse, "empty flags - assuming no device\n"); 289 return -ENXIO; 290 } 291 292 VMMOUSE_CMD(ABSPOINTER_DATA, 1 /* single item */, 293 version, dummy1, dummy2, dummy3); 294 if (version != VMMOUSE_VERSION_ID) { 295 psmouse_dbg(psmouse, "Unexpected version value: %u vs %u\n", 296 (unsigned) version, VMMOUSE_VERSION_ID); 297 vmmouse_disable(psmouse); 298 return -ENXIO; 299 } 300 301 /* 302 * Restrict ioport access, if possible. 303 */ 304 VMMOUSE_CMD(ABSPOINTER_RESTRICT, VMMOUSE_RESTRICT_CPL0, 305 dummy1, dummy2, dummy3, dummy4); 306 307 VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_REQUEST_ABSOLUTE, 308 dummy1, dummy2, dummy3, dummy4); 309 310 return 0; 311} 312 313/* 314 * Array of supported hypervisors. 315 */ 316static enum x86_hypervisor_type vmmouse_supported_hypervisors[] = { 317 X86_HYPER_VMWARE, 318 X86_HYPER_KVM, 319}; 320 321/** 322 * vmmouse_check_hypervisor - Check if we're running on a supported hypervisor 323 */ 324static bool vmmouse_check_hypervisor(void) 325{ 326 int i; 327 328 for (i = 0; i < ARRAY_SIZE(vmmouse_supported_hypervisors); i++) 329 if (vmmouse_supported_hypervisors[i] == x86_hyper_type) 330 return true; 331 332 return false; 333} 334 335/** 336 * vmmouse_detect - Probe whether vmmouse is available 337 * 338 * @psmouse: Pointer to the psmouse struct 339 * @set_properties: Whether to set psmouse name and vendor 340 * 341 * Returns 0 if vmmouse channel is available. Negative error code if not. 342 */ 343int vmmouse_detect(struct psmouse *psmouse, bool set_properties) 344{ 345 u32 response, version, dummy1, dummy2; 346 347 if (!vmmouse_check_hypervisor()) { 348 psmouse_dbg(psmouse, 349 "VMMouse not running on supported hypervisor.\n"); 350 return -ENXIO; 351 } 352 353 /* Check if the device is present */ 354 response = ~VMMOUSE_PROTO_MAGIC; 355 VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2); 356 if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU) 357 return -ENXIO; 358 359 if (set_properties) { 360 psmouse->vendor = VMMOUSE_VENDOR; 361 psmouse->name = VMMOUSE_NAME; 362 psmouse->model = version; 363 } 364 365 return 0; 366} 367 368/** 369 * vmmouse_reset - Disable vmmouse and reset 370 * 371 * @psmouse: Pointer to the psmouse struct 372 * 373 * Tries to disable vmmouse mode before enter suspend. 374 */ 375static void vmmouse_reset(struct psmouse *psmouse) 376{ 377 vmmouse_disable(psmouse); 378 psmouse_reset(psmouse); 379} 380 381/** 382 * vmmouse_disconnect - Take down vmmouse driver 383 * 384 * @psmouse: Pointer to the psmouse struct 385 * 386 * Takes down vmmouse driver and frees resources set up in vmmouse_init(). 387 */ 388static void vmmouse_disconnect(struct psmouse *psmouse) 389{ 390 struct vmmouse_data *priv = psmouse->private; 391 392 vmmouse_disable(psmouse); 393 psmouse_reset(psmouse); 394 input_unregister_device(priv->abs_dev); 395 kfree(priv); 396} 397 398/** 399 * vmmouse_reconnect - Reset the ps/2 - and vmmouse connections 400 * 401 * @psmouse: Pointer to the psmouse struct 402 * 403 * Attempts to reset the mouse connections. Returns 0 on success and 404 * -1 on failure. 405 */ 406static int vmmouse_reconnect(struct psmouse *psmouse) 407{ 408 int error; 409 410 psmouse_reset(psmouse); 411 vmmouse_disable(psmouse); 412 error = vmmouse_enable(psmouse); 413 if (error) { 414 psmouse_err(psmouse, 415 "Unable to re-enable mouse when reconnecting, err: %d\n", 416 error); 417 return error; 418 } 419 420 return 0; 421} 422 423/** 424 * vmmouse_init - Initialize the vmmouse driver 425 * 426 * @psmouse: Pointer to the psmouse struct 427 * 428 * Requests the device and tries to enable vmmouse mode. 429 * If successful, sets up the input device for relative movement events. 430 * It also allocates another input device and sets it up for absolute motion 431 * events. Returns 0 on success and -1 on failure. 432 */ 433int vmmouse_init(struct psmouse *psmouse) 434{ 435 struct vmmouse_data *priv; 436 struct input_dev *rel_dev = psmouse->dev, *abs_dev; 437 int error; 438 439 psmouse_reset(psmouse); 440 error = vmmouse_enable(psmouse); 441 if (error) 442 return error; 443 444 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 445 abs_dev = input_allocate_device(); 446 if (!priv || !abs_dev) { 447 error = -ENOMEM; 448 goto init_fail; 449 } 450 451 priv->abs_dev = abs_dev; 452 psmouse->private = priv; 453 454 /* Set up and register absolute device */ 455 snprintf(priv->phys, sizeof(priv->phys), "%s/input1", 456 psmouse->ps2dev.serio->phys); 457 458 /* Mimic name setup for relative device in psmouse-base.c */ 459 snprintf(priv->dev_name, sizeof(priv->dev_name), "%s %s %s", 460 VMMOUSE_PSNAME, VMMOUSE_VENDOR, VMMOUSE_NAME); 461 abs_dev->phys = priv->phys; 462 abs_dev->name = priv->dev_name; 463 abs_dev->id.bustype = BUS_I8042; 464 abs_dev->id.vendor = 0x0002; 465 abs_dev->id.product = PSMOUSE_VMMOUSE; 466 abs_dev->id.version = psmouse->model; 467 abs_dev->dev.parent = &psmouse->ps2dev.serio->dev; 468 469 /* Set absolute device capabilities */ 470 input_set_capability(abs_dev, EV_KEY, BTN_LEFT); 471 input_set_capability(abs_dev, EV_KEY, BTN_RIGHT); 472 input_set_capability(abs_dev, EV_KEY, BTN_MIDDLE); 473 input_set_capability(abs_dev, EV_ABS, ABS_X); 474 input_set_capability(abs_dev, EV_ABS, ABS_Y); 475 input_set_abs_params(abs_dev, ABS_X, 0, VMMOUSE_MAX_X, 0, 0); 476 input_set_abs_params(abs_dev, ABS_Y, 0, VMMOUSE_MAX_Y, 0, 0); 477 478 error = input_register_device(priv->abs_dev); 479 if (error) 480 goto init_fail; 481 482 /* Add wheel capability to the relative device */ 483 input_set_capability(rel_dev, EV_REL, REL_WHEEL); 484 485 psmouse->protocol_handler = vmmouse_process_byte; 486 psmouse->disconnect = vmmouse_disconnect; 487 psmouse->reconnect = vmmouse_reconnect; 488 psmouse->cleanup = vmmouse_reset; 489 490 return 0; 491 492init_fail: 493 vmmouse_disable(psmouse); 494 psmouse_reset(psmouse); 495 input_free_device(abs_dev); 496 kfree(priv); 497 psmouse->private = NULL; 498 499 return error; 500}