xref: /netbsd-src/sys/dev/vmt/vmt_subr.c (revision 9fd8799cb5ceb66c69f2eb1a6d26a1d587ba1f1e)
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 = &period;
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