1 /* $NetBSD: vmt_subr.c,v 1.8 2024/03/20 23:34:24 msaitoh Exp $ */ 2 /* $OpenBSD: vmt.c,v 1.11 2011/01/27 21:29:25 dtucker Exp $ */ 3 4 /* 5 * Copyright (c) 2007 David Crawshaw <david@zentus.com> 6 * Copyright (c) 2008 David Gwynne <dlg@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 /* 22 * Protocol reverse engineered by Ken Kato: 23 * https://sites.google.com/site/chitchatvmback/backdoor 24 */ 25 26 #include <sys/param.h> 27 #include <sys/types.h> 28 #include <sys/callout.h> 29 #include <sys/device.h> 30 #include <sys/endian.h> 31 #include <sys/kernel.h> 32 #include <sys/kmem.h> 33 #include <sys/module.h> 34 #include <sys/proc.h> 35 #include <sys/reboot.h> 36 #include <sys/socket.h> 37 #include <sys/sysctl.h> 38 #include <sys/syslog.h> 39 #include <sys/systm.h> 40 #include <sys/timetc.h> 41 42 #include <net/if.h> 43 #include <netinet/in.h> 44 45 #include <dev/sysmon/sysmonvar.h> 46 #include <dev/sysmon/sysmon_taskq.h> 47 #include <dev/vmt/vmtreg.h> 48 #include <dev/vmt/vmtvar.h> 49 50 /* #define VMT_DEBUG */ 51 52 static int vmt_sysctl_setup_root(device_t); 53 static int vmt_sysctl_setup_clock_sync(device_t, const struct sysctlnode *); 54 static int vmt_sysctl_update_clock_sync_period(SYSCTLFN_PROTO); 55 56 static void vm_cmd(struct vm_backdoor *); 57 static void vm_ins(struct vm_backdoor *); 58 static void vm_outs(struct vm_backdoor *); 59 60 /* Functions for communicating with the VM Host. */ 61 static int vm_rpc_open(struct vm_rpc *, uint32_t); 62 static int vm_rpc_close(struct vm_rpc *); 63 static int vm_rpc_send(const struct vm_rpc *, const uint8_t *, uint32_t); 64 static int vm_rpc_send_str(const struct vm_rpc *, const uint8_t *); 65 static int vm_rpc_get_length(const struct vm_rpc *, uint32_t *, uint16_t *); 66 static int vm_rpc_get_data(const struct vm_rpc *, char *, uint32_t, uint16_t); 67 static int vm_rpc_send_rpci_tx_buf(struct vmt_softc *, const uint8_t *, uint32_t); 68 static int vm_rpc_send_rpci_tx(struct vmt_softc *, const char *, ...) 69 __printflike(2, 3); 70 static int vm_rpci_response_successful(struct vmt_softc *); 71 72 static void vmt_tclo_state_change_success(struct vmt_softc *, int, char); 73 static void vmt_do_reboot(struct vmt_softc *); 74 static void vmt_do_shutdown(struct vmt_softc *); 75 static bool vmt_shutdown(device_t, int); 76 77 static void vmt_update_guest_info(struct vmt_softc *); 78 static void vmt_update_guest_uptime(struct vmt_softc *); 79 static void vmt_sync_guest_clock(struct vmt_softc *); 80 81 static void vmt_tick(void *); 82 static void vmt_clock_sync_tick(void *); 83 static void vmt_pswitch_event(void *); 84 85 static void vmt_tclo_tick(void *); 86 static int vmt_tclo_process(struct vmt_softc *, const char *); 87 static void vmt_tclo_reset(struct vmt_softc *); 88 static void vmt_tclo_ping(struct vmt_softc *); 89 static void vmt_tclo_halt(struct vmt_softc *); 90 static void vmt_tclo_reboot(struct vmt_softc *); 91 static void vmt_tclo_poweron(struct vmt_softc *); 92 static void vmt_tclo_suspend(struct vmt_softc *); 93 static void vmt_tclo_resume(struct vmt_softc *); 94 static void vmt_tclo_capreg(struct vmt_softc *); 95 static void vmt_tclo_broadcastip(struct vmt_softc *); 96 97 struct vmt_tclo_rpc { 98 const char *name; 99 void (*cb)(struct vmt_softc *); 100 } vmt_tclo_rpc[] = { 101 /* Keep sorted by name (case-sensitive) */ 102 { "Capabilities_Register", vmt_tclo_capreg }, 103 { "OS_Halt", vmt_tclo_halt }, 104 { "OS_PowerOn", vmt_tclo_poweron }, 105 { "OS_Reboot", vmt_tclo_reboot }, 106 { "OS_Resume", vmt_tclo_resume }, 107 { "OS_Suspend", vmt_tclo_suspend }, 108 { "Set_Option broadcastIP 1", vmt_tclo_broadcastip }, 109 { "ping", vmt_tclo_ping }, 110 { "reset", vmt_tclo_reset }, 111 { NULL }, 112 #if 0 113 /* Various unsupported commands */ 114 { "Set_Option autohide 0" }, 115 { "Set_Option copypaste 1" }, 116 { "Set_Option enableDnD 1" }, 117 { "Set_Option enableMessageBusTunnel 0" }, 118 { "Set_Option linkRootHgfsShare 0" }, 119 { "Set_Option mapRootHgfsShare 0" }, 120 { "Set_Option synctime 1" }, 121 { "Set_Option synctime.period 0" }, 122 { "Set_Option time.synchronize.tools.enable 1" }, 123 { "Set_Option time.synchronize.tools.percentCorrection 0" }, 124 { "Set_Option time.synchronize.tools.slewCorrection 1" }, 125 { "Set_Option time.synchronize.tools.startup 1" }, 126 { "Set_Option toolScripts.afterPowerOn 1" }, 127 { "Set_Option toolScripts.afterResume 1" }, 128 { "Set_Option toolScripts.beforePowerOff 1" }, 129 { "Set_Option toolScripts.beforeSuspend 1" }, 130 { "Time_Synchronize 0" }, 131 { "Vix_1_Relayed_Command \"38cdcae40e075d66\"" }, 132 #endif 133 }; 134 135 extern char hostname[MAXHOSTNAMELEN]; 136 137 static void 138 vmt_probe_cmd(struct vm_backdoor *frame, uint16_t cmd) 139 { 140 memset(frame, 0, sizeof(*frame)); 141 142 frame->eax = VM_MAGIC; 143 frame->ebx = ~VM_MAGIC & VM_REG_WORD_MASK; 144 frame->ecx = VM_REG_CMD(0xffff, cmd); 145 frame->edx = VM_REG_CMD(0, VM_PORT_CMD); 146 147 vm_cmd(frame); 148 } 149 150 bool 151 vmt_probe(void) 152 { 153 struct vm_backdoor frame; 154 155 vmt_probe_cmd(&frame, VM_CMD_GET_VERSION); 156 if (__SHIFTOUT(frame.eax, VM_REG_WORD_MASK) == 0xffffffff || 157 __SHIFTOUT(frame.ebx, VM_REG_WORD_MASK) != VM_MAGIC) 158 return false; 159 160 vmt_probe_cmd(&frame, VM_CMD_GET_SPEED); 161 if (__SHIFTOUT(frame.eax, VM_REG_WORD_MASK) == VM_MAGIC) 162 return false; 163 164 return true; 165 } 166 167 void 168 vmt_common_attach(struct vmt_softc *sc) 169 { 170 device_t self; 171 struct vm_backdoor frame; 172 int rv; 173 174 self = sc->sc_dev; 175 sc->sc_log = NULL; 176 177 /* check again */ 178 vmt_probe_cmd(&frame, VM_CMD_GET_VERSION); 179 if (__SHIFTOUT(frame.eax, VM_REG_WORD_MASK) == 0xffffffff || 180 __SHIFTOUT(frame.ebx, VM_REG_WORD_MASK) != VM_MAGIC) { 181 aprint_error_dev(self, "failed to get VMware version\n"); 182 return; 183 } 184 185 /* show uuid */ 186 { 187 struct uuid uuid; 188 uint32_t u; 189 190 vmt_probe_cmd(&frame, VM_CMD_GET_BIOS_UUID); 191 uuid.time_low = 192 bswap32(__SHIFTOUT(frame.eax, VM_REG_WORD_MASK)); 193 u = bswap32(__SHIFTOUT(frame.ebx, VM_REG_WORD_MASK)); 194 uuid.time_mid = u >> 16; 195 uuid.time_hi_and_version = u; 196 u = bswap32(__SHIFTOUT(frame.ecx, VM_REG_WORD_MASK)); 197 uuid.clock_seq_hi_and_reserved = u >> 24; 198 uuid.clock_seq_low = u >> 16; 199 uuid.node[0] = u >> 8; 200 uuid.node[1] = u; 201 u = bswap32(__SHIFTOUT(frame.edx, VM_REG_WORD_MASK)); 202 uuid.node[2] = u >> 24; 203 uuid.node[3] = u >> 16; 204 uuid.node[4] = u >> 8; 205 uuid.node[5] = u; 206 207 uuid_snprintf(sc->sc_uuid, sizeof(sc->sc_uuid), &uuid); 208 aprint_verbose_dev(sc->sc_dev, "UUID: %s\n", sc->sc_uuid); 209 } 210 211 callout_init(&sc->sc_tick, 0); 212 callout_init(&sc->sc_tclo_tick, 0); 213 callout_init(&sc->sc_clock_sync_tick, 0); 214 215 sc->sc_clock_sync_period_seconds = VMT_CLOCK_SYNC_PERIOD_SECONDS; 216 217 rv = vmt_sysctl_setup_root(self); 218 if (rv != 0) { 219 aprint_error_dev(self, "failed to initialize sysctl " 220 "(err %d)\n", rv); 221 goto free; 222 } 223 224 sc->sc_rpc_buf = kmem_alloc(VMT_RPC_BUFLEN, KM_SLEEP); 225 226 if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) { 227 aprint_error_dev(self, "failed to open backdoor RPC channel " 228 "(TCLO protocol)\n"); 229 goto free; 230 } 231 sc->sc_tclo_rpc_open = true; 232 233 /* don't know if this is important at all yet */ 234 if (vm_rpc_send_rpci_tx(sc, 235 "tools.capability.hgfs_server toolbox 1") != 0) { 236 aprint_error_dev(self, 237 "failed to set HGFS server capability\n"); 238 goto free; 239 } 240 241 pmf_device_register1(self, NULL, NULL, vmt_shutdown); 242 243 sysmon_task_queue_init(); 244 245 sc->sc_ev_power.ev_smpsw.smpsw_type = PSWITCH_TYPE_POWER; 246 sc->sc_ev_power.ev_smpsw.smpsw_name = device_xname(self); 247 sc->sc_ev_power.ev_code = PSWITCH_EVENT_PRESSED; 248 sysmon_pswitch_register(&sc->sc_ev_power.ev_smpsw); 249 sc->sc_ev_reset.ev_smpsw.smpsw_type = PSWITCH_TYPE_RESET; 250 sc->sc_ev_reset.ev_smpsw.smpsw_name = device_xname(self); 251 sc->sc_ev_reset.ev_code = PSWITCH_EVENT_PRESSED; 252 sysmon_pswitch_register(&sc->sc_ev_reset.ev_smpsw); 253 sc->sc_ev_sleep.ev_smpsw.smpsw_type = PSWITCH_TYPE_SLEEP; 254 sc->sc_ev_sleep.ev_smpsw.smpsw_name = device_xname(self); 255 sc->sc_ev_sleep.ev_code = PSWITCH_EVENT_RELEASED; 256 sysmon_pswitch_register(&sc->sc_ev_sleep.ev_smpsw); 257 sc->sc_smpsw_valid = true; 258 259 callout_setfunc(&sc->sc_tick, vmt_tick, sc); 260 callout_schedule(&sc->sc_tick, hz); 261 262 callout_setfunc(&sc->sc_tclo_tick, vmt_tclo_tick, sc); 263 callout_schedule(&sc->sc_tclo_tick, hz); 264 sc->sc_tclo_ping = 1; 265 266 callout_setfunc(&sc->sc_clock_sync_tick, vmt_clock_sync_tick, sc); 267 callout_schedule(&sc->sc_clock_sync_tick, 268 mstohz(sc->sc_clock_sync_period_seconds * 1000)); 269 270 vmt_sync_guest_clock(sc); 271 272 return; 273 274 free: 275 if (sc->sc_rpc_buf) 276 kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN); 277 pmf_device_register(self, NULL, NULL); 278 if (sc->sc_log) 279 sysctl_teardown(&sc->sc_log); 280 } 281 282 int 283 vmt_common_detach(struct vmt_softc *sc) 284 { 285 if (sc->sc_tclo_rpc_open) 286 vm_rpc_close(&sc->sc_tclo_rpc); 287 288 if (sc->sc_smpsw_valid) { 289 sysmon_pswitch_unregister(&sc->sc_ev_sleep.ev_smpsw); 290 sysmon_pswitch_unregister(&sc->sc_ev_reset.ev_smpsw); 291 sysmon_pswitch_unregister(&sc->sc_ev_power.ev_smpsw); 292 } 293 294 callout_halt(&sc->sc_tick, NULL); 295 callout_destroy(&sc->sc_tick); 296 297 callout_halt(&sc->sc_tclo_tick, NULL); 298 callout_destroy(&sc->sc_tclo_tick); 299 300 callout_halt(&sc->sc_clock_sync_tick, NULL); 301 callout_destroy(&sc->sc_clock_sync_tick); 302 303 if (sc->sc_rpc_buf) 304 kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN); 305 306 if (sc->sc_log) { 307 sysctl_teardown(&sc->sc_log); 308 sc->sc_log = NULL; 309 } 310 311 return 0; 312 } 313 314 static int 315 vmt_sysctl_setup_root(device_t self) 316 { 317 const struct sysctlnode *machdep_node, *vmt_node; 318 struct vmt_softc *sc = device_private(self); 319 int rv; 320 321 rv = sysctl_createv(&sc->sc_log, 0, NULL, &machdep_node, 322 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 323 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); 324 if (rv != 0) 325 goto fail; 326 327 rv = sysctl_createv(&sc->sc_log, 0, &machdep_node, &vmt_node, 328 0, CTLTYPE_NODE, device_xname(self), NULL, 329 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 330 if (rv != 0) 331 goto fail; 332 333 rv = sysctl_createv(&sc->sc_log, 0, &vmt_node, NULL, 334 CTLFLAG_READONLY, CTLTYPE_STRING, "uuid", 335 SYSCTL_DESCR("UUID of virtual machine"), 336 NULL, 0, sc->sc_uuid, 0, 337 CTL_CREATE, CTL_EOL); 338 339 rv = vmt_sysctl_setup_clock_sync(self, vmt_node); 340 if (rv != 0) 341 goto fail; 342 343 return 0; 344 345 fail: 346 sysctl_teardown(&sc->sc_log); 347 sc->sc_log = NULL; 348 349 return rv; 350 } 351 352 static int 353 vmt_sysctl_setup_clock_sync(device_t self, const struct sysctlnode *root_node) 354 { 355 const struct sysctlnode *node, *period_node; 356 struct vmt_softc *sc = device_private(self); 357 int rv; 358 359 rv = sysctl_createv(&sc->sc_log, 0, &root_node, &node, 360 0, CTLTYPE_NODE, "clock_sync", NULL, 361 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 362 if (rv != 0) 363 return rv; 364 365 rv = sysctl_createv(&sc->sc_log, 0, &node, &period_node, 366 CTLFLAG_READWRITE, CTLTYPE_INT, "period", 367 SYSCTL_DESCR("Period, in seconds, at which to update the " 368 "guest's clock"), 369 vmt_sysctl_update_clock_sync_period, 0, (void *)sc, 0, 370 CTL_CREATE, CTL_EOL); 371 return rv; 372 } 373 374 static int 375 vmt_sysctl_update_clock_sync_period(SYSCTLFN_ARGS) 376 { 377 int error, period; 378 struct sysctlnode node; 379 struct vmt_softc *sc; 380 381 node = *rnode; 382 sc = (struct vmt_softc *)node.sysctl_data; 383 384 period = sc->sc_clock_sync_period_seconds; 385 node.sysctl_data = . 386 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 387 if (error || newp == NULL) 388 return error; 389 390 if (sc->sc_clock_sync_period_seconds != period) { 391 callout_halt(&sc->sc_clock_sync_tick, NULL); 392 sc->sc_clock_sync_period_seconds = period; 393 if (sc->sc_clock_sync_period_seconds > 0) 394 callout_schedule(&sc->sc_clock_sync_tick, 395 mstohz(sc->sc_clock_sync_period_seconds * 1000)); 396 } 397 return 0; 398 } 399 400 static void 401 vmt_clock_sync_tick(void *xarg) 402 { 403 struct vmt_softc *sc = xarg; 404 405 vmt_sync_guest_clock(sc); 406 407 callout_schedule(&sc->sc_clock_sync_tick, 408 mstohz(sc->sc_clock_sync_period_seconds * 1000)); 409 } 410 411 static void 412 vmt_update_guest_uptime(struct vmt_softc *sc) 413 { 414 /* host wants uptime in hundredths of a second */ 415 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %" PRId64 "00", 416 VM_GUEST_INFO_UPTIME, time_uptime) != 0) { 417 device_printf(sc->sc_dev, "unable to set guest uptime\n"); 418 sc->sc_rpc_error = 1; 419 } 420 } 421 422 static void 423 vmt_update_guest_info(struct vmt_softc *sc) 424 { 425 if (strncmp(sc->sc_hostname, hostname, sizeof(sc->sc_hostname)) != 0) { 426 strlcpy(sc->sc_hostname, hostname, sizeof(sc->sc_hostname)); 427 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %s", 428 VM_GUEST_INFO_DNS_NAME, sc->sc_hostname) != 0) { 429 device_printf(sc->sc_dev, "unable to set hostname\n"); 430 sc->sc_rpc_error = 1; 431 } 432 } 433 434 /* 435 * we're supposed to pass the full network address information back 436 * here, but that involves xdr (sunrpc) data encoding, which seems 437 * a bit unreasonable. 438 */ 439 440 if (sc->sc_set_guest_os == 0) { 441 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %s %s %s", 442 VM_GUEST_INFO_OS_NAME_FULL, 443 ostype, osrelease, machine_arch) != 0) { 444 device_printf(sc->sc_dev, 445 "unable to set full guest OS\n"); 446 sc->sc_rpc_error = 1; 447 } 448 449 /* 450 * Host doesn't like it if we send an OS name it doesn't 451 * recognise, so use "other" for i386 and "other-64" for amd64. 452 */ 453 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %s", 454 VM_GUEST_INFO_OS_NAME, VM_OS_NAME) != 0) { 455 device_printf(sc->sc_dev, "unable to set guest OS\n"); 456 sc->sc_rpc_error = 1; 457 } 458 459 sc->sc_set_guest_os = 1; 460 } 461 } 462 463 static void 464 vmt_sync_guest_clock(struct vmt_softc *sc) 465 { 466 struct vm_backdoor frame; 467 struct timespec ts; 468 469 memset(&frame, 0, sizeof(frame)); 470 frame.eax = VM_MAGIC; 471 frame.ecx = VM_CMD_GET_TIME_FULL; 472 frame.edx = VM_REG_CMD(0, VM_PORT_CMD); 473 vm_cmd(&frame); 474 475 if (__SHIFTOUT(frame.eax, VM_REG_WORD_MASK) != 0xffffffff) { 476 ts.tv_sec = ((uint64_t)( 477 __SHIFTOUT(frame.esi, VM_REG_WORD_MASK) << 32)) | 478 __SHIFTOUT(frame.edx, VM_REG_WORD_MASK); 479 ts.tv_nsec = __SHIFTOUT(frame.ebx, VM_REG_WORD_MASK) * 1000; 480 tc_setclock(&ts); 481 } 482 } 483 484 static void 485 vmt_tick(void *xarg) 486 { 487 struct vmt_softc *sc = xarg; 488 489 vmt_update_guest_info(sc); 490 vmt_update_guest_uptime(sc); 491 492 callout_schedule(&sc->sc_tick, hz * 15); 493 } 494 495 static void 496 vmt_tclo_state_change_success(struct vmt_softc *sc, int success, char state) 497 { 498 if (vm_rpc_send_rpci_tx(sc, "tools.os.statechange.status %d %d", 499 success, state) != 0) { 500 device_printf(sc->sc_dev, 501 "unable to send state change result\n"); 502 sc->sc_rpc_error = 1; 503 } 504 } 505 506 static void 507 vmt_do_shutdown(struct vmt_softc *sc) 508 { 509 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_HALT); 510 vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK); 511 512 device_printf(sc->sc_dev, "host requested shutdown\n"); 513 sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_power); 514 } 515 516 static void 517 vmt_do_reboot(struct vmt_softc *sc) 518 { 519 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_REBOOT); 520 vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK); 521 522 device_printf(sc->sc_dev, "host requested reboot\n"); 523 sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_reset); 524 } 525 526 static void 527 vmt_do_resume(struct vmt_softc *sc) 528 { 529 device_printf(sc->sc_dev, "guest resuming from suspended state\n"); 530 531 vmt_sync_guest_clock(sc); 532 533 /* force guest info update */ 534 sc->sc_hostname[0] = '\0'; 535 sc->sc_set_guest_os = 0; 536 vmt_update_guest_info(sc); 537 538 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_RESUME); 539 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 540 device_printf(sc->sc_dev, "error sending resume response\n"); 541 sc->sc_rpc_error = 1; 542 } 543 544 sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_sleep); 545 } 546 547 static bool 548 vmt_shutdown(device_t self, int flags) 549 { 550 struct vmt_softc *sc = device_private(self); 551 552 if (vm_rpc_send_rpci_tx(sc, 553 "tools.capability.hgfs_server toolbox 0") != 0) { 554 device_printf(sc->sc_dev, 555 "failed to disable hgfs server capability\n"); 556 } 557 558 if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) { 559 device_printf(sc->sc_dev, "failed to send shutdown ping\n"); 560 } 561 562 vm_rpc_close(&sc->sc_tclo_rpc); 563 564 return true; 565 } 566 567 static void 568 vmt_pswitch_event(void *xarg) 569 { 570 struct vmt_event *ev = xarg; 571 572 sysmon_pswitch_event(&ev->ev_smpsw, ev->ev_code); 573 } 574 575 static void 576 vmt_tclo_reset(struct vmt_softc *sc) 577 { 578 579 if (sc->sc_rpc_error != 0) { 580 device_printf(sc->sc_dev, "resetting rpc\n"); 581 vm_rpc_close(&sc->sc_tclo_rpc); 582 583 /* reopen and send the reset reply next time around */ 584 return; 585 } 586 587 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_RESET_REPLY) != 0) { 588 device_printf(sc->sc_dev, "failed to send reset reply\n"); 589 sc->sc_rpc_error = 1; 590 } 591 592 } 593 594 static void 595 vmt_tclo_ping(struct vmt_softc *sc) 596 { 597 598 vmt_update_guest_info(sc); 599 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 600 device_printf(sc->sc_dev, "error sending ping response\n"); 601 sc->sc_rpc_error = 1; 602 } 603 } 604 605 static void 606 vmt_tclo_halt(struct vmt_softc *sc) 607 { 608 609 vmt_do_shutdown(sc); 610 } 611 612 static void 613 vmt_tclo_reboot(struct vmt_softc *sc) 614 { 615 616 vmt_do_reboot(sc); 617 } 618 619 static void 620 vmt_tclo_poweron(struct vmt_softc *sc) 621 { 622 623 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_POWERON); 624 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 625 device_printf(sc->sc_dev, "error sending poweron response\n"); 626 sc->sc_rpc_error = 1; 627 } 628 } 629 630 static void 631 vmt_tclo_suspend(struct vmt_softc *sc) 632 { 633 634 log(LOG_KERN | LOG_NOTICE, 635 "VMware guest entering suspended state\n"); 636 637 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_SUSPEND); 638 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 639 device_printf(sc->sc_dev, "error sending suspend response\n"); 640 sc->sc_rpc_error = 1; 641 } 642 } 643 644 static void 645 vmt_tclo_resume(struct vmt_softc *sc) 646 { 647 648 vmt_do_resume(sc); /* XXX msaitoh extract */ 649 } 650 651 static void 652 vmt_tclo_capreg(struct vmt_softc *sc) 653 { 654 655 /* don't know if this is important at all */ 656 if (vm_rpc_send_rpci_tx(sc, 657 "vmx.capability.unified_loop toolbox") != 0) { 658 device_printf(sc->sc_dev, "unable to set unified loop\n"); 659 sc->sc_rpc_error = 1; 660 } 661 if (vm_rpci_response_successful(sc) == 0) { 662 device_printf(sc->sc_dev, 663 "host rejected unified loop setting\n"); 664 } 665 666 /* the trailing space is apparently important here */ 667 if (vm_rpc_send_rpci_tx(sc, 668 "tools.capability.statechange ") != 0) { 669 device_printf(sc->sc_dev, 670 "unable to send statechange capability\n"); 671 sc->sc_rpc_error = 1; 672 } 673 if (vm_rpci_response_successful(sc) == 0) { 674 device_printf(sc->sc_dev, 675 "host rejected statechange capability\n"); 676 } 677 678 if (vm_rpc_send_rpci_tx(sc, 679 "tools.set.version %u", VM_VERSION_UNMANAGED) != 0) { 680 device_printf(sc->sc_dev, "unable to set tools version\n"); 681 sc->sc_rpc_error = 1; 682 } 683 684 vmt_update_guest_uptime(sc); 685 686 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 687 device_printf(sc->sc_dev, 688 "error sending capabilities_register response\n"); 689 sc->sc_rpc_error = 1; 690 } 691 } 692 693 static void 694 vmt_tclo_broadcastip(struct vmt_softc *sc) 695 { 696 struct ifaddr *iface_addr = NULL; 697 struct ifnet *iface; 698 struct sockaddr_in *guest_ip; 699 int s; 700 struct psref psref; 701 702 /* find first available ipv4 address */ 703 guest_ip = NULL; 704 s = pserialize_read_enter(); 705 IFNET_READER_FOREACH(iface) { 706 707 /* skip loopback */ 708 if (strncmp(iface->if_xname, "lo", 2) == 0 && 709 iface->if_xname[2] >= '0' && 710 iface->if_xname[2] <= '9') { 711 continue; 712 } 713 714 IFADDR_READER_FOREACH(iface_addr, iface) { 715 if (iface_addr->ifa_addr->sa_family != AF_INET) { 716 continue; 717 } 718 719 guest_ip = satosin(iface_addr->ifa_addr); 720 ifa_acquire(iface_addr, &psref); 721 goto got; 722 } 723 } 724 got: 725 pserialize_read_exit(s); 726 727 if (guest_ip != NULL) { 728 if (vm_rpc_send_rpci_tx(sc, "info-set guestinfo.ip %s", 729 inet_ntoa(guest_ip->sin_addr)) != 0) { 730 device_printf(sc->sc_dev, 731 "unable to send guest IP address\n"); 732 sc->sc_rpc_error = 1; 733 } 734 ifa_release(iface_addr, &psref); 735 736 if (vm_rpc_send_str(&sc->sc_tclo_rpc, 737 VM_RPC_REPLY_OK) != 0) { 738 device_printf(sc->sc_dev, 739 "error sending broadcastIP response\n"); 740 sc->sc_rpc_error = 1; 741 } 742 } else { 743 if (vm_rpc_send_str(&sc->sc_tclo_rpc, 744 VM_RPC_REPLY_ERROR_IP_ADDR) != 0) { 745 device_printf(sc->sc_dev, 746 "error sending broadcastIP" 747 " error response\n"); 748 sc->sc_rpc_error = 1; 749 } 750 } 751 } 752 753 int 754 vmt_tclo_process(struct vmt_softc *sc, const char *name) 755 { 756 int i; 757 758 /* Search for rpc command and call handler */ 759 for (i = 0; vmt_tclo_rpc[i].name != NULL; i++) { 760 if (strcmp(vmt_tclo_rpc[i].name, sc->sc_rpc_buf) == 0) { 761 vmt_tclo_rpc[i].cb(sc); 762 return (0); 763 } 764 } 765 766 device_printf(sc->sc_dev, "unknown command: \"%s\"\n", name); 767 768 return (-1); 769 } 770 771 static void 772 vmt_tclo_tick(void *xarg) 773 { 774 struct vmt_softc *sc = xarg; 775 u_int32_t rlen; 776 u_int16_t ack; 777 int delay; 778 779 /* By default, poll every second for new messages */ 780 delay = 1; 781 782 /* reopen tclo channel if it's currently closed */ 783 if (sc->sc_tclo_rpc.channel == 0 && 784 sc->sc_tclo_rpc.cookie1 == 0 && 785 sc->sc_tclo_rpc.cookie2 == 0) { 786 if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) { 787 device_printf(sc->sc_dev, 788 "unable to reopen TCLO channel\n"); 789 delay = 15; 790 goto out; 791 } 792 793 if (vm_rpc_send_str(&sc->sc_tclo_rpc, 794 VM_RPC_RESET_REPLY) != 0) { 795 device_printf(sc->sc_dev, 796 "failed to send reset reply\n"); 797 sc->sc_rpc_error = 1; 798 goto out; 799 } else { 800 sc->sc_rpc_error = 0; 801 } 802 } 803 804 if (sc->sc_tclo_ping) { 805 if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) { 806 device_printf(sc->sc_dev, 807 "failed to send TCLO outgoing ping\n"); 808 sc->sc_rpc_error = 1; 809 goto out; 810 } 811 } 812 813 if (vm_rpc_get_length(&sc->sc_tclo_rpc, &rlen, &ack) != 0) { 814 device_printf(sc->sc_dev, 815 "failed to get length of incoming TCLO data\n"); 816 sc->sc_rpc_error = 1; 817 goto out; 818 } 819 820 if (rlen == 0) { 821 sc->sc_tclo_ping = 1; 822 goto out; 823 } 824 825 if (rlen >= VMT_RPC_BUFLEN) { 826 rlen = VMT_RPC_BUFLEN - 1; 827 } 828 if (vm_rpc_get_data(&sc->sc_tclo_rpc, sc->sc_rpc_buf, rlen, ack) != 0) { 829 device_printf(sc->sc_dev, 830 "failed to get incoming TCLO data\n"); 831 sc->sc_rpc_error = 1; 832 goto out; 833 } 834 sc->sc_tclo_ping = 0; 835 836 /* The VM host can queue multiple messages; continue without delay */ 837 delay = 0; 838 839 #ifdef VMT_DEBUG 840 printf("vmware: received message '%s'\n", sc->sc_rpc_buf); 841 #endif 842 843 if (vmt_tclo_process(sc, sc->sc_rpc_buf) != 0) { 844 if (vm_rpc_send_str(&sc->sc_tclo_rpc, 845 VM_RPC_REPLY_ERROR) != 0) { 846 device_printf(sc->sc_dev, 847 "error sending unknown command reply\n"); 848 sc->sc_rpc_error = 1; 849 } 850 } 851 852 if (sc->sc_rpc_error == 1) { 853 /* On error, give time to recover and wait a second */ 854 delay = 1; 855 } 856 857 out: 858 callout_schedule(&sc->sc_tclo_tick, hz * delay); 859 } 860 861 static void 862 vm_cmd(struct vm_backdoor *frame) 863 { 864 BACKDOOR_OP(BACKDOOR_OP_CMD, frame); 865 } 866 867 static void 868 vm_ins(struct vm_backdoor *frame) 869 { 870 BACKDOOR_OP(BACKDOOR_OP_IN, frame); 871 } 872 873 static void 874 vm_outs(struct vm_backdoor *frame) 875 { 876 BACKDOOR_OP(BACKDOOR_OP_OUT, frame); 877 } 878 879 static int 880 vm_rpc_open(struct vm_rpc *rpc, uint32_t proto) 881 { 882 struct vm_backdoor frame; 883 884 memset(&frame, 0, sizeof(frame)); 885 frame.eax = VM_MAGIC; 886 frame.ebx = proto | VM_RPC_FLAG_COOKIE; 887 frame.ecx = VM_REG_CMD_RPC(VM_RPC_OPEN); 888 frame.edx = VM_REG_PORT_CMD(0); 889 890 vm_cmd(&frame); 891 892 if (__SHIFTOUT(frame.ecx, VM_REG_HIGH_MASK) != 1 || 893 __SHIFTOUT(frame.edx, VM_REG_LOW_MASK) != 0) { 894 /* open-vm-tools retries without VM_RPC_FLAG_COOKIE here.. */ 895 printf("vmware: open failed, eax=%#"PRIxREGISTER 896 ", ecx=%#"PRIxREGISTER", edx=%#"PRIxREGISTER"\n", 897 frame.eax, frame.ecx, frame.edx); 898 return EIO; 899 } 900 901 rpc->channel = __SHIFTOUT(frame.edx, VM_REG_HIGH_MASK); 902 rpc->cookie1 = __SHIFTOUT(frame.esi, VM_REG_WORD_MASK); 903 rpc->cookie2 = __SHIFTOUT(frame.edi, VM_REG_WORD_MASK); 904 905 return 0; 906 } 907 908 static int 909 vm_rpc_close(struct vm_rpc *rpc) 910 { 911 struct vm_backdoor frame; 912 913 memset(&frame, 0, sizeof(frame)); 914 frame.eax = VM_MAGIC; 915 frame.ebx = 0; 916 frame.ecx = VM_REG_CMD_RPC(VM_RPC_CLOSE); 917 frame.edx = VM_REG_PORT_CMD(rpc->channel); 918 frame.edi = rpc->cookie2; 919 frame.esi = rpc->cookie1; 920 921 vm_cmd(&frame); 922 923 if (__SHIFTOUT(frame.ecx, VM_REG_HIGH_MASK) == 0 || 924 __SHIFTOUT(frame.ecx, VM_REG_LOW_MASK) != 0) { 925 printf("vmware: close failed, " 926 "eax=%#"PRIxREGISTER", ecx=%#"PRIxREGISTER"\n", 927 frame.eax, frame.ecx); 928 return EIO; 929 } 930 931 rpc->channel = 0; 932 rpc->cookie1 = 0; 933 rpc->cookie2 = 0; 934 935 return 0; 936 } 937 938 static int 939 vm_rpc_send(const struct vm_rpc *rpc, const uint8_t *buf, uint32_t length) 940 { 941 struct vm_backdoor frame; 942 943 /* Send the length of the command. */ 944 memset(&frame, 0, sizeof(frame)); 945 frame.eax = VM_MAGIC; 946 frame.ebx = length; 947 frame.ecx = VM_REG_CMD_RPC(VM_RPC_SET_LENGTH); 948 frame.edx = VM_REG_PORT_CMD(rpc->channel); 949 frame.esi = rpc->cookie1; 950 frame.edi = rpc->cookie2; 951 952 vm_cmd(&frame); 953 954 if ((__SHIFTOUT(frame.ecx, VM_REG_HIGH_MASK) & VM_RPC_REPLY_SUCCESS) == 955 0) { 956 printf("vmware: sending length failed, " 957 "eax=%#"PRIxREGISTER", ecx=%#"PRIxREGISTER"\n", 958 frame.eax, frame.ecx); 959 return EIO; 960 } 961 962 if (length == 0) 963 return 0; /* Only need to poke once if command is null. */ 964 965 /* Send the command using enhanced RPC. */ 966 memset(&frame, 0, sizeof(frame)); 967 frame.eax = VM_MAGIC; 968 frame.ebx = VM_RPC_ENH_DATA; 969 frame.ecx = length; 970 frame.edx = VM_REG_PORT_RPC(rpc->channel); 971 frame.ebp = rpc->cookie1; 972 frame.edi = rpc->cookie2; 973 frame.esi = (register_t)buf; 974 975 vm_outs(&frame); 976 977 if (__SHIFTOUT(frame.ebx, VM_REG_WORD_MASK) != VM_RPC_ENH_DATA) { 978 /* open-vm-tools retries on VM_RPC_REPLY_CHECKPOINT */ 979 printf("vmware: send failed, ebx=%#"PRIxREGISTER"\n", 980 frame.ebx); 981 return EIO; 982 } 983 984 return 0; 985 } 986 987 static int 988 vm_rpc_send_str(const struct vm_rpc *rpc, const uint8_t *str) 989 { 990 return vm_rpc_send(rpc, str, strlen(str)); 991 } 992 993 static int 994 vm_rpc_get_data(const struct vm_rpc *rpc, char *data, uint32_t length, 995 uint16_t dataid) 996 { 997 struct vm_backdoor frame; 998 999 /* Get data using enhanced RPC. */ 1000 memset(&frame, 0, sizeof(frame)); 1001 frame.eax = VM_MAGIC; 1002 frame.ebx = VM_RPC_ENH_DATA; 1003 frame.ecx = length; 1004 frame.edx = VM_REG_PORT_RPC(rpc->channel); 1005 frame.esi = rpc->cookie1; 1006 frame.edi = (register_t)data; 1007 frame.ebp = rpc->cookie2; 1008 1009 vm_ins(&frame); 1010 1011 /* NUL-terminate the data */ 1012 data[length] = '\0'; 1013 1014 if (__SHIFTOUT(frame.ebx, VM_REG_WORD_MASK) != VM_RPC_ENH_DATA) { 1015 printf("vmware: get data failed, ebx=%#"PRIxREGISTER"\n", 1016 frame.ebx); 1017 return EIO; 1018 } 1019 1020 /* Acknowledge data received. */ 1021 memset(&frame, 0, sizeof(frame)); 1022 frame.eax = VM_MAGIC; 1023 frame.ebx = dataid; 1024 frame.ecx = VM_REG_CMD_RPC(VM_RPC_GET_END); 1025 frame.edx = VM_REG_PORT_CMD(rpc->channel); 1026 frame.esi = rpc->cookie1; 1027 frame.edi = rpc->cookie2; 1028 1029 vm_cmd(&frame); 1030 1031 if (__SHIFTOUT(frame.ecx, VM_REG_HIGH_MASK) == 0) { 1032 printf("vmware: ack data failed, " 1033 "eax=%#"PRIxREGISTER", ecx=%#"PRIxREGISTER"\n", 1034 frame.eax, frame.ecx); 1035 return EIO; 1036 } 1037 1038 return 0; 1039 } 1040 1041 static int 1042 vm_rpc_get_length(const struct vm_rpc *rpc, uint32_t *length, uint16_t *dataid) 1043 { 1044 struct vm_backdoor frame; 1045 1046 memset(&frame, 0, sizeof(frame)); 1047 frame.eax = VM_MAGIC; 1048 frame.ebx = 0; 1049 frame.ecx = VM_REG_CMD_RPC(VM_RPC_GET_LENGTH); 1050 frame.edx = VM_REG_PORT_CMD(rpc->channel); 1051 frame.esi = rpc->cookie1; 1052 frame.edi = rpc->cookie2; 1053 1054 vm_cmd(&frame); 1055 1056 if ((__SHIFTOUT(frame.ecx, VM_REG_HIGH_MASK) & VM_RPC_REPLY_SUCCESS) == 1057 0) { 1058 printf("vmware: get length failed, " 1059 "eax=%#"PRIxREGISTER", ecx=%#"PRIxREGISTER"\n", 1060 frame.eax, frame.ecx); 1061 return EIO; 1062 } 1063 if ((__SHIFTOUT(frame.ecx, VM_REG_HIGH_MASK) & VM_RPC_REPLY_DORECV) == 1064 0) { 1065 *length = 0; 1066 *dataid = 0; 1067 } else { 1068 *length = __SHIFTOUT(frame.ebx, VM_REG_WORD_MASK); 1069 *dataid = __SHIFTOUT(frame.edx, VM_REG_HIGH_MASK); 1070 } 1071 1072 return 0; 1073 } 1074 1075 static int 1076 vm_rpci_response_successful(struct vmt_softc *sc) 1077 { 1078 return (sc->sc_rpc_buf[0] == '1' && sc->sc_rpc_buf[1] == ' '); 1079 } 1080 1081 static int 1082 vm_rpc_send_rpci_tx_buf(struct vmt_softc *sc, const uint8_t *buf, 1083 uint32_t length) 1084 { 1085 struct vm_rpc rpci; 1086 u_int32_t rlen; 1087 u_int16_t ack; 1088 int result = 0; 1089 1090 if (vm_rpc_open(&rpci, VM_RPC_OPEN_RPCI) != 0) { 1091 device_printf(sc->sc_dev, "rpci channel open failed\n"); 1092 return EIO; 1093 } 1094 1095 if (vm_rpc_send(&rpci, sc->sc_rpc_buf, length) != 0) { 1096 device_printf(sc->sc_dev, "unable to send rpci command\n"); 1097 result = EIO; 1098 goto out; 1099 } 1100 1101 if (vm_rpc_get_length(&rpci, &rlen, &ack) != 0) { 1102 device_printf(sc->sc_dev, 1103 "failed to get length of rpci response data\n"); 1104 result = EIO; 1105 goto out; 1106 } 1107 1108 if (rlen > 0) { 1109 if (rlen >= VMT_RPC_BUFLEN) { 1110 rlen = VMT_RPC_BUFLEN - 1; 1111 } 1112 1113 if (vm_rpc_get_data(&rpci, sc->sc_rpc_buf, rlen, ack) != 0) { 1114 device_printf(sc->sc_dev, 1115 "failed to get rpci response data\n"); 1116 result = EIO; 1117 goto out; 1118 } 1119 } 1120 1121 out: 1122 if (vm_rpc_close(&rpci) != 0) { 1123 device_printf(sc->sc_dev, "unable to close rpci channel\n"); 1124 } 1125 1126 return result; 1127 } 1128 1129 static int 1130 vm_rpc_send_rpci_tx(struct vmt_softc *sc, const char *fmt, ...) 1131 { 1132 va_list args; 1133 int len; 1134 1135 va_start(args, fmt); 1136 len = vsnprintf(sc->sc_rpc_buf, VMT_RPC_BUFLEN, fmt, args); 1137 va_end(args); 1138 1139 if (len >= VMT_RPC_BUFLEN) { 1140 device_printf(sc->sc_dev, 1141 "rpci command didn't fit in buffer\n"); 1142 return EIO; 1143 } 1144 1145 return vm_rpc_send_rpci_tx_buf(sc, sc->sc_rpc_buf, len); 1146 } 1147 1148 #if 0 1149 struct vm_backdoor frame; 1150 1151 memset(&frame, 0, sizeof(frame)); 1152 1153 frame.eax = VM_MAGIC; 1154 frame.ecx = VM_CMD_GET_VERSION; 1155 frame.edx = VM_PORT_CMD; 1156 1157 printf("\n"); 1158 printf("eax %#"PRIxREGISTER"\n", frame.eax); 1159 printf("ebx %#"PRIxREGISTER"\n", frame.ebx); 1160 printf("ecx %#"PRIxREGISTER"\n", frame.ecx); 1161 printf("edx %#"PRIxREGISTER"\n", frame.edx) 1162 printf("ebp %#"PRIxREGISTER"\n", frame.ebp); 1163 printf("edi %#"PRIxREGISTER"\n", frame.edi); 1164 printf("esi %#"PRIxREGISTER"\n", frame.esi); 1165 1166 vm_cmd(&frame); 1167 1168 printf("-\n"); 1169 printf("eax %#"PRIxREGISTER"\n", frame.eax); 1170 printf("ebx %#"PRIxREGISTER"\n", frame.ebx); 1171 printf("ecx %#"PRIxREGISTER"\n", frame.ecx); 1172 printf("edx %#"PRIxREGISTER"\n", frame.edx); 1173 printf("ebp %#"PRIxREGISTER"\n", frame.ebp); 1174 printf("edi %#"PRIxREGISTER"\n", frame.edi); 1175 printf("esi %#"PRIxREGISTER"\n", frame.esi); 1176 #endif 1177 1178 /* 1179 * Notes on tracing backdoor activity in vmware-guestd: 1180 * 1181 * - Find the addresses of the inl / rep insb / rep outsb 1182 * instructions used to perform backdoor operations. 1183 * One way to do this is to disassemble vmware-guestd: 1184 * 1185 * $ objdump -S /emul/freebsd/sbin/vmware-guestd > vmware-guestd.S 1186 * 1187 * and search for '<tab>in ' in the resulting file. The rep insb and 1188 * rep outsb code is directly below that. 1189 * 1190 * - Run vmware-guestd under gdb, setting up breakpoints as follows: 1191 * (the addresses shown here are the ones from VMware-server-1.0.10-203137, 1192 * the last version that actually works in FreeBSD emulation on OpenBSD) 1193 * 1194 * break *0x805497b (address of 'in' instruction) 1195 * commands 1 1196 * silent 1197 * echo INOUT\n 1198 * print/x $ecx 1199 * print/x $ebx 1200 * print/x $edx 1201 * continue 1202 * end 1203 * break *0x805497c (address of instruction after 'in') 1204 * commands 2 1205 * silent 1206 * echo ===\n 1207 * print/x $ecx 1208 * print/x $ebx 1209 * print/x $edx 1210 * echo \n 1211 * continue 1212 * end 1213 * break *0x80549b7 (address of instruction before 'rep insb') 1214 * commands 3 1215 * silent 1216 * set variable $inaddr = $edi 1217 * set variable $incount = $ecx 1218 * continue 1219 * end 1220 * break *0x80549ba (address of instruction after 'rep insb') 1221 * commands 4 1222 * silent 1223 * echo IN\n 1224 * print $incount 1225 * x/s $inaddr 1226 * echo \n 1227 * continue 1228 * end 1229 * break *0x80549fb (address of instruction before 'rep outsb') 1230 * commands 5 1231 * silent 1232 * echo OUT\n 1233 * print $ecx 1234 * x/s $esi 1235 * echo \n 1236 * continue 1237 * end 1238 * 1239 * This will produce a log of the backdoor operations, including the 1240 * data sent and received and the relevant register values. You can then 1241 * match the register values to the various constants in this file. 1242 */ 1243