1/* $NetBSD: vmt.c,v 1.6 2011/10/20 20:13:55 jmcneill 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 * http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
24 */
25
26#include <sys/param.h>
27#include <sys/systm.h>
28#include <sys/kernel.h>
29#include <sys/device.h>
30#include <sys/types.h>
31#include <sys/kmem.h>
32#include <sys/callout.h>
33#include <sys/reboot.h>
34#include <sys/syslog.h>
35#include <sys/proc.h>
36#include <sys/socket.h>
37#include <sys/timetc.h>
38#include <sys/module.h>
39
40#include <net/if.h>
41#include <netinet/in.h>
42
43#include <machine/cpuvar.h>
44
45#include <dev/sysmon/sysmonvar.h>
46#include <dev/sysmon/sysmon_taskq.h>
47
48/* #define VMT_DEBUG */
49
50/* OS name to report to host */
51#ifdef __i386__
52#define VM_OS_NAME	"other"
53#else
54#define VM_OS_NAME	"other-64"
55#endif
56
57/* "The" magic number, always occupies the EAX register. */
58#define VM_MAGIC			0x564D5868
59
60/* Port numbers, passed on EDX.LOW . */
61#define VM_PORT_CMD			0x5658
62#define VM_PORT_RPC			0x5659
63
64/* Commands, passed on ECX.LOW. */
65#define VM_CMD_GET_SPEED		0x01
66#define VM_CMD_APM			0x02
67#define VM_CMD_GET_MOUSEPOS		0x04
68#define VM_CMD_SET_MOUSEPOS		0x05
69#define VM_CMD_GET_CLIPBOARD_LEN	0x06
70#define VM_CMD_GET_CLIPBOARD		0x07
71#define VM_CMD_SET_CLIPBOARD_LEN	0x08
72#define VM_CMD_SET_CLIPBOARD		0x09
73#define VM_CMD_GET_VERSION		0x0a
74#define  VM_VERSION_UNMANAGED			0x7fffffff
75#define VM_CMD_GET_DEVINFO		0x0b
76#define VM_CMD_DEV_ADDREMOVE		0x0c
77#define VM_CMD_GET_GUI_OPTIONS		0x0d
78#define VM_CMD_SET_GUI_OPTIONS		0x0e
79#define VM_CMD_GET_SCREEN_SIZE		0x0f
80#define VM_CMD_GET_HWVER		0x11
81#define VM_CMD_POPUP_OSNOTFOUND		0x12
82#define VM_CMD_GET_BIOS_UUID		0x13
83#define VM_CMD_GET_MEM_SIZE		0x14
84/*#define VM_CMD_GET_TIME		0x17 */	/* deprecated */
85#define VM_CMD_RPC			0x1e
86#define VM_CMD_GET_TIME_FULL		0x2e
87
88/* RPC sub-commands, passed on ECX.HIGH. */
89#define VM_RPC_OPEN			0x00
90#define VM_RPC_SET_LENGTH		0x01
91#define VM_RPC_SET_DATA			0x02
92#define VM_RPC_GET_LENGTH		0x03
93#define VM_RPC_GET_DATA			0x04
94#define VM_RPC_GET_END			0x05
95#define VM_RPC_CLOSE			0x06
96
97/* RPC magic numbers, passed on EBX. */
98#define VM_RPC_OPEN_RPCI	0x49435052UL /* with VM_RPC_OPEN. */
99#define VM_RPC_OPEN_TCLO	0x4F4C4354UL /* with VP_RPC_OPEN. */
100#define VM_RPC_ENH_DATA		0x00010000UL /* with enhanced RPC data calls. */
101
102#define VM_RPC_FLAG_COOKIE	0x80000000UL
103
104/* RPC reply flags */
105#define VM_RPC_REPLY_SUCCESS	0x0001
106#define VM_RPC_REPLY_DORECV	0x0002		/* incoming message available */
107#define VM_RPC_REPLY_CLOSED	0x0004		/* RPC channel is closed */
108#define VM_RPC_REPLY_UNSENT	0x0008		/* incoming message was removed? */
109#define VM_RPC_REPLY_CHECKPOINT	0x0010		/* checkpoint occurred -> retry */
110#define VM_RPC_REPLY_POWEROFF	0x0020		/* underlying device is powering off */
111#define VM_RPC_REPLY_TIMEOUT	0x0040
112#define VM_RPC_REPLY_HB		0x0080		/* high-bandwidth tx/rx available */
113
114/* VM state change IDs */
115#define VM_STATE_CHANGE_HALT	1
116#define VM_STATE_CHANGE_REBOOT	2
117#define VM_STATE_CHANGE_POWERON 3
118#define VM_STATE_CHANGE_RESUME  4
119#define VM_STATE_CHANGE_SUSPEND 5
120
121/* VM guest info keys */
122#define VM_GUEST_INFO_DNS_NAME		1
123#define VM_GUEST_INFO_IP_ADDRESS	2
124#define VM_GUEST_INFO_DISK_FREE_SPACE	3
125#define VM_GUEST_INFO_BUILD_NUMBER	4
126#define VM_GUEST_INFO_OS_NAME_FULL	5
127#define VM_GUEST_INFO_OS_NAME		6
128#define VM_GUEST_INFO_UPTIME		7
129#define VM_GUEST_INFO_MEMORY		8
130#define VM_GUEST_INFO_IP_ADDRESS_V2	9
131
132/* RPC responses */
133#define VM_RPC_REPLY_OK			"OK "
134#define VM_RPC_RESET_REPLY		"OK ATR toolbox"
135#define VM_RPC_REPLY_ERROR		"ERROR Unknown command"
136#define VM_RPC_REPLY_ERROR_IP_ADDR	"ERROR Unable to find guest IP address"
137
138/* A register. */
139union vm_reg {
140	struct {
141		uint16_t low;
142		uint16_t high;
143	} part;
144	uint32_t word;
145#ifdef __amd64__
146	struct {
147		uint32_t low;
148		uint32_t high;
149	} words;
150	uint64_t quad;
151#endif
152} __packed;
153
154/* A register frame. */
155/* XXX 'volatile' as a workaround because BACKDOOR_OP is likely broken */
156struct vm_backdoor {
157	volatile union vm_reg eax;
158	volatile union vm_reg ebx;
159	volatile union vm_reg ecx;
160	volatile union vm_reg edx;
161	volatile union vm_reg esi;
162	volatile union vm_reg edi;
163	volatile union vm_reg ebp;
164} __packed;
165
166/* RPC context. */
167struct vm_rpc {
168	uint16_t channel;
169	uint32_t cookie1;
170	uint32_t cookie2;
171};
172
173static int	vmt_match(device_t, cfdata_t, void *);
174static void	vmt_attach(device_t, device_t, void *);
175static int	vmt_detach(device_t, int);
176
177struct vmt_event {
178	struct sysmon_pswitch	ev_smpsw;
179	int			ev_code;
180};
181
182struct vmt_softc {
183	device_t		sc_dev;
184
185	struct vm_rpc		sc_tclo_rpc;
186	bool			sc_tclo_rpc_open;
187	char			*sc_rpc_buf;
188	int			sc_rpc_error;
189	int			sc_tclo_ping;
190	int			sc_set_guest_os;
191#define VMT_RPC_BUFLEN			256
192
193	struct callout		sc_tick;
194	struct callout		sc_tclo_tick;
195
196	struct vmt_event	sc_ev_power;
197	struct vmt_event	sc_ev_reset;
198	struct vmt_event	sc_ev_sleep;
199	bool			sc_smpsw_valid;
200
201	char			sc_hostname[MAXHOSTNAMELEN];
202};
203
204CFATTACH_DECL_NEW(vmt, sizeof(struct vmt_softc),
205	vmt_match, vmt_attach, vmt_detach, NULL);
206
207static void vm_cmd(struct vm_backdoor *);
208static void vm_ins(struct vm_backdoor *);
209static void vm_outs(struct vm_backdoor *);
210
211/* Functions for communicating with the VM Host. */
212static int vm_rpc_open(struct vm_rpc *, uint32_t);
213static int vm_rpc_close(struct vm_rpc *);
214static int vm_rpc_send(const struct vm_rpc *, const uint8_t *, uint32_t);
215static int vm_rpc_send_str(const struct vm_rpc *, const uint8_t *);
216static int vm_rpc_get_length(const struct vm_rpc *, uint32_t *, uint16_t *);
217static int vm_rpc_get_data(const struct vm_rpc *, char *, uint32_t, uint16_t);
218static int vm_rpc_send_rpci_tx_buf(struct vmt_softc *, const uint8_t *, uint32_t);
219static int vm_rpc_send_rpci_tx(struct vmt_softc *, const char *, ...)
220    __printflike(2, 3);
221static int vm_rpci_response_successful(struct vmt_softc *);
222
223static void vmt_tclo_state_change_success(struct vmt_softc *, int, char);
224static void vmt_do_reboot(struct vmt_softc *);
225static void vmt_do_shutdown(struct vmt_softc *);
226
227static void vmt_update_guest_info(struct vmt_softc *);
228static void vmt_update_guest_uptime(struct vmt_softc *);
229static void vmt_sync_guest_clock(struct vmt_softc *);
230
231static void vmt_tick(void *);
232static void vmt_tclo_tick(void *);
233static bool vmt_shutdown(device_t, int);
234static void vmt_pswitch_event(void *);
235
236extern char hostname[MAXHOSTNAMELEN];
237
238static bool
239vmt_probe(uint32_t *type)
240{
241	struct vm_backdoor frame;
242
243	memset(&frame, 0, sizeof(frame));
244
245	frame.eax.word = VM_MAGIC;
246	frame.ebx.word = ~VM_MAGIC;
247	frame.ecx.part.low = VM_CMD_GET_VERSION;
248	frame.ecx.part.high = 0xffff;
249	frame.edx.part.low  = VM_PORT_CMD;
250	frame.edx.part.high = 0;
251
252	vm_cmd(&frame);
253
254	if (frame.eax.word == 0xffffffff ||
255	    frame.ebx.word != VM_MAGIC)
256		return false;
257
258	if (type)
259		*type = frame.ecx.word;
260
261	return true;
262}
263
264static int
265vmt_match(device_t parent, cfdata_t match, void *aux)
266{
267	struct cpufeature_attach_args *cfaa = aux;
268	struct cpu_info *ci = cfaa->ci;
269
270	if (strcmp(cfaa->name, "vm") != 0)
271		return 0;
272	if ((ci->ci_flags & (CPUF_BSP|CPUF_SP|CPUF_PRIMARY)) == 0)
273		return 0;
274
275	return vmt_probe(NULL);
276}
277
278static const char *
279vmt_type(void)
280{
281	uint32_t vmwaretype = 0;
282
283	vmt_probe(&vmwaretype);
284
285	switch (vmwaretype) {
286	case 1:	return "Express";
287	case 2:	return "ESX Server";
288	case 3:	return "VMware Server";
289	case 4: return "Workstation";
290	default: return "Unknown";
291	}
292}
293
294static void
295vmt_attach(device_t parent, device_t self, void *aux)
296{
297	struct vmt_softc *sc = device_private(self);
298
299	aprint_naive("\n");
300	aprint_normal(": %s\n", vmt_type());
301
302	sc->sc_dev = self;
303	callout_init(&sc->sc_tick, 0);
304	callout_init(&sc->sc_tclo_tick, 0);
305
306	sc->sc_rpc_buf = kmem_alloc(VMT_RPC_BUFLEN, KM_SLEEP);
307	if (sc->sc_rpc_buf == NULL) {
308		aprint_error_dev(self, "unable to allocate buffer for RPC\n");
309		goto free;
310	}
311
312	if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) {
313		aprint_error_dev(self, "failed to open backdoor RPC channel (TCLO protocol)\n");
314		goto free;
315	}
316	sc->sc_tclo_rpc_open = true;
317
318	/* don't know if this is important at all yet */
319	if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 1") != 0) {
320		aprint_error_dev(self, "failed to set HGFS server capability\n");
321		goto free;
322	}
323
324	pmf_device_register1(self, NULL, NULL, vmt_shutdown);
325
326	sysmon_task_queue_init();
327
328	sc->sc_ev_power.ev_smpsw.smpsw_type = PSWITCH_TYPE_POWER;
329	sc->sc_ev_power.ev_smpsw.smpsw_name = device_xname(self);
330	sc->sc_ev_power.ev_code = PSWITCH_EVENT_PRESSED;
331	sysmon_pswitch_register(&sc->sc_ev_power.ev_smpsw);
332	sc->sc_ev_reset.ev_smpsw.smpsw_type = PSWITCH_TYPE_RESET;
333	sc->sc_ev_reset.ev_smpsw.smpsw_name = device_xname(self);
334	sc->sc_ev_reset.ev_code = PSWITCH_EVENT_PRESSED;
335	sysmon_pswitch_register(&sc->sc_ev_reset.ev_smpsw);
336	sc->sc_ev_sleep.ev_smpsw.smpsw_type = PSWITCH_TYPE_SLEEP;
337	sc->sc_ev_sleep.ev_smpsw.smpsw_name = device_xname(self);
338	sc->sc_ev_sleep.ev_code = PSWITCH_EVENT_RELEASED;
339	sysmon_pswitch_register(&sc->sc_ev_sleep.ev_smpsw);
340	sc->sc_smpsw_valid = true;
341
342	callout_setfunc(&sc->sc_tick, vmt_tick, sc);
343	callout_schedule(&sc->sc_tick, hz);
344
345	callout_setfunc(&sc->sc_tclo_tick, vmt_tclo_tick, sc);
346	callout_schedule(&sc->sc_tclo_tick, hz);
347	sc->sc_tclo_ping = 1;
348
349	vmt_sync_guest_clock(sc);
350
351	return;
352
353free:
354	if (sc->sc_rpc_buf)
355		kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN);
356	pmf_device_register(self, NULL, NULL);
357}
358
359static int
360vmt_detach(device_t self, int flags)
361{
362	struct vmt_softc *sc = device_private(self);
363
364	if (sc->sc_tclo_rpc_open)
365		vm_rpc_close(&sc->sc_tclo_rpc);
366
367	if (sc->sc_smpsw_valid) {
368		sysmon_pswitch_unregister(&sc->sc_ev_sleep.ev_smpsw);
369		sysmon_pswitch_unregister(&sc->sc_ev_reset.ev_smpsw);
370		sysmon_pswitch_unregister(&sc->sc_ev_power.ev_smpsw);
371	}
372
373	callout_halt(&sc->sc_tick, NULL);
374	callout_destroy(&sc->sc_tick);
375
376	callout_halt(&sc->sc_tclo_tick, NULL);
377	callout_destroy(&sc->sc_tclo_tick);
378
379	if (sc->sc_rpc_buf)
380		kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN);
381
382	return 0;
383}
384
385static void
386vmt_update_guest_uptime(struct vmt_softc *sc)
387{
388	/* host wants uptime in hundredths of a second */
389	if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %" PRId64 "00",
390	    VM_GUEST_INFO_UPTIME, time_uptime) != 0) {
391		device_printf(sc->sc_dev, "unable to set guest uptime\n");
392		sc->sc_rpc_error = 1;
393	}
394}
395
396static void
397vmt_update_guest_info(struct vmt_softc *sc)
398{
399	if (strncmp(sc->sc_hostname, hostname, sizeof(sc->sc_hostname)) != 0) {
400		strlcpy(sc->sc_hostname, hostname, sizeof(sc->sc_hostname));
401
402		if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %s",
403		    VM_GUEST_INFO_DNS_NAME, sc->sc_hostname) != 0) {
404			device_printf(sc->sc_dev, "unable to set hostname\n");
405			sc->sc_rpc_error = 1;
406		}
407	}
408
409	/*
410	 * we're supposed to pass the full network address information back here,
411	 * but that involves xdr (sunrpc) data encoding, which seems a bit unreasonable.
412	 */
413
414	if (sc->sc_set_guest_os == 0) {
415		if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %s %s %s",
416		    VM_GUEST_INFO_OS_NAME_FULL, ostype, osrelease, machine_arch) != 0) {
417			device_printf(sc->sc_dev, "unable to set full guest OS\n");
418			sc->sc_rpc_error = 1;
419		}
420
421		/*
422		 * host doesn't like it if we send an OS name it doesn't recognise,
423		 * so use "other" for i386 and "other-64" for amd64
424		 */
425		if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %s",
426		    VM_GUEST_INFO_OS_NAME, VM_OS_NAME) != 0) {
427			device_printf(sc->sc_dev, "unable to set guest OS\n");
428			sc->sc_rpc_error = 1;
429		}
430
431		sc->sc_set_guest_os = 1;
432	}
433}
434
435static void
436vmt_sync_guest_clock(struct vmt_softc *sc)
437{
438	struct vm_backdoor frame;
439	struct timespec ts;
440
441	memset(&frame, 0, sizeof(frame));
442	frame.eax.word = VM_MAGIC;
443	frame.ecx.part.low = VM_CMD_GET_TIME_FULL;
444	frame.edx.part.low  = VM_PORT_CMD;
445	vm_cmd(&frame);
446
447	if (frame.eax.word != 0xffffffff) {
448		ts.tv_sec = ((uint64_t)frame.esi.word << 32) | frame.edx.word;
449		ts.tv_nsec = frame.ebx.word * 1000;
450		tc_setclock(&ts);
451	}
452}
453
454static void
455vmt_tick(void *xarg)
456{
457	struct vmt_softc *sc = xarg;
458
459	vmt_update_guest_info(sc);
460	vmt_update_guest_uptime(sc);
461
462	callout_schedule(&sc->sc_tick, hz * 15);
463}
464
465static void
466vmt_tclo_state_change_success(struct vmt_softc *sc, int success, char state)
467{
468	if (vm_rpc_send_rpci_tx(sc, "tools.os.statechange.status %d %d",
469	    success, state) != 0) {
470		device_printf(sc->sc_dev, "unable to send state change result\n");
471		sc->sc_rpc_error = 1;
472	}
473}
474
475static void
476vmt_do_shutdown(struct vmt_softc *sc)
477{
478	vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_HALT);
479	vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK);
480
481	device_printf(sc->sc_dev, "host requested shutdown\n");
482	sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_power);
483}
484
485static void
486vmt_do_reboot(struct vmt_softc *sc)
487{
488	vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_REBOOT);
489	vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK);
490
491	device_printf(sc->sc_dev, "host requested reboot\n");
492	sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_reset);
493}
494
495static void
496vmt_do_resume(struct vmt_softc *sc)
497{
498	device_printf(sc->sc_dev, "guest resuming from suspended state\n");
499
500	vmt_sync_guest_clock(sc);
501
502	/* force guest info update */
503	sc->sc_hostname[0] = '\0';
504	sc->sc_set_guest_os = 0;
505	vmt_update_guest_info(sc);
506
507	vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_RESUME);
508	if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
509		device_printf(sc->sc_dev, "error sending resume response\n");
510		sc->sc_rpc_error = 1;
511	}
512
513	sysmon_task_queue_sched(0, vmt_pswitch_event, &sc->sc_ev_sleep);
514}
515
516static bool
517vmt_shutdown(device_t self, int flags)
518{
519	struct vmt_softc *sc = device_private(self);
520
521	if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 0") != 0) {
522		device_printf(sc->sc_dev, "failed to disable hgfs server capability\n");
523	}
524
525	if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) {
526		device_printf(sc->sc_dev, "failed to send shutdown ping\n");
527	}
528
529	vm_rpc_close(&sc->sc_tclo_rpc);
530
531	return true;
532}
533
534static void
535vmt_pswitch_event(void *xarg)
536{
537	struct vmt_event *ev = xarg;
538
539	sysmon_pswitch_event(&ev->ev_smpsw, ev->ev_code);
540}
541
542static void
543vmt_tclo_tick(void *xarg)
544{
545	struct vmt_softc *sc = xarg;
546	u_int32_t rlen;
547	u_int16_t ack;
548
549	/* reopen tclo channel if it's currently closed */
550	if (sc->sc_tclo_rpc.channel == 0 &&
551	    sc->sc_tclo_rpc.cookie1 == 0 &&
552	    sc->sc_tclo_rpc.cookie2 == 0) {
553		if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) {
554			device_printf(sc->sc_dev, "unable to reopen TCLO channel\n");
555			callout_schedule(&sc->sc_tclo_tick, hz * 15);
556			return;
557		}
558
559		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_RESET_REPLY) != 0) {
560			device_printf(sc->sc_dev, "failed to send reset reply\n");
561			sc->sc_rpc_error = 1;
562			goto out;
563		} else {
564			sc->sc_rpc_error = 0;
565		}
566	}
567
568	if (sc->sc_tclo_ping) {
569		if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) {
570			device_printf(sc->sc_dev, "failed to send TCLO outgoing ping\n");
571			sc->sc_rpc_error = 1;
572			goto out;
573		}
574	}
575
576	if (vm_rpc_get_length(&sc->sc_tclo_rpc, &rlen, &ack) != 0) {
577		device_printf(sc->sc_dev, "failed to get length of incoming TCLO data\n");
578		sc->sc_rpc_error = 1;
579		goto out;
580	}
581
582	if (rlen == 0) {
583		sc->sc_tclo_ping = 1;
584		goto out;
585	}
586
587	if (rlen >= VMT_RPC_BUFLEN) {
588		rlen = VMT_RPC_BUFLEN - 1;
589	}
590	if (vm_rpc_get_data(&sc->sc_tclo_rpc, sc->sc_rpc_buf, rlen, ack) != 0) {
591		device_printf(sc->sc_dev, "failed to get incoming TCLO data\n");
592		sc->sc_rpc_error = 1;
593		goto out;
594	}
595	sc->sc_tclo_ping = 0;
596
597#ifdef VMT_DEBUG
598	printf("vmware: received message '%s'\n", sc->sc_rpc_buf);
599#endif
600
601	if (strcmp(sc->sc_rpc_buf, "reset") == 0) {
602
603		if (sc->sc_rpc_error != 0) {
604			device_printf(sc->sc_dev, "resetting rpc\n");
605			vm_rpc_close(&sc->sc_tclo_rpc);
606			/* reopen and send the reset reply next time around */
607			goto out;
608		}
609
610		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_RESET_REPLY) != 0) {
611			device_printf(sc->sc_dev, "failed to send reset reply\n");
612			sc->sc_rpc_error = 1;
613		}
614
615	} else if (strcmp(sc->sc_rpc_buf, "ping") == 0) {
616
617		vmt_update_guest_info(sc);
618		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
619			device_printf(sc->sc_dev, "error sending ping response\n");
620			sc->sc_rpc_error = 1;
621		}
622
623	} else if (strcmp(sc->sc_rpc_buf, "OS_Halt") == 0) {
624		vmt_do_shutdown(sc);
625	} else if (strcmp(sc->sc_rpc_buf, "OS_Reboot") == 0) {
626		vmt_do_reboot(sc);
627	} else if (strcmp(sc->sc_rpc_buf, "OS_PowerOn") == 0) {
628		vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_POWERON);
629		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
630			device_printf(sc->sc_dev, "error sending poweron response\n");
631			sc->sc_rpc_error = 1;
632		}
633	} else if (strcmp(sc->sc_rpc_buf, "OS_Suspend") == 0) {
634		log(LOG_KERN | LOG_NOTICE, "VMware guest entering suspended state\n");
635
636		vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_SUSPEND);
637		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
638			device_printf(sc->sc_dev, "error sending suspend response\n");
639			sc->sc_rpc_error = 1;
640		}
641	} else if (strcmp(sc->sc_rpc_buf, "OS_Resume") == 0) {
642		vmt_do_resume(sc);
643	} else if (strcmp(sc->sc_rpc_buf, "Capabilities_Register") == 0) {
644
645		/* don't know if this is important at all */
646		if (vm_rpc_send_rpci_tx(sc, "vmx.capability.unified_loop toolbox") != 0) {
647			device_printf(sc->sc_dev, "unable to set unified loop\n");
648			sc->sc_rpc_error = 1;
649		}
650		if (vm_rpci_response_successful(sc) == 0) {
651			device_printf(sc->sc_dev, "host rejected unified loop setting\n");
652		}
653
654		/* the trailing space is apparently important here */
655		if (vm_rpc_send_rpci_tx(sc, "tools.capability.statechange ") != 0) {
656			device_printf(sc->sc_dev, "unable to send statechange capability\n");
657			sc->sc_rpc_error = 1;
658		}
659		if (vm_rpci_response_successful(sc) == 0) {
660			device_printf(sc->sc_dev, "host rejected statechange capability\n");
661		}
662
663		if (vm_rpc_send_rpci_tx(sc, "tools.set.version %u", VM_VERSION_UNMANAGED) != 0) {
664			device_printf(sc->sc_dev, "unable to set tools version\n");
665			sc->sc_rpc_error = 1;
666		}
667
668		vmt_update_guest_uptime(sc);
669
670		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
671			device_printf(sc->sc_dev, "error sending capabilities_register response\n");
672			sc->sc_rpc_error = 1;
673		}
674	} else if (strcmp(sc->sc_rpc_buf, "Set_Option broadcastIP 1") == 0) {
675		struct ifnet *iface;
676		struct sockaddr_in *guest_ip;
677
678		/* find first available ipv4 address */
679		guest_ip = NULL;
680		TAILQ_FOREACH(iface, &ifnet, if_list) {
681			struct ifaddr *iface_addr;
682
683			/* skip loopback */
684			if (strncmp(iface->if_xname, "lo", 2) == 0 &&
685			    iface->if_xname[2] >= '0' && iface->if_xname[2] <= '9') {
686				continue;
687			}
688
689			TAILQ_FOREACH(iface_addr, &iface->if_addrlist, ifa_list) {
690				if (iface_addr->ifa_addr->sa_family != AF_INET) {
691					continue;
692				}
693
694				guest_ip = satosin(iface_addr->ifa_addr);
695				break;
696			}
697		}
698
699		if (guest_ip != NULL) {
700			if (vm_rpc_send_rpci_tx(sc, "info-set guestinfo.ip %s",
701			    inet_ntoa(guest_ip->sin_addr)) != 0) {
702				device_printf(sc->sc_dev, "unable to send guest IP address\n");
703				sc->sc_rpc_error = 1;
704			}
705
706			if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
707				device_printf(sc->sc_dev, "error sending broadcastIP response\n");
708				sc->sc_rpc_error = 1;
709			}
710		} else {
711			if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_ERROR_IP_ADDR) != 0) {
712				device_printf(sc->sc_dev,
713				    "error sending broadcastIP error response\n");
714				sc->sc_rpc_error = 1;
715			}
716		}
717	} else {
718		if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_ERROR) != 0) {
719			device_printf(sc->sc_dev, "error sending unknown command reply\n");
720			sc->sc_rpc_error = 1;
721		}
722	}
723
724out:
725	callout_schedule(&sc->sc_tclo_tick, sc->sc_tclo_ping ? hz : 1);
726}
727
728#define BACKDOOR_OP_I386(op, frame)		\
729	__asm__ __volatile__ (			\
730		"pushal;"			\
731		"pushl %%eax;"			\
732		"movl 0x18(%%eax), %%ebp;"	\
733		"movl 0x14(%%eax), %%edi;"	\
734		"movl 0x10(%%eax), %%esi;"	\
735		"movl 0x0c(%%eax), %%edx;"	\
736		"movl 0x08(%%eax), %%ecx;"	\
737		"movl 0x04(%%eax), %%ebx;"	\
738		"movl 0x00(%%eax), %%eax;"	\
739		op				\
740		"xchgl %%eax, 0x00(%%esp);"	\
741		"movl %%ebp, 0x18(%%eax);"	\
742		"movl %%edi, 0x14(%%eax);"	\
743		"movl %%esi, 0x10(%%eax);"	\
744		"movl %%edx, 0x0c(%%eax);"	\
745		"movl %%ecx, 0x08(%%eax);"	\
746		"movl %%ebx, 0x04(%%eax);"	\
747		"popl 0x00(%%eax);"		\
748		"popal;"			\
749		:				\
750		:"a"(frame)			\
751	)
752
753#define BACKDOOR_OP_AMD64(op, frame)		\
754	__asm__ __volatile__ (			\
755		"pushq %%rbp;			\n\t" \
756		"pushq %%rax;			\n\t" \
757		"movq 0x30(%%rax), %%rbp;	\n\t" \
758		"movq 0x28(%%rax), %%rdi;	\n\t" \
759		"movq 0x20(%%rax), %%rsi;	\n\t" \
760		"movq 0x18(%%rax), %%rdx;	\n\t" \
761		"movq 0x10(%%rax), %%rcx;	\n\t" \
762		"movq 0x08(%%rax), %%rbx;	\n\t" \
763		"movq 0x00(%%rax), %%rax;	\n\t" \
764		op				"\n\t" \
765		"xchgq %%rax, 0x00(%%rsp);	\n\t" \
766		"movq %%rbp, 0x30(%%rax);	\n\t" \
767		"movq %%rdi, 0x28(%%rax);	\n\t" \
768		"movq %%rsi, 0x20(%%rax);	\n\t" \
769		"movq %%rdx, 0x18(%%rax);	\n\t" \
770		"movq %%rcx, 0x10(%%rax);	\n\t" \
771		"movq %%rbx, 0x08(%%rax);	\n\t" \
772		"popq 0x00(%%rax);		\n\t" \
773		"popq %%rbp;			\n\t" \
774		: /* No outputs. */ : "a" (frame) \
775		  /* No pushal on amd64 so warn gcc about the clobbered registers. */ \
776		: "rbx", "rcx", "rdx", "rdi", "rsi", "cc", "memory" \
777	)
778
779
780#ifdef __i386__
781#define BACKDOOR_OP(op, frame) BACKDOOR_OP_I386(op, frame)
782#else
783#define BACKDOOR_OP(op, frame) BACKDOOR_OP_AMD64(op, frame)
784#endif
785
786static void
787vm_cmd(struct vm_backdoor *frame)
788{
789	BACKDOOR_OP("inl %%dx, %%eax;", frame);
790}
791
792static void
793vm_ins(struct vm_backdoor *frame)
794{
795	BACKDOOR_OP("cld;\n\trep insb;", frame);
796}
797
798static void
799vm_outs(struct vm_backdoor *frame)
800{
801	BACKDOOR_OP("cld;\n\trep outsb;", frame);
802}
803
804static int
805vm_rpc_open(struct vm_rpc *rpc, uint32_t proto)
806{
807	struct vm_backdoor frame;
808
809	memset(&frame, 0, sizeof(frame));
810	frame.eax.word      = VM_MAGIC;
811	frame.ebx.word      = proto | VM_RPC_FLAG_COOKIE;
812	frame.ecx.part.low  = VM_CMD_RPC;
813	frame.ecx.part.high = VM_RPC_OPEN;
814	frame.edx.part.low  = VM_PORT_CMD;
815	frame.edx.part.high = 0;
816
817	vm_cmd(&frame);
818
819	if (frame.ecx.part.high != 1 || frame.edx.part.low != 0) {
820		/* open-vm-tools retries without VM_RPC_FLAG_COOKIE here.. */
821		printf("vmware: open failed, eax=%08x, ecx=%08x, edx=%08x\n",
822			frame.eax.word, frame.ecx.word, frame.edx.word);
823		return EIO;
824	}
825
826	rpc->channel = frame.edx.part.high;
827	rpc->cookie1 = frame.esi.word;
828	rpc->cookie2 = frame.edi.word;
829
830	return 0;
831}
832
833static int
834vm_rpc_close(struct vm_rpc *rpc)
835{
836	struct vm_backdoor frame;
837
838	memset(&frame, 0, sizeof(frame));
839	frame.eax.word      = VM_MAGIC;
840	frame.ebx.word      = 0;
841	frame.ecx.part.low  = VM_CMD_RPC;
842	frame.ecx.part.high = VM_RPC_CLOSE;
843	frame.edx.part.low  = VM_PORT_CMD;
844	frame.edx.part.high = rpc->channel;
845	frame.edi.word      = rpc->cookie2;
846	frame.esi.word      = rpc->cookie1;
847
848	vm_cmd(&frame);
849
850	if (frame.ecx.part.high == 0 || frame.ecx.part.low != 0) {
851		printf("vmware: close failed, eax=%08x, ecx=%08x\n",
852				frame.eax.word, frame.ecx.word);
853		return EIO;
854	}
855
856	rpc->channel = 0;
857	rpc->cookie1 = 0;
858	rpc->cookie2 = 0;
859
860	return 0;
861}
862
863static int
864vm_rpc_send(const struct vm_rpc *rpc, const uint8_t *buf, uint32_t length)
865{
866	struct vm_backdoor frame;
867
868	/* Send the length of the command. */
869	memset(&frame, 0, sizeof(frame));
870	frame.eax.word = VM_MAGIC;
871	frame.ebx.word = length;
872	frame.ecx.part.low  = VM_CMD_RPC;
873	frame.ecx.part.high = VM_RPC_SET_LENGTH;
874	frame.edx.part.low  = VM_PORT_CMD;
875	frame.edx.part.high = rpc->channel;
876	frame.esi.word = rpc->cookie1;
877	frame.edi.word = rpc->cookie2;
878
879	vm_cmd(&frame);
880
881	if ((frame.ecx.part.high & VM_RPC_REPLY_SUCCESS) == 0) {
882		printf("vmware: sending length failed, eax=%08x, ecx=%08x\n",
883				frame.eax.word, frame.ecx.word);
884		return EIO;
885	}
886
887	if (length == 0)
888		return 0; /* Only need to poke once if command is null. */
889
890	/* Send the command using enhanced RPC. */
891	memset(&frame, 0, sizeof(frame));
892	frame.eax.word = VM_MAGIC;
893	frame.ebx.word = VM_RPC_ENH_DATA;
894	frame.ecx.word = length;
895	frame.edx.part.low  = VM_PORT_RPC;
896	frame.edx.part.high = rpc->channel;
897	frame.ebp.word = rpc->cookie1;
898	frame.edi.word = rpc->cookie2;
899#ifdef __amd64__
900	frame.esi.quad = (uint64_t)buf;
901#else
902	frame.esi.word = (uint32_t)buf;
903#endif
904
905	vm_outs(&frame);
906
907	if (frame.ebx.word != VM_RPC_ENH_DATA) {
908		/* open-vm-tools retries on VM_RPC_REPLY_CHECKPOINT */
909		printf("vmware: send failed, ebx=%08x\n", frame.ebx.word);
910		return EIO;
911	}
912
913	return 0;
914}
915
916static int
917vm_rpc_send_str(const struct vm_rpc *rpc, const uint8_t *str)
918{
919	return vm_rpc_send(rpc, str, strlen(str));
920}
921
922static int
923vm_rpc_get_data(const struct vm_rpc *rpc, char *data, uint32_t length,
924    uint16_t dataid)
925{
926	struct vm_backdoor frame;
927
928	/* Get data using enhanced RPC. */
929	memset(&frame, 0, sizeof(frame));
930	frame.eax.word      = VM_MAGIC;
931	frame.ebx.word      = VM_RPC_ENH_DATA;
932	frame.ecx.word      = length;
933	frame.edx.part.low  = VM_PORT_RPC;
934	frame.edx.part.high = rpc->channel;
935	frame.esi.word      = rpc->cookie1;
936#ifdef __amd64__
937	frame.edi.quad      = (uint64_t)data;
938#else
939	frame.edi.word      = (uint32_t)data;
940#endif
941	frame.ebp.word      = rpc->cookie2;
942
943	vm_ins(&frame);
944
945	/* NUL-terminate the data */
946	data[length] = '\0';
947
948	if (frame.ebx.word != VM_RPC_ENH_DATA) {
949		printf("vmware: get data failed, ebx=%08x\n",
950				frame.ebx.word);
951		return EIO;
952	}
953
954	/* Acknowledge data received. */
955	memset(&frame, 0, sizeof(frame));
956	frame.eax.word      = VM_MAGIC;
957	frame.ebx.word      = dataid;
958	frame.ecx.part.low  = VM_CMD_RPC;
959	frame.ecx.part.high = VM_RPC_GET_END;
960	frame.edx.part.low  = VM_PORT_CMD;
961	frame.edx.part.high = rpc->channel;
962	frame.esi.word      = rpc->cookie1;
963	frame.edi.word      = rpc->cookie2;
964
965	vm_cmd(&frame);
966
967	if (frame.ecx.part.high == 0) {
968		printf("vmware: ack data failed, eax=%08x, ecx=%08x\n",
969				frame.eax.word, frame.ecx.word);
970		return EIO;
971	}
972
973	return 0;
974}
975
976static int
977vm_rpc_get_length(const struct vm_rpc *rpc, uint32_t *length, uint16_t *dataid)
978{
979	struct vm_backdoor frame;
980
981	memset(&frame, 0, sizeof(frame));
982	frame.eax.word      = VM_MAGIC;
983	frame.ebx.word      = 0;
984	frame.ecx.part.low  = VM_CMD_RPC;
985	frame.ecx.part.high = VM_RPC_GET_LENGTH;
986	frame.edx.part.low  = VM_PORT_CMD;
987	frame.edx.part.high = rpc->channel;
988	frame.esi.word      = rpc->cookie1;
989	frame.edi.word      = rpc->cookie2;
990
991	vm_cmd(&frame);
992
993	if ((frame.ecx.part.high & VM_RPC_REPLY_SUCCESS) == 0) {
994		printf("vmware: get length failed, eax=%08x, ecx=%08x\n",
995				frame.eax.word, frame.ecx.word);
996		return EIO;
997	}
998	if ((frame.ecx.part.high & VM_RPC_REPLY_DORECV) == 0) {
999		*length = 0;
1000		*dataid = 0;
1001	} else {
1002		*length = frame.ebx.word;
1003		*dataid = frame.edx.part.high;
1004	}
1005
1006	return 0;
1007}
1008
1009static int
1010vm_rpci_response_successful(struct vmt_softc *sc)
1011{
1012	return (sc->sc_rpc_buf[0] == '1' && sc->sc_rpc_buf[1] == ' ');
1013}
1014
1015static int
1016vm_rpc_send_rpci_tx_buf(struct vmt_softc *sc, const uint8_t *buf, uint32_t length)
1017{
1018	struct vm_rpc rpci;
1019	u_int32_t rlen;
1020	u_int16_t ack;
1021	int result = 0;
1022
1023	if (vm_rpc_open(&rpci, VM_RPC_OPEN_RPCI) != 0) {
1024		device_printf(sc->sc_dev, "rpci channel open failed\n");
1025		return EIO;
1026	}
1027
1028	if (vm_rpc_send(&rpci, sc->sc_rpc_buf, length) != 0) {
1029		device_printf(sc->sc_dev, "unable to send rpci command\n");
1030		result = EIO;
1031		goto out;
1032	}
1033
1034	if (vm_rpc_get_length(&rpci, &rlen, &ack) != 0) {
1035		device_printf(sc->sc_dev, "failed to get length of rpci response data\n");
1036		result = EIO;
1037		goto out;
1038	}
1039
1040	if (rlen > 0) {
1041		if (rlen >= VMT_RPC_BUFLEN) {
1042			rlen = VMT_RPC_BUFLEN - 1;
1043		}
1044
1045		if (vm_rpc_get_data(&rpci, sc->sc_rpc_buf, rlen, ack) != 0) {
1046			device_printf(sc->sc_dev, "failed to get rpci response data\n");
1047			result = EIO;
1048			goto out;
1049		}
1050	}
1051
1052out:
1053	if (vm_rpc_close(&rpci) != 0) {
1054		device_printf(sc->sc_dev, "unable to close rpci channel\n");
1055	}
1056
1057	return result;
1058}
1059
1060static int
1061vm_rpc_send_rpci_tx(struct vmt_softc *sc, const char *fmt, ...)
1062{
1063	va_list args;
1064	int len;
1065
1066	va_start(args, fmt);
1067	len = vsnprintf(sc->sc_rpc_buf, VMT_RPC_BUFLEN, fmt, args);
1068	va_end(args);
1069
1070	if (len >= VMT_RPC_BUFLEN) {
1071		device_printf(sc->sc_dev, "rpci command didn't fit in buffer\n");
1072		return EIO;
1073	}
1074
1075	return vm_rpc_send_rpci_tx_buf(sc, sc->sc_rpc_buf, len);
1076}
1077
1078#if 0
1079	struct vm_backdoor frame;
1080
1081	memset(&frame, 0, sizeof(frame));
1082
1083	frame.eax.word = VM_MAGIC;
1084	frame.ecx.part.low = VM_CMD_GET_VERSION;
1085	frame.edx.part.low  = VM_PORT_CMD;
1086
1087	printf("\n");
1088	printf("eax 0x%08x\n", frame.eax.word);
1089	printf("ebx 0x%08x\n", frame.ebx.word);
1090	printf("ecx 0x%08x\n", frame.ecx.word);
1091	printf("edx 0x%08x\n", frame.edx.word);
1092	printf("ebp 0x%08x\n", frame.ebp.word);
1093	printf("edi 0x%08x\n", frame.edi.word);
1094	printf("esi 0x%08x\n", frame.esi.word);
1095
1096	vm_cmd(&frame);
1097
1098	printf("-\n");
1099	printf("eax 0x%08x\n", frame.eax.word);
1100	printf("ebx 0x%08x\n", frame.ebx.word);
1101	printf("ecx 0x%08x\n", frame.ecx.word);
1102	printf("edx 0x%08x\n", frame.edx.word);
1103	printf("ebp 0x%08x\n", frame.ebp.word);
1104	printf("edi 0x%08x\n", frame.edi.word);
1105	printf("esi 0x%08x\n", frame.esi.word);
1106#endif
1107
1108/*
1109 * Notes on tracing backdoor activity in vmware-guestd:
1110 *
1111 * - Find the addresses of the inl / rep insb / rep outsb
1112 *   instructions used to perform backdoor operations.
1113 *   One way to do this is to disassemble vmware-guestd:
1114 *
1115 *   $ objdump -S /emul/freebsd/sbin/vmware-guestd > vmware-guestd.S
1116 *
1117 *   and search for '<tab>in ' in the resulting file.  The rep insb and
1118 *   rep outsb code is directly below that.
1119 *
1120 * - Run vmware-guestd under gdb, setting up breakpoints as follows:
1121 *   (the addresses shown here are the ones from VMware-server-1.0.10-203137,
1122 *   the last version that actually works in FreeBSD emulation on OpenBSD)
1123 *
1124 * break *0x805497b   (address of 'in' instruction)
1125 * commands 1
1126 * silent
1127 * echo INOUT\n
1128 * print/x $ecx
1129 * print/x $ebx
1130 * print/x $edx
1131 * continue
1132 * end
1133 * break *0x805497c   (address of instruction after 'in')
1134 * commands 2
1135 * silent
1136 * echo ===\n
1137 * print/x $ecx
1138 * print/x $ebx
1139 * print/x $edx
1140 * echo \n
1141 * continue
1142 * end
1143 * break *0x80549b7   (address of instruction before 'rep insb')
1144 * commands 3
1145 * silent
1146 * set variable $inaddr = $edi
1147 * set variable $incount = $ecx
1148 * continue
1149 * end
1150 * break *0x80549ba   (address of instruction after 'rep insb')
1151 * commands 4
1152 * silent
1153 * echo IN\n
1154 * print $incount
1155 * x/s $inaddr
1156 * echo \n
1157 * continue
1158 * end
1159 * break *0x80549fb    (address of instruction before 'rep outsb')
1160 * commands 5
1161 * silent
1162 * echo OUT\n
1163 * print $ecx
1164 * x/s $esi
1165 * echo \n
1166 * continue
1167 * end
1168 *
1169 * This will produce a log of the backdoor operations, including the
1170 * data sent and received and the relevant register values.  You can then
1171 * match the register values to the various constants in this file.
1172 */
1173
1174MODULE(MODULE_CLASS_DRIVER, vmt, NULL);
1175
1176#ifdef _MODULE
1177#include "ioconf.c"
1178#endif
1179
1180static int
1181vmt_modcmd(modcmd_t cmd, void *aux)
1182{
1183	int error = 0;
1184
1185	switch (cmd) {
1186	case MODULE_CMD_INIT:
1187#ifdef _MODULE
1188		error = config_init_component(cfdriver_ioconf_vmt,
1189		    cfattach_ioconf_vmt, cfdata_ioconf_vmt);
1190#endif
1191		break;
1192	case MODULE_CMD_FINI:
1193#ifdef _MODULE
1194		error = config_fini_component(cfdriver_ioconf_vmt,
1195		    cfattach_ioconf_vmt, cfdata_ioconf_vmt);
1196#endif
1197		break;
1198	case MODULE_CMD_AUTOUNLOAD:
1199		error = EBUSY;
1200		break;
1201	default:
1202		error = ENOTTY;
1203		break;
1204	}
1205
1206	return error;
1207}
1208