1 /* $NetBSD: vmt_subr.c,v 1.2 2020/11/17 17:59:31 ryo 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 76 static void vmt_update_guest_info(struct vmt_softc *); 77 static void vmt_update_guest_uptime(struct vmt_softc *); 78 static void vmt_sync_guest_clock(struct vmt_softc *); 79 80 static void vmt_tick(void *); 81 static void vmt_tclo_tick(void *); 82 static void vmt_clock_sync_tick(void *); 83 static bool vmt_shutdown(device_t, int); 84 static void vmt_pswitch_event(void *); 85 86 extern char hostname[MAXHOSTNAMELEN]; 87 88 static void 89 vmt_probe_cmd(struct vm_backdoor *frame, uint16_t cmd) 90 { 91 memset(frame, 0, sizeof(*frame)); 92 93 (frame->eax).word = VM_MAGIC; 94 (frame->ebx).word = ~VM_MAGIC; 95 (frame->ecx).part.low = cmd; 96 (frame->ecx).part.high = 0xffff; 97 (frame->edx).part.low = VM_PORT_CMD; 98 (frame->edx).part.high = 0; 99 100 vm_cmd(frame); 101 } 102 103 bool 104 vmt_probe(void) 105 { 106 #if BYTE_ORDER == BIG_ENDIAN 107 /* 108 * XXX: doesn't support in big-endian. 109 * vmt has some code depends on little-endian. 110 */ 111 return false; 112 #else 113 struct vm_backdoor frame; 114 115 vmt_probe_cmd(&frame, VM_CMD_GET_VERSION); 116 if (frame.eax.word == 0xffffffff || 117 frame.ebx.word != VM_MAGIC) 118 return false; 119 120 vmt_probe_cmd(&frame, VM_CMD_GET_SPEED); 121 if (frame.eax.word == VM_MAGIC) 122 return false; 123 124 return true; 125 #endif 126 } 127 128 void 129 vmt_common_attach(struct vmt_softc *sc) 130 { 131 device_t self; 132 struct vm_backdoor frame; 133 int rv; 134 135 self = sc->sc_dev; 136 sc->sc_log = NULL; 137 138 /* check again */ 139 vmt_probe_cmd(&frame, VM_CMD_GET_VERSION); 140 if (frame.eax.word == 0xffffffff || 141 frame.ebx.word != VM_MAGIC) { 142 aprint_error_dev(self, "failed to get VMware version\n"); 143 return; 144 } 145 146 /* show uuid */ 147 { 148 struct uuid uuid; 149 uint32_t u; 150 151 vmt_probe_cmd(&frame, VM_CMD_GET_BIOS_UUID); 152 uuid.time_low = htobe32(frame.eax.word); 153 u = htobe32(frame.ebx.word); 154 uuid.time_mid = u >> 16; 155 uuid.time_hi_and_version = u; 156 u = htobe32(frame.ecx.word); 157 uuid.clock_seq_hi_and_reserved = u >> 24; 158 uuid.clock_seq_low = u >> 16; 159 uuid.node[0] = u >> 8; 160 uuid.node[1] = u; 161 u = htobe32(frame.edx.word); 162 uuid.node[2] = u >> 24; 163 uuid.node[3] = u >> 16; 164 uuid.node[4] = u >> 8; 165 uuid.node[5] = u; 166 167 uuid_snprintf(sc->sc_uuid, sizeof(sc->sc_uuid), &uuid); 168 aprint_verbose_dev(sc->sc_dev, "UUID: %s\n", sc->sc_uuid); 169 } 170 171 callout_init(&sc->sc_tick, 0); 172 callout_init(&sc->sc_tclo_tick, 0); 173 callout_init(&sc->sc_clock_sync_tick, 0); 174 175 sc->sc_clock_sync_period_seconds = VMT_CLOCK_SYNC_PERIOD_SECONDS; 176 177 rv = vmt_sysctl_setup_root(self); 178 if (rv != 0) { 179 aprint_error_dev(self, "failed to initialize sysctl " 180 "(err %d)\n", rv); 181 goto free; 182 } 183 184 sc->sc_rpc_buf = kmem_alloc(VMT_RPC_BUFLEN, KM_SLEEP); 185 186 if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) { 187 aprint_error_dev(self, "failed to open backdoor RPC channel (TCLO protocol)\n"); 188 goto free; 189 } 190 sc->sc_tclo_rpc_open = true; 191 192 /* don't know if this is important at all yet */ 193 if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 1") != 0) { 194 aprint_error_dev(self, "failed to set HGFS server capability\n"); 195 goto free; 196 } 197 198 pmf_device_register1(self, NULL, NULL, vmt_shutdown); 199 200 sysmon_task_queue_init(); 201 202 sc->sc_ev_power.ev_smpsw.smpsw_type = PSWITCH_TYPE_POWER; 203 sc->sc_ev_power.ev_smpsw.smpsw_name = device_xname(self); 204 sc->sc_ev_power.ev_code = PSWITCH_EVENT_PRESSED; 205 sysmon_pswitch_register(&sc->sc_ev_power.ev_smpsw); 206 sc->sc_ev_reset.ev_smpsw.smpsw_type = PSWITCH_TYPE_RESET; 207 sc->sc_ev_reset.ev_smpsw.smpsw_name = device_xname(self); 208 sc->sc_ev_reset.ev_code = PSWITCH_EVENT_PRESSED; 209 sysmon_pswitch_register(&sc->sc_ev_reset.ev_smpsw); 210 sc->sc_ev_sleep.ev_smpsw.smpsw_type = PSWITCH_TYPE_SLEEP; 211 sc->sc_ev_sleep.ev_smpsw.smpsw_name = device_xname(self); 212 sc->sc_ev_sleep.ev_code = PSWITCH_EVENT_RELEASED; 213 sysmon_pswitch_register(&sc->sc_ev_sleep.ev_smpsw); 214 sc->sc_smpsw_valid = true; 215 216 callout_setfunc(&sc->sc_tick, vmt_tick, sc); 217 callout_schedule(&sc->sc_tick, hz); 218 219 callout_setfunc(&sc->sc_tclo_tick, vmt_tclo_tick, sc); 220 callout_schedule(&sc->sc_tclo_tick, hz); 221 sc->sc_tclo_ping = 1; 222 223 callout_setfunc(&sc->sc_clock_sync_tick, vmt_clock_sync_tick, sc); 224 callout_schedule(&sc->sc_clock_sync_tick, 225 mstohz(sc->sc_clock_sync_period_seconds * 1000)); 226 227 vmt_sync_guest_clock(sc); 228 229 return; 230 231 free: 232 if (sc->sc_rpc_buf) 233 kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN); 234 pmf_device_register(self, NULL, NULL); 235 if (sc->sc_log) 236 sysctl_teardown(&sc->sc_log); 237 } 238 239 int 240 vmt_common_detach(struct vmt_softc *sc) 241 { 242 if (sc->sc_tclo_rpc_open) 243 vm_rpc_close(&sc->sc_tclo_rpc); 244 245 if (sc->sc_smpsw_valid) { 246 sysmon_pswitch_unregister(&sc->sc_ev_sleep.ev_smpsw); 247 sysmon_pswitch_unregister(&sc->sc_ev_reset.ev_smpsw); 248 sysmon_pswitch_unregister(&sc->sc_ev_power.ev_smpsw); 249 } 250 251 callout_halt(&sc->sc_tick, NULL); 252 callout_destroy(&sc->sc_tick); 253 254 callout_halt(&sc->sc_tclo_tick, NULL); 255 callout_destroy(&sc->sc_tclo_tick); 256 257 callout_halt(&sc->sc_clock_sync_tick, NULL); 258 callout_destroy(&sc->sc_clock_sync_tick); 259 260 if (sc->sc_rpc_buf) 261 kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN); 262 263 if (sc->sc_log) { 264 sysctl_teardown(&sc->sc_log); 265 sc->sc_log = NULL; 266 } 267 268 return 0; 269 } 270 271 static int 272 vmt_sysctl_setup_root(device_t self) 273 { 274 const struct sysctlnode *machdep_node, *vmt_node; 275 struct vmt_softc *sc = device_private(self); 276 int rv; 277 278 rv = sysctl_createv(&sc->sc_log, 0, NULL, &machdep_node, 279 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 280 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); 281 if (rv != 0) 282 goto fail; 283 284 rv = sysctl_createv(&sc->sc_log, 0, &machdep_node, &vmt_node, 285 0, CTLTYPE_NODE, device_xname(self), NULL, 286 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 287 if (rv != 0) 288 goto fail; 289 290 rv = sysctl_createv(&sc->sc_log, 0, &vmt_node, NULL, 291 CTLFLAG_READONLY, CTLTYPE_STRING, "uuid", 292 SYSCTL_DESCR("UUID of virtual machine"), 293 NULL, 0, sc->sc_uuid, 0, 294 CTL_CREATE, CTL_EOL); 295 296 rv = vmt_sysctl_setup_clock_sync(self, vmt_node); 297 if (rv != 0) 298 goto fail; 299 300 return 0; 301 302 fail: 303 sysctl_teardown(&sc->sc_log); 304 sc->sc_log = NULL; 305 306 return rv; 307 } 308 309 static int 310 vmt_sysctl_setup_clock_sync(device_t self, const struct sysctlnode *root_node) 311 { 312 const struct sysctlnode *node, *period_node; 313 struct vmt_softc *sc = device_private(self); 314 int rv; 315 316 rv = sysctl_createv(&sc->sc_log, 0, &root_node, &node, 317 0, CTLTYPE_NODE, "clock_sync", NULL, 318 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 319 if (rv != 0) 320 return rv; 321 322 rv = sysctl_createv(&sc->sc_log, 0, &node, &period_node, 323 CTLFLAG_READWRITE, CTLTYPE_INT, "period", 324 SYSCTL_DESCR("Period, in seconds, at which to update the " 325 "guest's clock"), 326 vmt_sysctl_update_clock_sync_period, 0, (void *)sc, 0, 327 CTL_CREATE, CTL_EOL); 328 return rv; 329 } 330 331 static int 332 vmt_sysctl_update_clock_sync_period(SYSCTLFN_ARGS) 333 { 334 int error, period; 335 struct sysctlnode node; 336 struct vmt_softc *sc; 337 338 node = *rnode; 339 sc = (struct vmt_softc *)node.sysctl_data; 340 341 period = sc->sc_clock_sync_period_seconds; 342 node.sysctl_data = . 343 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 344 if (error || newp == NULL) 345 return error; 346 347 if (sc->sc_clock_sync_period_seconds != period) { 348 callout_halt(&sc->sc_clock_sync_tick, NULL); 349 sc->sc_clock_sync_period_seconds = period; 350 if (sc->sc_clock_sync_period_seconds > 0) 351 callout_schedule(&sc->sc_clock_sync_tick, 352 mstohz(sc->sc_clock_sync_period_seconds * 1000)); 353 } 354 return 0; 355 } 356 357 static void 358 vmt_clock_sync_tick(void *xarg) 359 { 360 struct vmt_softc *sc = xarg; 361 362 vmt_sync_guest_clock(sc); 363 364 callout_schedule(&sc->sc_clock_sync_tick, 365 mstohz(sc->sc_clock_sync_period_seconds * 1000)); 366 } 367 368 static void 369 vmt_update_guest_uptime(struct vmt_softc *sc) 370 { 371 /* host wants uptime in hundredths of a second */ 372 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %" PRId64 "00", 373 VM_GUEST_INFO_UPTIME, time_uptime) != 0) { 374 device_printf(sc->sc_dev, "unable to set guest uptime\n"); 375 sc->sc_rpc_error = 1; 376 } 377 } 378 379 static void 380 vmt_update_guest_info(struct vmt_softc *sc) 381 { 382 if (strncmp(sc->sc_hostname, hostname, sizeof(sc->sc_hostname)) != 0) { 383 strlcpy(sc->sc_hostname, hostname, sizeof(sc->sc_hostname)); 384 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %s", 385 VM_GUEST_INFO_DNS_NAME, sc->sc_hostname) != 0) { 386 device_printf(sc->sc_dev, "unable to set hostname\n"); 387 sc->sc_rpc_error = 1; 388 } 389 } 390 391 /* 392 * we're supposed to pass the full network address information back here, 393 * but that involves xdr (sunrpc) data encoding, which seems a bit unreasonable. 394 */ 395 396 if (sc->sc_set_guest_os == 0) { 397 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %s %s %s", 398 VM_GUEST_INFO_OS_NAME_FULL, ostype, osrelease, machine_arch) != 0) { 399 device_printf(sc->sc_dev, "unable to set full guest OS\n"); 400 sc->sc_rpc_error = 1; 401 } 402 403 /* 404 * host doesn't like it if we send an OS name it doesn't recognise, 405 * so use "other" for i386 and "other-64" for amd64 406 */ 407 if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo %d %s", 408 VM_GUEST_INFO_OS_NAME, VM_OS_NAME) != 0) { 409 device_printf(sc->sc_dev, "unable to set guest OS\n"); 410 sc->sc_rpc_error = 1; 411 } 412 413 sc->sc_set_guest_os = 1; 414 } 415 } 416 417 static void 418 vmt_sync_guest_clock(struct vmt_softc *sc) 419 { 420 struct vm_backdoor frame; 421 struct timespec ts; 422 423 memset(&frame, 0, sizeof(frame)); 424 frame.eax.word = VM_MAGIC; 425 frame.ecx.part.low = VM_CMD_GET_TIME_FULL; 426 frame.edx.part.low = VM_PORT_CMD; 427 vm_cmd(&frame); 428 429 if (frame.eax.word != 0xffffffff) { 430 ts.tv_sec = ((uint64_t)frame.esi.word << 32) | frame.edx.word; 431 ts.tv_nsec = frame.ebx.word * 1000; 432 tc_setclock(&ts); 433 } 434 } 435 436 static void 437 vmt_tick(void *xarg) 438 { 439 struct vmt_softc *sc = xarg; 440 441 vmt_update_guest_info(sc); 442 vmt_update_guest_uptime(sc); 443 444 callout_schedule(&sc->sc_tick, hz * 15); 445 } 446 447 static void 448 vmt_tclo_state_change_success(struct vmt_softc *sc, int success, char state) 449 { 450 if (vm_rpc_send_rpci_tx(sc, "tools.os.statechange.status %d %d", 451 success, state) != 0) { 452 device_printf(sc->sc_dev, "unable to send state change result\n"); 453 sc->sc_rpc_error = 1; 454 } 455 } 456 457 static void 458 vmt_do_shutdown(struct vmt_softc *sc) 459 { 460 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_HALT); 461 vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK); 462 463 device_printf(sc->sc_dev, "host requested shutdown\n"); 464 sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_power); 465 } 466 467 static void 468 vmt_do_reboot(struct vmt_softc *sc) 469 { 470 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_REBOOT); 471 vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK); 472 473 device_printf(sc->sc_dev, "host requested reboot\n"); 474 sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_reset); 475 } 476 477 static void 478 vmt_do_resume(struct vmt_softc *sc) 479 { 480 device_printf(sc->sc_dev, "guest resuming from suspended state\n"); 481 482 vmt_sync_guest_clock(sc); 483 484 /* force guest info update */ 485 sc->sc_hostname[0] = '\0'; 486 sc->sc_set_guest_os = 0; 487 vmt_update_guest_info(sc); 488 489 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_RESUME); 490 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 491 device_printf(sc->sc_dev, "error sending resume response\n"); 492 sc->sc_rpc_error = 1; 493 } 494 495 sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_sleep); 496 } 497 498 static bool 499 vmt_shutdown(device_t self, int flags) 500 { 501 struct vmt_softc *sc = device_private(self); 502 503 if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 0") != 0) { 504 device_printf(sc->sc_dev, "failed to disable hgfs server capability\n"); 505 } 506 507 if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) { 508 device_printf(sc->sc_dev, "failed to send shutdown ping\n"); 509 } 510 511 vm_rpc_close(&sc->sc_tclo_rpc); 512 513 return true; 514 } 515 516 static void 517 vmt_pswitch_event(void *xarg) 518 { 519 struct vmt_event *ev = xarg; 520 521 sysmon_pswitch_event(&ev->ev_smpsw, ev->ev_code); 522 } 523 524 static void 525 vmt_tclo_tick(void *xarg) 526 { 527 struct vmt_softc *sc = xarg; 528 u_int32_t rlen; 529 u_int16_t ack; 530 531 /* reopen tclo channel if it's currently closed */ 532 if (sc->sc_tclo_rpc.channel == 0 && 533 sc->sc_tclo_rpc.cookie1 == 0 && 534 sc->sc_tclo_rpc.cookie2 == 0) { 535 if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) { 536 device_printf(sc->sc_dev, "unable to reopen TCLO channel\n"); 537 callout_schedule(&sc->sc_tclo_tick, hz * 15); 538 return; 539 } 540 541 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_RESET_REPLY) != 0) { 542 device_printf(sc->sc_dev, "failed to send reset reply\n"); 543 sc->sc_rpc_error = 1; 544 goto out; 545 } else { 546 sc->sc_rpc_error = 0; 547 } 548 } 549 550 if (sc->sc_tclo_ping) { 551 if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) { 552 device_printf(sc->sc_dev, "failed to send TCLO outgoing ping\n"); 553 sc->sc_rpc_error = 1; 554 goto out; 555 } 556 } 557 558 if (vm_rpc_get_length(&sc->sc_tclo_rpc, &rlen, &ack) != 0) { 559 device_printf(sc->sc_dev, "failed to get length of incoming TCLO data\n"); 560 sc->sc_rpc_error = 1; 561 goto out; 562 } 563 564 if (rlen == 0) { 565 sc->sc_tclo_ping = 1; 566 goto out; 567 } 568 569 if (rlen >= VMT_RPC_BUFLEN) { 570 rlen = VMT_RPC_BUFLEN - 1; 571 } 572 if (vm_rpc_get_data(&sc->sc_tclo_rpc, sc->sc_rpc_buf, rlen, ack) != 0) { 573 device_printf(sc->sc_dev, "failed to get incoming TCLO data\n"); 574 sc->sc_rpc_error = 1; 575 goto out; 576 } 577 sc->sc_tclo_ping = 0; 578 579 #ifdef VMT_DEBUG 580 printf("vmware: received message '%s'\n", sc->sc_rpc_buf); 581 #endif 582 583 if (strcmp(sc->sc_rpc_buf, "reset") == 0) { 584 585 if (sc->sc_rpc_error != 0) { 586 device_printf(sc->sc_dev, "resetting rpc\n"); 587 vm_rpc_close(&sc->sc_tclo_rpc); 588 /* reopen and send the reset reply next time around */ 589 goto out; 590 } 591 592 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_RESET_REPLY) != 0) { 593 device_printf(sc->sc_dev, "failed to send reset reply\n"); 594 sc->sc_rpc_error = 1; 595 } 596 597 } else if (strcmp(sc->sc_rpc_buf, "ping") == 0) { 598 599 vmt_update_guest_info(sc); 600 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 601 device_printf(sc->sc_dev, "error sending ping response\n"); 602 sc->sc_rpc_error = 1; 603 } 604 605 } else if (strcmp(sc->sc_rpc_buf, "OS_Halt") == 0) { 606 vmt_do_shutdown(sc); 607 } else if (strcmp(sc->sc_rpc_buf, "OS_Reboot") == 0) { 608 vmt_do_reboot(sc); 609 } else if (strcmp(sc->sc_rpc_buf, "OS_PowerOn") == 0) { 610 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_POWERON); 611 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 612 device_printf(sc->sc_dev, "error sending poweron response\n"); 613 sc->sc_rpc_error = 1; 614 } 615 } else if (strcmp(sc->sc_rpc_buf, "OS_Suspend") == 0) { 616 log(LOG_KERN | LOG_NOTICE, "VMware guest entering suspended state\n"); 617 618 vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_SUSPEND); 619 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 620 device_printf(sc->sc_dev, "error sending suspend response\n"); 621 sc->sc_rpc_error = 1; 622 } 623 } else if (strcmp(sc->sc_rpc_buf, "OS_Resume") == 0) { 624 vmt_do_resume(sc); 625 } else if (strcmp(sc->sc_rpc_buf, "Capabilities_Register") == 0) { 626 627 /* don't know if this is important at all */ 628 if (vm_rpc_send_rpci_tx(sc, "vmx.capability.unified_loop toolbox") != 0) { 629 device_printf(sc->sc_dev, "unable to set unified loop\n"); 630 sc->sc_rpc_error = 1; 631 } 632 if (vm_rpci_response_successful(sc) == 0) { 633 device_printf(sc->sc_dev, "host rejected unified loop setting\n"); 634 } 635 636 /* the trailing space is apparently important here */ 637 if (vm_rpc_send_rpci_tx(sc, "tools.capability.statechange ") != 0) { 638 device_printf(sc->sc_dev, "unable to send statechange capability\n"); 639 sc->sc_rpc_error = 1; 640 } 641 if (vm_rpci_response_successful(sc) == 0) { 642 device_printf(sc->sc_dev, "host rejected statechange capability\n"); 643 } 644 645 if (vm_rpc_send_rpci_tx(sc, "tools.set.version %u", VM_VERSION_UNMANAGED) != 0) { 646 device_printf(sc->sc_dev, "unable to set tools version\n"); 647 sc->sc_rpc_error = 1; 648 } 649 650 vmt_update_guest_uptime(sc); 651 652 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 653 device_printf(sc->sc_dev, "error sending capabilities_register response\n"); 654 sc->sc_rpc_error = 1; 655 } 656 } else if (strcmp(sc->sc_rpc_buf, "Set_Option broadcastIP 1") == 0) { 657 struct ifaddr *iface_addr = NULL; 658 struct ifnet *iface; 659 struct sockaddr_in *guest_ip; 660 int s; 661 struct psref psref; 662 663 /* find first available ipv4 address */ 664 guest_ip = NULL; 665 s = pserialize_read_enter(); 666 IFNET_READER_FOREACH(iface) { 667 668 /* skip loopback */ 669 if (strncmp(iface->if_xname, "lo", 2) == 0 && 670 iface->if_xname[2] >= '0' && iface->if_xname[2] <= '9') { 671 continue; 672 } 673 674 IFADDR_READER_FOREACH(iface_addr, iface) { 675 if (iface_addr->ifa_addr->sa_family != AF_INET) { 676 continue; 677 } 678 679 guest_ip = satosin(iface_addr->ifa_addr); 680 ifa_acquire(iface_addr, &psref); 681 goto got; 682 } 683 } 684 got: 685 pserialize_read_exit(s); 686 687 if (guest_ip != NULL) { 688 if (vm_rpc_send_rpci_tx(sc, "info-set guestinfo.ip %s", 689 inet_ntoa(guest_ip->sin_addr)) != 0) { 690 device_printf(sc->sc_dev, "unable to send guest IP address\n"); 691 sc->sc_rpc_error = 1; 692 } 693 ifa_release(iface_addr, &psref); 694 695 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) { 696 device_printf(sc->sc_dev, "error sending broadcastIP response\n"); 697 sc->sc_rpc_error = 1; 698 } 699 } else { 700 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_ERROR_IP_ADDR) != 0) { 701 device_printf(sc->sc_dev, 702 "error sending broadcastIP error response\n"); 703 sc->sc_rpc_error = 1; 704 } 705 } 706 } else { 707 if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_ERROR) != 0) { 708 device_printf(sc->sc_dev, "error sending unknown command reply\n"); 709 sc->sc_rpc_error = 1; 710 } 711 } 712 713 out: 714 callout_schedule(&sc->sc_tclo_tick, sc->sc_tclo_ping ? hz : 1); 715 } 716 717 static void 718 vm_cmd(struct vm_backdoor *frame) 719 { 720 BACKDOOR_OP(BACKDOOR_OP_CMD, frame); 721 } 722 723 static void 724 vm_ins(struct vm_backdoor *frame) 725 { 726 BACKDOOR_OP(BACKDOOR_OP_IN, frame); 727 } 728 729 static void 730 vm_outs(struct vm_backdoor *frame) 731 { 732 BACKDOOR_OP(BACKDOOR_OP_OUT, frame); 733 } 734 735 static int 736 vm_rpc_open(struct vm_rpc *rpc, uint32_t proto) 737 { 738 struct vm_backdoor frame; 739 740 memset(&frame, 0, sizeof(frame)); 741 frame.eax.word = VM_MAGIC; 742 frame.ebx.word = proto | VM_RPC_FLAG_COOKIE; 743 frame.ecx.part.low = VM_CMD_RPC; 744 frame.ecx.part.high = VM_RPC_OPEN; 745 frame.edx.part.low = VM_PORT_CMD; 746 frame.edx.part.high = 0; 747 748 vm_cmd(&frame); 749 750 if (frame.ecx.part.high != 1 || frame.edx.part.low != 0) { 751 /* open-vm-tools retries without VM_RPC_FLAG_COOKIE here.. */ 752 printf("vmware: open failed, eax=%08x, ecx=%08x, edx=%08x\n", 753 frame.eax.word, frame.ecx.word, frame.edx.word); 754 return EIO; 755 } 756 757 rpc->channel = frame.edx.part.high; 758 rpc->cookie1 = frame.esi.word; 759 rpc->cookie2 = frame.edi.word; 760 761 return 0; 762 } 763 764 static int 765 vm_rpc_close(struct vm_rpc *rpc) 766 { 767 struct vm_backdoor frame; 768 769 memset(&frame, 0, sizeof(frame)); 770 frame.eax.word = VM_MAGIC; 771 frame.ebx.word = 0; 772 frame.ecx.part.low = VM_CMD_RPC; 773 frame.ecx.part.high = VM_RPC_CLOSE; 774 frame.edx.part.low = VM_PORT_CMD; 775 frame.edx.part.high = rpc->channel; 776 frame.edi.word = rpc->cookie2; 777 frame.esi.word = rpc->cookie1; 778 779 vm_cmd(&frame); 780 781 if (frame.ecx.part.high == 0 || frame.ecx.part.low != 0) { 782 printf("vmware: close failed, eax=%08x, ecx=%08x\n", 783 frame.eax.word, frame.ecx.word); 784 return EIO; 785 } 786 787 rpc->channel = 0; 788 rpc->cookie1 = 0; 789 rpc->cookie2 = 0; 790 791 return 0; 792 } 793 794 static int 795 vm_rpc_send(const struct vm_rpc *rpc, const uint8_t *buf, uint32_t length) 796 { 797 struct vm_backdoor frame; 798 799 /* Send the length of the command. */ 800 memset(&frame, 0, sizeof(frame)); 801 frame.eax.word = VM_MAGIC; 802 frame.ebx.word = length; 803 frame.ecx.part.low = VM_CMD_RPC; 804 frame.ecx.part.high = VM_RPC_SET_LENGTH; 805 frame.edx.part.low = VM_PORT_CMD; 806 frame.edx.part.high = rpc->channel; 807 frame.esi.word = rpc->cookie1; 808 frame.edi.word = rpc->cookie2; 809 810 vm_cmd(&frame); 811 812 if ((frame.ecx.part.high & VM_RPC_REPLY_SUCCESS) == 0) { 813 printf("vmware: sending length failed, eax=%08x, ecx=%08x\n", 814 frame.eax.word, frame.ecx.word); 815 return EIO; 816 } 817 818 if (length == 0) 819 return 0; /* Only need to poke once if command is null. */ 820 821 /* Send the command using enhanced RPC. */ 822 memset(&frame, 0, sizeof(frame)); 823 frame.eax.word = VM_MAGIC; 824 frame.ebx.word = VM_RPC_ENH_DATA; 825 frame.ecx.word = length; 826 frame.edx.part.low = VM_PORT_RPC; 827 frame.edx.part.high = rpc->channel; 828 frame.ebp.word = rpc->cookie1; 829 frame.edi.word = rpc->cookie2; 830 #if defined(__amd64__) || defined(__aarch64__) 831 frame.esi.quad = (uint64_t)buf; 832 #else 833 frame.esi.word = (uint32_t)buf; 834 #endif 835 836 vm_outs(&frame); 837 838 if (frame.ebx.word != VM_RPC_ENH_DATA) { 839 /* open-vm-tools retries on VM_RPC_REPLY_CHECKPOINT */ 840 printf("vmware: send failed, ebx=%08x\n", frame.ebx.word); 841 return EIO; 842 } 843 844 return 0; 845 } 846 847 static int 848 vm_rpc_send_str(const struct vm_rpc *rpc, const uint8_t *str) 849 { 850 return vm_rpc_send(rpc, str, strlen(str)); 851 } 852 853 static int 854 vm_rpc_get_data(const struct vm_rpc *rpc, char *data, uint32_t length, 855 uint16_t dataid) 856 { 857 struct vm_backdoor frame; 858 859 /* Get data using enhanced RPC. */ 860 memset(&frame, 0, sizeof(frame)); 861 frame.eax.word = VM_MAGIC; 862 frame.ebx.word = VM_RPC_ENH_DATA; 863 frame.ecx.word = length; 864 frame.edx.part.low = VM_PORT_RPC; 865 frame.edx.part.high = rpc->channel; 866 frame.esi.word = rpc->cookie1; 867 #if defined(__amd64__) || defined(__aarch64__) 868 frame.edi.quad = (uint64_t)data; 869 #else 870 frame.edi.word = (uint32_t)data; 871 #endif 872 frame.ebp.word = rpc->cookie2; 873 874 vm_ins(&frame); 875 876 /* NUL-terminate the data */ 877 data[length] = '\0'; 878 879 if (frame.ebx.word != VM_RPC_ENH_DATA) { 880 printf("vmware: get data failed, ebx=%08x\n", 881 frame.ebx.word); 882 return EIO; 883 } 884 885 /* Acknowledge data received. */ 886 memset(&frame, 0, sizeof(frame)); 887 frame.eax.word = VM_MAGIC; 888 frame.ebx.word = dataid; 889 frame.ecx.part.low = VM_CMD_RPC; 890 frame.ecx.part.high = VM_RPC_GET_END; 891 frame.edx.part.low = VM_PORT_CMD; 892 frame.edx.part.high = rpc->channel; 893 frame.esi.word = rpc->cookie1; 894 frame.edi.word = rpc->cookie2; 895 896 vm_cmd(&frame); 897 898 if (frame.ecx.part.high == 0) { 899 printf("vmware: ack data failed, eax=%08x, ecx=%08x\n", 900 frame.eax.word, frame.ecx.word); 901 return EIO; 902 } 903 904 return 0; 905 } 906 907 static int 908 vm_rpc_get_length(const struct vm_rpc *rpc, uint32_t *length, uint16_t *dataid) 909 { 910 struct vm_backdoor frame; 911 912 memset(&frame, 0, sizeof(frame)); 913 frame.eax.word = VM_MAGIC; 914 frame.ebx.word = 0; 915 frame.ecx.part.low = VM_CMD_RPC; 916 frame.ecx.part.high = VM_RPC_GET_LENGTH; 917 frame.edx.part.low = VM_PORT_CMD; 918 frame.edx.part.high = rpc->channel; 919 frame.esi.word = rpc->cookie1; 920 frame.edi.word = rpc->cookie2; 921 922 vm_cmd(&frame); 923 924 if ((frame.ecx.part.high & VM_RPC_REPLY_SUCCESS) == 0) { 925 printf("vmware: get length failed, eax=%08x, ecx=%08x\n", 926 frame.eax.word, frame.ecx.word); 927 return EIO; 928 } 929 if ((frame.ecx.part.high & VM_RPC_REPLY_DORECV) == 0) { 930 *length = 0; 931 *dataid = 0; 932 } else { 933 *length = frame.ebx.word; 934 *dataid = frame.edx.part.high; 935 } 936 937 return 0; 938 } 939 940 static int 941 vm_rpci_response_successful(struct vmt_softc *sc) 942 { 943 return (sc->sc_rpc_buf[0] == '1' && sc->sc_rpc_buf[1] == ' '); 944 } 945 946 static int 947 vm_rpc_send_rpci_tx_buf(struct vmt_softc *sc, const uint8_t *buf, uint32_t length) 948 { 949 struct vm_rpc rpci; 950 u_int32_t rlen; 951 u_int16_t ack; 952 int result = 0; 953 954 if (vm_rpc_open(&rpci, VM_RPC_OPEN_RPCI) != 0) { 955 device_printf(sc->sc_dev, "rpci channel open failed\n"); 956 return EIO; 957 } 958 959 if (vm_rpc_send(&rpci, sc->sc_rpc_buf, length) != 0) { 960 device_printf(sc->sc_dev, "unable to send rpci command\n"); 961 result = EIO; 962 goto out; 963 } 964 965 if (vm_rpc_get_length(&rpci, &rlen, &ack) != 0) { 966 device_printf(sc->sc_dev, "failed to get length of rpci response data\n"); 967 result = EIO; 968 goto out; 969 } 970 971 if (rlen > 0) { 972 if (rlen >= VMT_RPC_BUFLEN) { 973 rlen = VMT_RPC_BUFLEN - 1; 974 } 975 976 if (vm_rpc_get_data(&rpci, sc->sc_rpc_buf, rlen, ack) != 0) { 977 device_printf(sc->sc_dev, "failed to get rpci response data\n"); 978 result = EIO; 979 goto out; 980 } 981 } 982 983 out: 984 if (vm_rpc_close(&rpci) != 0) { 985 device_printf(sc->sc_dev, "unable to close rpci channel\n"); 986 } 987 988 return result; 989 } 990 991 static int 992 vm_rpc_send_rpci_tx(struct vmt_softc *sc, const char *fmt, ...) 993 { 994 va_list args; 995 int len; 996 997 va_start(args, fmt); 998 len = vsnprintf(sc->sc_rpc_buf, VMT_RPC_BUFLEN, fmt, args); 999 va_end(args); 1000 1001 if (len >= VMT_RPC_BUFLEN) { 1002 device_printf(sc->sc_dev, "rpci command didn't fit in buffer\n"); 1003 return EIO; 1004 } 1005 1006 return vm_rpc_send_rpci_tx_buf(sc, sc->sc_rpc_buf, len); 1007 } 1008 1009 #if 0 1010 struct vm_backdoor frame; 1011 1012 memset(&frame, 0, sizeof(frame)); 1013 1014 frame.eax.word = VM_MAGIC; 1015 frame.ecx.part.low = VM_CMD_GET_VERSION; 1016 frame.edx.part.low = VM_PORT_CMD; 1017 1018 printf("\n"); 1019 printf("eax 0x%08x\n", frame.eax.word); 1020 printf("ebx 0x%08x\n", frame.ebx.word); 1021 printf("ecx 0x%08x\n", frame.ecx.word); 1022 printf("edx 0x%08x\n", frame.edx.word); 1023 printf("ebp 0x%08x\n", frame.ebp.word); 1024 printf("edi 0x%08x\n", frame.edi.word); 1025 printf("esi 0x%08x\n", frame.esi.word); 1026 1027 vm_cmd(&frame); 1028 1029 printf("-\n"); 1030 printf("eax 0x%08x\n", frame.eax.word); 1031 printf("ebx 0x%08x\n", frame.ebx.word); 1032 printf("ecx 0x%08x\n", frame.ecx.word); 1033 printf("edx 0x%08x\n", frame.edx.word); 1034 printf("ebp 0x%08x\n", frame.ebp.word); 1035 printf("edi 0x%08x\n", frame.edi.word); 1036 printf("esi 0x%08x\n", frame.esi.word); 1037 #endif 1038 1039 /* 1040 * Notes on tracing backdoor activity in vmware-guestd: 1041 * 1042 * - Find the addresses of the inl / rep insb / rep outsb 1043 * instructions used to perform backdoor operations. 1044 * One way to do this is to disassemble vmware-guestd: 1045 * 1046 * $ objdump -S /emul/freebsd/sbin/vmware-guestd > vmware-guestd.S 1047 * 1048 * and search for '<tab>in ' in the resulting file. The rep insb and 1049 * rep outsb code is directly below that. 1050 * 1051 * - Run vmware-guestd under gdb, setting up breakpoints as follows: 1052 * (the addresses shown here are the ones from VMware-server-1.0.10-203137, 1053 * the last version that actually works in FreeBSD emulation on OpenBSD) 1054 * 1055 * break *0x805497b (address of 'in' instruction) 1056 * commands 1 1057 * silent 1058 * echo INOUT\n 1059 * print/x $ecx 1060 * print/x $ebx 1061 * print/x $edx 1062 * continue 1063 * end 1064 * break *0x805497c (address of instruction after 'in') 1065 * commands 2 1066 * silent 1067 * echo ===\n 1068 * print/x $ecx 1069 * print/x $ebx 1070 * print/x $edx 1071 * echo \n 1072 * continue 1073 * end 1074 * break *0x80549b7 (address of instruction before 'rep insb') 1075 * commands 3 1076 * silent 1077 * set variable $inaddr = $edi 1078 * set variable $incount = $ecx 1079 * continue 1080 * end 1081 * break *0x80549ba (address of instruction after 'rep insb') 1082 * commands 4 1083 * silent 1084 * echo IN\n 1085 * print $incount 1086 * x/s $inaddr 1087 * echo \n 1088 * continue 1089 * end 1090 * break *0x80549fb (address of instruction before 'rep outsb') 1091 * commands 5 1092 * silent 1093 * echo OUT\n 1094 * print $ecx 1095 * x/s $esi 1096 * echo \n 1097 * continue 1098 * end 1099 * 1100 * This will produce a log of the backdoor operations, including the 1101 * data sent and received and the relevant register values. You can then 1102 * match the register values to the various constants in this file. 1103 */ 1104