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