The report on bugs shows vmt(4) lagging behind and I sent a working
working open-vm-tools port to ports@ yesterday.

In case the port gets imported and there are no further regressions wrt.
the functionality vmt(4) already provides, here's a tentative diff to
remove the driver entirely.

Not asking for OKs at this point because the port neede testing test and
I have only tested with it anyway, but vmt(4) supports i386 as well.

Thoughts?


Index: sys/dev/pv/vmt.c
===================================================================
RCS file: sys/dev/pv/vmt.c
diff -N sys/dev/pv/vmt.c
--- sys/dev/pv/vmt.c    24 Jun 2020 22:03:40 -0000      1.19
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,1521 +0,0 @@
-/*     $OpenBSD: vmt.c,v 1.19 2020/06/24 22:03:40 cheloha Exp $ */
-
-/*
- * Copyright (c) 2007 David Crawshaw <[email protected]>
- * Copyright (c) 2008 David Gwynne <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#if !defined(__i386__) && !defined(__amd64__)
-#error vmt(4) is only supported on i386 and amd64
-#endif
-
-/*
- * Protocol reverse engineered by Ken Kato:
- * https://sites.google.com/site/chitchatvmback/backdoor
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/timeout.h>
-#include <sys/signalvar.h>
-#include <sys/syslog.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <sys/task.h>
-#include <sys/sensors.h>
-
-#include <net/if.h>
-#include <net/if_var.h>
-#include <netinet/in.h>
-
-#include <dev/pv/pvvar.h>
-
-/* "The" magic number, always occupies the EAX register. */
-#define VM_MAGIC                       0x564D5868
-
-/* Port numbers, passed on EDX.LOW . */
-#define VM_PORT_CMD                    0x5658
-#define VM_PORT_RPC                    0x5659
-
-/* Commands, passed on ECX.LOW. */
-#define VM_CMD_GET_SPEED               0x01
-#define VM_CMD_APM                     0x02
-#define VM_CMD_GET_MOUSEPOS            0x04
-#define VM_CMD_SET_MOUSEPOS            0x05
-#define VM_CMD_GET_CLIPBOARD_LEN       0x06
-#define VM_CMD_GET_CLIPBOARD           0x07
-#define VM_CMD_SET_CLIPBOARD_LEN       0x08
-#define VM_CMD_SET_CLIPBOARD           0x09
-#define VM_CMD_GET_VERSION             0x0a
-#define  VM_VERSION_UNMANAGED                  0x7fffffff
-#define VM_CMD_GET_DEVINFO             0x0b
-#define VM_CMD_DEV_ADDREMOVE           0x0c
-#define VM_CMD_GET_GUI_OPTIONS         0x0d
-#define VM_CMD_SET_GUI_OPTIONS         0x0e
-#define VM_CMD_GET_SCREEN_SIZE         0x0f
-#define VM_CMD_GET_HWVER               0x11
-#define VM_CMD_POPUP_OSNOTFOUND                0x12
-#define VM_CMD_GET_BIOS_UUID           0x13
-#define VM_CMD_GET_MEM_SIZE            0x14
-/*#define VM_CMD_GET_TIME              0x17 */ /* deprecated */
-#define VM_CMD_RPC                     0x1e
-#define VM_CMD_GET_TIME_FULL           0x2e
-
-/* RPC sub-commands, passed on ECX.HIGH. */
-#define VM_RPC_OPEN                    0x00
-#define VM_RPC_SET_LENGTH              0x01
-#define VM_RPC_SET_DATA                        0x02
-#define VM_RPC_GET_LENGTH              0x03
-#define VM_RPC_GET_DATA                        0x04
-#define VM_RPC_GET_END                 0x05
-#define VM_RPC_CLOSE                   0x06
-
-/* RPC magic numbers, passed on EBX. */
-#define VM_RPC_OPEN_RPCI       0x49435052UL /* with VM_RPC_OPEN. */
-#define VM_RPC_OPEN_TCLO       0x4F4C4354UL /* with VP_RPC_OPEN. */
-#define VM_RPC_ENH_DATA                0x00010000UL /* with enhanced RPC data 
calls. */
-
-#define VM_RPC_FLAG_COOKIE     0x80000000UL
-
-/* RPC reply flags */
-#define VM_RPC_REPLY_SUCCESS   0x0001
-#define VM_RPC_REPLY_DORECV    0x0002          /* incoming message available */
-#define VM_RPC_REPLY_CLOSED    0x0004          /* RPC channel is closed */
-#define VM_RPC_REPLY_UNSENT    0x0008          /* incoming message was 
removed? */
-#define VM_RPC_REPLY_CHECKPOINT        0x0010          /* checkpoint occurred 
-> retry */
-#define VM_RPC_REPLY_POWEROFF  0x0020          /* underlying device is 
powering off */
-#define VM_RPC_REPLY_TIMEOUT   0x0040
-#define VM_RPC_REPLY_HB                0x0080          /* high-bandwidth tx/rx 
available */
-
-/* VM state change IDs */
-#define VM_STATE_CHANGE_HALT   1
-#define VM_STATE_CHANGE_REBOOT 2
-#define VM_STATE_CHANGE_POWERON 3
-#define VM_STATE_CHANGE_RESUME  4
-#define VM_STATE_CHANGE_SUSPEND 5
-
-/* VM guest info keys */
-#define VM_GUEST_INFO_DNS_NAME         1
-#define VM_GUEST_INFO_IP_ADDRESS       2
-#define VM_GUEST_INFO_DISK_FREE_SPACE  3
-#define VM_GUEST_INFO_BUILD_NUMBER     4
-#define VM_GUEST_INFO_OS_NAME_FULL     5
-#define VM_GUEST_INFO_OS_NAME          6
-#define VM_GUEST_INFO_UPTIME           7
-#define VM_GUEST_INFO_MEMORY           8
-#define VM_GUEST_INFO_IP_ADDRESS_V2    9
-
-/* RPC responses */
-#define VM_RPC_REPLY_OK                        "OK "
-#define VM_RPC_RESET_REPLY             "OK ATR toolbox"
-#define VM_RPC_REPLY_ERROR             "ERROR Unknown command"
-#define VM_RPC_REPLY_ERROR_IP_ADDR     "ERROR Unable to find guest IP address"
-
-/* VM backup error codes */
-#define VM_BACKUP_SUCCESS              0
-#define VM_BACKUP_SYNC_ERROR           3
-#define VM_BACKUP_REMOTE_ABORT         4
-
-#define VM_BACKUP_TIMEOUT              30 /* seconds */
-
-/* A register. */
-union vm_reg {
-       struct {
-               uint16_t low;
-               uint16_t high;
-       } part;
-       uint32_t word;
-#ifdef __amd64__
-       struct {
-               uint32_t low;
-               uint32_t high;
-       } words;
-       uint64_t quad;
-#endif
-} __packed;
-
-/* A register frame. */
-struct vm_backdoor {
-       union vm_reg eax;
-       union vm_reg ebx;
-       union vm_reg ecx;
-       union vm_reg edx;
-       union vm_reg esi;
-       union vm_reg edi;
-       union vm_reg ebp;
-} __packed;
-
-/* RPC context. */
-struct vm_rpc {
-       uint16_t channel;
-       uint32_t cookie1;
-       uint32_t cookie2;
-};
-
-struct vmt_softc {
-       struct device           sc_dev;
-
-       struct vm_rpc           sc_tclo_rpc;
-       char                    *sc_rpc_buf;
-       int                     sc_rpc_error;
-       int                     sc_tclo_ping;
-       int                     sc_set_guest_os;
-       int                     sc_quiesce;
-       struct task             sc_quiesce_task;
-#define VMT_RPC_BUFLEN         4096
-
-       struct timeout          sc_tick;
-       struct timeout          sc_tclo_tick;
-       struct ksensordev       sc_sensordev;
-       struct ksensor          sc_sensor;
-
-       char                    sc_hostname[MAXHOSTNAMELEN];
-};
-
-#ifdef VMT_DEBUG
-#define DPRINTF(_arg...)       printf(_arg)
-#else
-#define DPRINTF(_arg...)       do {} while(0)
-#endif
-#define DEVNAME(_s)            ((_s)->sc_dev.dv_xname)
-
-void    vm_cmd(struct vm_backdoor *);
-void    vm_ins(struct vm_backdoor *);
-void    vm_outs(struct vm_backdoor *);
-
-/* Functions for communicating with the VM Host. */
-int     vm_rpc_open(struct vm_rpc *, uint32_t);
-int     vm_rpc_close(struct vm_rpc *);
-int     vm_rpc_send(const struct vm_rpc *, const uint8_t *, uint32_t);
-int     vm_rpc_send_str(const struct vm_rpc *, const uint8_t *);
-int     vm_rpc_get_length(const struct vm_rpc *, uint32_t *, uint16_t *);
-int     vm_rpc_get_data(const struct vm_rpc *, char *, uint32_t, uint16_t);
-int     vm_rpc_send_rpci_tx_buf(struct vmt_softc *, const uint8_t *, uint32_t);
-int     vm_rpc_send_rpci_tx(struct vmt_softc *, const char *, ...)
-           __attribute__((__format__(__kprintf__,2,3)));
-int     vm_rpci_response_successful(struct vmt_softc *);
-
-int     vmt_kvop(void *, int, char *, char *, size_t);
-
-void    vmt_probe_cmd(struct vm_backdoor *, uint16_t);
-void    vmt_tclo_state_change_success(struct vmt_softc *, int, char);
-void    vmt_do_reboot(struct vmt_softc *);
-void    vmt_do_shutdown(struct vmt_softc *);
-void    vmt_shutdown(void *);
-
-void    vmt_clear_guest_info(struct vmt_softc *);
-void    vmt_update_guest_info(struct vmt_softc *);
-void    vmt_update_guest_uptime(struct vmt_softc *);
-
-void    vmt_tick_hook(struct device *self);
-void    vmt_tick(void *);
-void    vmt_resume(void);
-
-int     vmt_match(struct device *, void *, void *);
-void    vmt_attach(struct device *, struct device *, void *);
-int     vmt_activate(struct device *, int);
-
-void    vmt_tclo_tick(void *);
-int     vmt_tclo_process(struct vmt_softc *, const char *);
-void    vmt_tclo_reset(struct vmt_softc *);
-void    vmt_tclo_ping(struct vmt_softc *);
-void    vmt_tclo_halt(struct vmt_softc *);
-void    vmt_tclo_reboot(struct vmt_softc *);
-void    vmt_tclo_poweron(struct vmt_softc *);
-void    vmt_tclo_suspend(struct vmt_softc *);
-void    vmt_tclo_resume(struct vmt_softc *);
-void    vmt_tclo_capreg(struct vmt_softc *);
-void    vmt_tclo_broadcastip(struct vmt_softc *);
-
-void    vmt_set_backup_status(struct vmt_softc *, const char *, int,
-           const char *);
-void    vmt_quiesce_task(void *);
-void    vmt_quiesce_done_task(void *);
-void    vmt_tclo_abortbackup(struct vmt_softc *);
-void    vmt_tclo_startbackup(struct vmt_softc *);
-void    vmt_tclo_backupdone(struct vmt_softc *);
-
-int     vmt_probe(void);
-
-struct vmt_tclo_rpc {
-       const char      *name;
-       void            (*cb)(struct vmt_softc *);
-} vmt_tclo_rpc[] = {
-       /* Keep sorted by name (case-sensitive) */
-        { "Capabilities_Register",      vmt_tclo_capreg },
-        { "OS_Halt",                    vmt_tclo_halt },
-        { "OS_PowerOn",                 vmt_tclo_poweron },
-        { "OS_Reboot",                  vmt_tclo_reboot },
-        { "OS_Resume",                  vmt_tclo_resume },
-        { "OS_Suspend",                 vmt_tclo_suspend },
-        { "Set_Option broadcastIP 1",   vmt_tclo_broadcastip },
-        { "ping",                       vmt_tclo_ping },
-        { "reset",                      vmt_tclo_reset },
-        { "vmbackup.abort",            vmt_tclo_abortbackup },
-        { "vmbackup.snapshotDone",     vmt_tclo_backupdone },
-        { "vmbackup.start 1",          vmt_tclo_startbackup },
-        { NULL },
-#if 0
-       /* Various unsupported commands */
-       { "Set_Option autohide 0" },
-       { "Set_Option copypaste 1" },
-       { "Set_Option enableDnD 1" },
-       { "Set_Option enableMessageBusTunnel 0" },
-       { "Set_Option linkRootHgfsShare 0" },
-       { "Set_Option mapRootHgfsShare 0" },
-       { "Set_Option synctime 1" },
-       { "Set_Option synctime.period 0" },
-       { "Set_Option time.synchronize.tools.enable 1" },
-       { "Set_Option time.synchronize.tools.percentCorrection 0" },
-       { "Set_Option time.synchronize.tools.slewCorrection 1" },
-       { "Set_Option time.synchronize.tools.startup 1" },
-       { "Set_Option toolScripts.afterPowerOn 1" },
-       { "Set_Option toolScripts.afterResume 1" },
-       { "Set_Option toolScripts.beforePowerOff 1" },
-       { "Set_Option toolScripts.beforeSuspend 1" },
-       { "Time_Synchronize 0" },
-       { "Vix_1_Relayed_Command \"38cdcae40e075d66\"" },
-#endif
-};
-
-struct cfattach vmt_ca = {
-       sizeof(struct vmt_softc),
-       vmt_match,
-       vmt_attach,
-       NULL,
-       vmt_activate
-};
-
-struct cfdriver vmt_cd = {
-       NULL,
-       "vmt",
-       DV_DULL
-};
-
-extern char hostname[MAXHOSTNAMELEN];
-
-void
-vmt_probe_cmd(struct vm_backdoor *frame, uint16_t cmd)
-{
-       bzero(frame, sizeof(*frame));
-
-       (frame->eax).word = VM_MAGIC;
-       (frame->ebx).word = ~VM_MAGIC;
-       (frame->ecx).part.low = cmd;
-       (frame->ecx).part.high = 0xffff;
-       (frame->edx).part.low  = VM_PORT_CMD;
-       (frame->edx).part.high = 0;
-
-       vm_cmd(frame);
-}
-
-int
-vmt_probe(void)
-{
-       struct vm_backdoor frame;
-
-       vmt_probe_cmd(&frame, VM_CMD_GET_VERSION);
-       if (frame.eax.word == 0xffffffff ||
-           frame.ebx.word != VM_MAGIC)
-               return (0);
-
-       vmt_probe_cmd(&frame, VM_CMD_GET_SPEED);
-       if (frame.eax.word == VM_MAGIC)
-               return (0);
-
-       return (1);
-}
-
-int
-vmt_match(struct device *parent, void *match, void *aux)
-{
-       struct pv_attach_args   *pva = aux;
-       struct pvbus_hv         *hv = &pva->pva_hv[PVBUS_VMWARE];
-
-       if (hv->hv_base == 0)
-               return (0);
-       if (!vmt_probe())
-               return (0);
-
-       return (1);
-}
-
-void
-vmt_attach(struct device *parent, struct device *self, void *aux)
-{
-       struct vmt_softc *sc = (struct vmt_softc *)self;
-       struct pv_attach_args   *pva = aux;
-       struct pvbus_hv         *hv = &pva->pva_hv[PVBUS_VMWARE];
-
-       printf("\n");
-       sc->sc_rpc_buf = malloc(VMT_RPC_BUFLEN, M_DEVBUF, M_NOWAIT);
-       if (sc->sc_rpc_buf == NULL) {
-               printf("%s: unable to allocate buffer for RPC\n",
-                   DEVNAME(sc));
-               return;
-       }
-
-       if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) {
-               printf("%s: failed to open backdoor RPC channel "
-                   "(TCLO protocol)\n", DEVNAME(sc));
-               goto free;
-       }
-
-       /* don't know if this is important at all yet */
-       if (vm_rpc_send_rpci_tx(sc,
-           "tools.capability.hgfs_server toolbox 1") != 0) {
-               printf(": failed to set HGFS server capability\n");
-               goto free;
-       }
-
-       strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
-           sizeof(sc->sc_sensordev.xname));
-
-       sc->sc_sensor.type = SENSOR_TIMEDELTA;
-       sc->sc_sensor.status = SENSOR_S_UNKNOWN;
-
-       sensor_attach(&sc->sc_sensordev, &sc->sc_sensor);
-       sensordev_install(&sc->sc_sensordev);
-
-       config_mountroot(self, vmt_tick_hook);
-
-       timeout_set(&sc->sc_tclo_tick, vmt_tclo_tick, sc);
-       timeout_add_sec(&sc->sc_tclo_tick, 1);
-       sc->sc_tclo_ping = 1;
-
-       /* pvbus(4) key/value interface */
-       hv->hv_kvop = vmt_kvop;
-       hv->hv_arg = sc;
-
-       return;
-
-free:
-       free(sc->sc_rpc_buf, M_DEVBUF, VMT_RPC_BUFLEN);
-}
-
-int
-vmt_kvop(void *arg, int op, char *key, char *value, size_t valuelen)
-{
-       struct vmt_softc *sc = arg;
-       char *buf = NULL, *ptr;
-       size_t bufsz;
-       int error = 0;
-
-       bufsz = VMT_RPC_BUFLEN;
-       buf = malloc(bufsz, M_TEMP|M_ZERO, M_WAITOK);
-
-       switch (op) {
-       case PVBUS_KVWRITE:
-               if ((size_t)snprintf(buf, bufsz, "info-set %s %s",
-                   key, value) >= bufsz) {
-                       DPRINTF("%s: write command too long", DEVNAME(sc));
-                       error = EINVAL;
-                       goto done;
-               }
-               break;
-       case PVBUS_KVREAD:
-               if ((size_t)snprintf(buf, bufsz, "info-get %s",
-                   key) >= bufsz) {
-                       DPRINTF("%s: read command too long", DEVNAME(sc));
-                       error = EINVAL;
-                       goto done;
-               }
-               break;
-       default:
-               error = EOPNOTSUPP;
-               goto done;
-       }
-
-       if (vm_rpc_send_rpci_tx(sc, "%s", buf) != 0) {
-               DPRINTF("%s: error sending command: %s\n", DEVNAME(sc), buf);
-               sc->sc_rpc_error = 1;
-               error = EIO;
-               goto done;
-       }
-
-       if (vm_rpci_response_successful(sc) == 0) {
-               DPRINTF("%s: host rejected command: %s\n", DEVNAME(sc), buf);
-               error = EINVAL;
-               goto done;
-       }
-
-       /* skip response that was tested in vm_rpci_response_successful() */
-       ptr = sc->sc_rpc_buf + 2;
-
-       /* might truncat, copy anyway but return error */
-       if (strlcpy(value, ptr, valuelen) >= valuelen)
-               error = ENOMEM;
-
- done:
-       free(buf, M_TEMP, bufsz);
-       return (error);
-}
-
-void
-vmt_resume(void)
-{
-       struct vm_backdoor frame;
-       extern void rdrand(void *);
-
-       bzero(&frame, sizeof(frame));
-       frame.eax.word = VM_MAGIC;
-       frame.ecx.part.low = VM_CMD_GET_TIME_FULL;
-       frame.edx.part.low  = VM_PORT_CMD;
-       vm_cmd(&frame);
-
-       rdrand(NULL);
-       enqueue_randomness(frame.eax.word);
-       enqueue_randomness(frame.esi.word);
-       enqueue_randomness(frame.edx.word);
-       enqueue_randomness(frame.ebx.word);
-       resume_randomness(NULL, 0);
-}
-
-int
-vmt_activate(struct device *self, int act)
-{
-       int rv = 0;
-
-       switch (act) {
-       case DVACT_POWERDOWN:
-               vmt_shutdown(self);
-               break;
-       case DVACT_RESUME:
-               vmt_resume();
-               break;
-       }
-       return (rv);
-}
-
-
-void
-vmt_update_guest_uptime(struct vmt_softc *sc)
-{
-       /* host wants uptime in hundredths of a second */
-       if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %lld00",
-           VM_GUEST_INFO_UPTIME, (long long)getuptime()) != 0) {
-               DPRINTF("%s: unable to set guest uptime", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_clear_guest_info(struct vmt_softc *sc)
-{
-       sc->sc_hostname[0] = '\0';
-       sc->sc_set_guest_os = 0;
-}
-
-void
-vmt_update_guest_info(struct vmt_softc *sc)
-{
-       if (strncmp(sc->sc_hostname, hostname, sizeof(sc->sc_hostname)) != 0) {
-               strlcpy(sc->sc_hostname, hostname, sizeof(sc->sc_hostname));
-
-               if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %s",
-                   VM_GUEST_INFO_DNS_NAME, sc->sc_hostname) != 0) {
-                       DPRINTF("%s: unable to set hostname", DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-       }
-
-       /*
-        * We're supposed to pass the full network address information back
-        * here, but that involves xdr (sunrpc) data encoding, which seems a
-        * bit unreasonable.
-        */
-
-       if (sc->sc_set_guest_os == 0) {
-               if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %s %s %s",
-                   VM_GUEST_INFO_OS_NAME_FULL,
-                   ostype, osrelease, osversion) != 0) {
-                       DPRINTF("%s: unable to set full guest OS", DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-
-               /*
-                * Host doesn't like it if we send an OS name it doesn't
-                * recognise, so use the closest match, which happens
-                * to be FreeBSD.
-                */
-
-               if (vm_rpc_send_rpci_tx(sc, "SetGuestInfo  %d %s",
-                   VM_GUEST_INFO_OS_NAME, "FreeBSD") != 0) {
-                       DPRINTF("%s: unable to set guest OS", DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-
-               sc->sc_set_guest_os = 1;
-       }
-}
-
-void
-vmt_tick_hook(struct device *self)
-{
-       struct vmt_softc *sc = (struct vmt_softc *)self;
-
-       timeout_set(&sc->sc_tick, vmt_tick, sc);
-       vmt_tick(sc);
-}
-
-void
-vmt_tick(void *xarg)
-{
-       struct vmt_softc *sc = xarg;
-       struct vm_backdoor frame;
-       struct timeval *guest = &sc->sc_sensor.tv;
-       struct timeval host, diff;
-
-       microtime(guest);
-
-       bzero(&frame, sizeof(frame));
-       frame.eax.word = VM_MAGIC;
-       frame.ecx.part.low = VM_CMD_GET_TIME_FULL;
-       frame.edx.part.low  = VM_PORT_CMD;
-       vm_cmd(&frame);
-
-       if (frame.eax.word != 0xffffffff) {
-               host.tv_sec = ((uint64_t)frame.esi.word << 32) | frame.edx.word;
-               host.tv_usec = frame.ebx.word;
-
-               timersub(guest, &host, &diff);
-
-               sc->sc_sensor.value = (u_int64_t)diff.tv_sec * 1000000000LL +
-                   (u_int64_t)diff.tv_usec * 1000LL;
-               sc->sc_sensor.status = SENSOR_S_OK;
-       } else {
-               sc->sc_sensor.status = SENSOR_S_UNKNOWN;
-       }
-
-       vmt_update_guest_info(sc);
-       vmt_update_guest_uptime(sc);
-
-       timeout_add_sec(&sc->sc_tick, 15);
-}
-
-void
-vmt_tclo_state_change_success(struct vmt_softc *sc, int success, char state)
-{
-       if (vm_rpc_send_rpci_tx(sc, "tools.os.statechange.status %d %d",
-           success, state) != 0) {
-               DPRINTF("%s: unable to send state change result\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_do_shutdown(struct vmt_softc *sc)
-{
-       vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_HALT);
-       vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK);
-       pvbus_shutdown(&sc->sc_dev);
-}
-
-void
-vmt_do_reboot(struct vmt_softc *sc)
-{
-       vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_REBOOT);
-       vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK);
-       pvbus_reboot(&sc->sc_dev);
-}
-
-void
-vmt_shutdown(void *arg)
-{
-       struct vmt_softc *sc = arg;
-
-       if (vm_rpc_send_rpci_tx(sc,
-           "tools.capability.hgfs_server toolbox 0") != 0) {
-               DPRINTF("%s: failed to disable hgfs server capability\n",
-                   DEVNAME(sc));
-       }
-
-       if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) {
-               DPRINTF("%s: failed to send shutdown ping\n", DEVNAME(sc));
-       }
-
-       vm_rpc_close(&sc->sc_tclo_rpc);
-}
-
-void
-vmt_tclo_reset(struct vmt_softc *sc)
-{
-       if (sc->sc_rpc_error != 0) {
-               DPRINTF("%s: resetting rpc\n", DEVNAME(sc));
-               vm_rpc_close(&sc->sc_tclo_rpc);
-
-               /* reopen and send the reset reply next time around */
-               sc->sc_rpc_error = 1;
-               return;
-       }
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_RESET_REPLY) != 0) {
-               DPRINTF("%s: failed to send reset reply\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_ping(struct vmt_softc *sc)
-{
-       vmt_update_guest_info(sc);
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
-               DPRINTF("%s: error sending ping response\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_halt(struct vmt_softc *sc)
-{
-       vmt_do_shutdown(sc);
-}
-
-void
-vmt_tclo_reboot(struct vmt_softc *sc)
-{
-       vmt_do_reboot(sc);
-}
-
-void
-vmt_tclo_poweron(struct vmt_softc *sc)
-{
-       vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_POWERON);
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
-               DPRINTF("%s: error sending poweron response\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_suspend(struct vmt_softc *sc)
-{
-       log(LOG_KERN | LOG_NOTICE,
-           "VMware guest entering suspended state\n");
-
-       suspend_randomness();
-
-       vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_SUSPEND);
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
-               DPRINTF("%s: error sending suspend response\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_resume(struct vmt_softc *sc)
-{
-       log(LOG_KERN | LOG_NOTICE,
-           "VMware guest resuming from suspended state\n");
-
-       /* force guest info update */
-       vmt_clear_guest_info(sc);
-       vmt_update_guest_info(sc);
-       vmt_resume();
-
-       vmt_tclo_state_change_success(sc, 1, VM_STATE_CHANGE_RESUME);
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
-               DPRINTF("%s: error sending resume response\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_capreg(struct vmt_softc *sc)
-{
-       /* don't know if this is important at all */
-       if (vm_rpc_send_rpci_tx(sc,
-           "vmx.capability.unified_loop toolbox") != 0) {
-               DPRINTF("%s: unable to set unified loop\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-
-       if (vm_rpci_response_successful(sc) == 0) {
-               DPRINTF("%s: host rejected unified loop setting\n",
-                   DEVNAME(sc));
-       }
-
-       /* the trailing space is apparently important here */
-       if (vm_rpc_send_rpci_tx(sc,
-           "tools.capability.statechange ") != 0) {
-               DPRINTF("%s: unable to send statechange capability\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-
-       if (vm_rpci_response_successful(sc) == 0) {
-               DPRINTF("%s: host rejected statechange capability\n",
-                   DEVNAME(sc));
-       }
-
-       if (vm_rpc_send_rpci_tx(sc, "tools.set.version %u",
-           VM_VERSION_UNMANAGED) != 0) {
-               DPRINTF("%s: unable to set tools version\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-
-       vmt_clear_guest_info(sc);
-       vmt_update_guest_uptime(sc);
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, VM_RPC_REPLY_OK) != 0) {
-               DPRINTF("%s: error sending capabilities_register"
-                   " response\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_broadcastip(struct vmt_softc *sc)
-{
-       struct ifnet *iface;
-       struct sockaddr_in *guest_ip;
-
-       /* find first available ipv4 address */
-       guest_ip = NULL;
-       TAILQ_FOREACH(iface, &ifnet, if_list) {
-               struct ifaddr *iface_addr;
-
-               /* skip loopback */
-               if (strncmp(iface->if_xname, "lo", 2) == 0 &&
-                   iface->if_xname[2] >= '0' &&
-                   iface->if_xname[2] <= '9') {
-                       continue;
-               }
-
-               TAILQ_FOREACH(iface_addr, &iface->if_addrlist,
-                   ifa_list) {
-                       if (iface_addr->ifa_addr->sa_family != AF_INET)
-                               continue;
-
-                       guest_ip = satosin(iface_addr->ifa_addr);
-                       break;
-               }
-       }
-
-       if (guest_ip != NULL) {
-               char ip[INET_ADDRSTRLEN];
-
-               inet_ntop(AF_INET, &guest_ip->sin_addr, ip, sizeof(ip));
-               if (vm_rpc_send_rpci_tx(sc, "info-set guestinfo.ip %s",
-                   ip) != 0) {
-                       DPRINTF("%s: unable to send guest IP address\n",
-                           DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-
-               if (vm_rpc_send_str(&sc->sc_tclo_rpc,
-                   VM_RPC_REPLY_OK) != 0) {
-                       DPRINTF("%s: error sending broadcastIP"
-                           " response\n", DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-       } else {
-               if (vm_rpc_send_str(&sc->sc_tclo_rpc,
-                   VM_RPC_REPLY_ERROR_IP_ADDR) != 0) {
-                       DPRINTF("%s: error sending broadcastIP"
-                           " error response\n", DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-       }
-}
-
-void
-vmt_set_backup_status(struct vmt_softc *sc, const char *state, int code,
-    const char *desc)
-{
-       if (vm_rpc_send_rpci_tx(sc, "vmbackup.eventSet %s %d %s",
-           state, code, desc) != 0) {
-               DPRINTF("%s: setting backup status failed\n", DEVNAME(sc));
-       }
-}
-
-void
-vmt_quiesce_task(void *data)
-{
-       struct vmt_softc *sc = data;
-       int err;
-
-       DPRINTF("%s: quiescing filesystems for backup\n", DEVNAME(sc));
-       err = vfs_stall(curproc, 1);
-       if (err != 0) {
-               printf("%s: unable to quiesce filesystems\n", DEVNAME(sc));
-               vfs_stall(curproc, 0);
-
-               vmt_set_backup_status(sc, "req.aborted", VM_BACKUP_SYNC_ERROR,
-                   "vfs_stall failed");
-               vmt_set_backup_status(sc, "req.done", VM_BACKUP_SUCCESS, "");
-               sc->sc_quiesce = 0;
-               return;
-       }
-
-       DPRINTF("%s: filesystems quiesced\n", DEVNAME(sc));
-       vmt_set_backup_status(sc, "prov.snapshotCommit", VM_BACKUP_SUCCESS, "");
-}
-
-void
-vmt_quiesce_done_task(void *data)
-{
-       struct vmt_softc *sc = data;
-
-       vfs_stall(curproc, 0);
-
-       if (sc->sc_quiesce == -1)
-               vmt_set_backup_status(sc, "req.aborted", VM_BACKUP_REMOTE_ABORT,
-                   "");
-
-       vmt_set_backup_status(sc, "req.done", VM_BACKUP_SUCCESS, "");
-       sc->sc_quiesce = 0;
-}
-
-void
-vmt_tclo_abortbackup(struct vmt_softc *sc)
-{
-       const char *reply = VM_RPC_REPLY_OK;
-
-       if (sc->sc_quiesce > 0) {
-               DPRINTF("%s: aborting backup\n", DEVNAME(sc));
-               sc->sc_quiesce = -1;
-               task_set(&sc->sc_quiesce_task, vmt_quiesce_done_task, sc);
-               task_add(systq, &sc->sc_quiesce_task);
-       } else {
-               DPRINTF("%s: can't abort, no backup in progress\n",
-                   DEVNAME(sc));
-               reply = VM_RPC_REPLY_ERROR;
-       }
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, reply) != 0) {
-               DPRINTF("%s: error sending vmbackup.abort reply\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_startbackup(struct vmt_softc *sc)
-{
-       const char *reply = VM_RPC_REPLY_OK;
-
-       if (sc->sc_quiesce == 0) {
-               DPRINTF("%s: starting quiesce\n", DEVNAME(sc));
-               vmt_set_backup_status(sc, "reset", VM_BACKUP_SUCCESS, "");
-
-               task_set(&sc->sc_quiesce_task, vmt_quiesce_task, sc);
-               task_add(systq, &sc->sc_quiesce_task);
-               sc->sc_quiesce = 1;
-       } else {
-               DPRINTF("%s: can't start backup, already in progress\n",
-                   DEVNAME(sc));
-               reply = VM_RPC_REPLY_ERROR;
-       }
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, reply) != 0) {
-               DPRINTF("%s: error sending vmbackup.start reply\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-void
-vmt_tclo_backupdone(struct vmt_softc *sc)
-{
-       const char *reply = VM_RPC_REPLY_OK;
-       if (sc->sc_quiesce > 0) {
-               DPRINTF("%s: backup complete\n", DEVNAME(sc));
-               task_set(&sc->sc_quiesce_task, vmt_quiesce_done_task, sc);
-               task_add(systq, &sc->sc_quiesce_task);
-       } else {
-               DPRINTF("%s: got backup complete, but not doing a backup\n",
-                   DEVNAME(sc));
-               reply = VM_RPC_REPLY_ERROR;
-       }
-
-       if (vm_rpc_send_str(&sc->sc_tclo_rpc, reply) != 0) {
-               DPRINTF("%s: error sending vmbackup.snapshotDone reply\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-       }
-}
-
-int
-vmt_tclo_process(struct vmt_softc *sc, const char *name)
-{
-       int i;
-
-       /* Search for rpc command and call handler */
-       for (i = 0; vmt_tclo_rpc[i].name != NULL; i++) {
-               if (strcmp(vmt_tclo_rpc[i].name, sc->sc_rpc_buf) == 0) {
-                       vmt_tclo_rpc[i].cb(sc);
-                       return (0);
-               }
-       }
-
-       DPRINTF("%s: unknown command: \"%s\"\n", DEVNAME(sc), name);
-
-       return (-1);
-}
-
-void
-vmt_tclo_tick(void *xarg)
-{
-       struct vmt_softc *sc = xarg;
-       u_int32_t rlen;
-       u_int16_t ack;
-       int delay;
-
-       /* By default, poll every second for new messages */
-       delay = 1;
-
-       if (sc->sc_quiesce > 0) {
-               /* abort quiesce if it's taking too long */
-               if (sc->sc_quiesce++ == VM_BACKUP_TIMEOUT) {
-                       printf("%s: aborting quiesce\n", DEVNAME(sc));
-                       sc->sc_quiesce = -1;
-                       task_set(&sc->sc_quiesce_task, vmt_quiesce_done_task,
-                           sc);
-                       task_add(systq, &sc->sc_quiesce_task);
-               } else
-                       vmt_set_backup_status(sc, "req.keepAlive",
-                           VM_BACKUP_SUCCESS, "");
-       }
-
-       /* reopen tclo channel if it's currently closed */
-       if (sc->sc_tclo_rpc.channel == 0 &&
-           sc->sc_tclo_rpc.cookie1 == 0 &&
-           sc->sc_tclo_rpc.cookie2 == 0) {
-               if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) {
-                       DPRINTF("%s: unable to reopen TCLO channel\n",
-                           DEVNAME(sc));
-                       delay = 15;
-                       goto out;
-               }
-
-               if (vm_rpc_send_str(&sc->sc_tclo_rpc,
-                   VM_RPC_RESET_REPLY) != 0) {
-                       DPRINTF("%s: failed to send reset reply\n",
-                           DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-                       goto out;
-               } else {
-                       sc->sc_rpc_error = 0;
-               }
-       }
-
-       if (sc->sc_tclo_ping) {
-               if (vm_rpc_send(&sc->sc_tclo_rpc, NULL, 0) != 0) {
-                       DPRINTF("%s: failed to send TCLO outgoing ping\n",
-                           DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-                       goto out;
-               }
-       }
-
-       if (vm_rpc_get_length(&sc->sc_tclo_rpc, &rlen, &ack) != 0) {
-               DPRINTF("%s: failed to get length of incoming TCLO data\n",
-                   DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-               goto out;
-       }
-
-       if (rlen == 0) {
-               sc->sc_tclo_ping = 1;
-               goto out;
-       }
-
-       if (rlen >= VMT_RPC_BUFLEN) {
-               rlen = VMT_RPC_BUFLEN - 1;
-       }
-       if (vm_rpc_get_data(&sc->sc_tclo_rpc, sc->sc_rpc_buf, rlen, ack) != 0) {
-               DPRINTF("%s: failed to get incoming TCLO data\n", DEVNAME(sc));
-               sc->sc_rpc_error = 1;
-               goto out;
-       }
-       sc->sc_tclo_ping = 0;
-
-       /* The VM host can queue multiple messages; continue without delay */
-       delay = 0;
-
-       if (vmt_tclo_process(sc, sc->sc_rpc_buf) != 0) {
-               if (vm_rpc_send_str(&sc->sc_tclo_rpc,
-                   VM_RPC_REPLY_ERROR) != 0) {
-                       DPRINTF("%s: error sending unknown command reply\n",
-                           DEVNAME(sc));
-                       sc->sc_rpc_error = 1;
-               }
-       }
-
-       if (sc->sc_rpc_error == 1) {
-               /* On error, give time to recover and wait a second */
-               delay = 1;
-       }
-
-out:
-       timeout_add_sec(&sc->sc_tclo_tick, delay);
-}
-
-#define BACKDOOR_OP_I386(op, frame)            \
-       __asm__ volatile (                      \
-               "pushal;"                       \
-               "pushl %%eax;"                  \
-               "movl 0x18(%%eax), %%ebp;"      \
-               "movl 0x14(%%eax), %%edi;"      \
-               "movl 0x10(%%eax), %%esi;"      \
-               "movl 0x0c(%%eax), %%edx;"      \
-               "movl 0x08(%%eax), %%ecx;"      \
-               "movl 0x04(%%eax), %%ebx;"      \
-               "movl 0x00(%%eax), %%eax;"      \
-               op                              \
-               "xchgl %%eax, 0x00(%%esp);"     \
-               "movl %%ebp, 0x18(%%eax);"      \
-               "movl %%edi, 0x14(%%eax);"      \
-               "movl %%esi, 0x10(%%eax);"      \
-               "movl %%edx, 0x0c(%%eax);"      \
-               "movl %%ecx, 0x08(%%eax);"      \
-               "movl %%ebx, 0x04(%%eax);"      \
-               "popl 0x00(%%eax);"             \
-               "popal;"                        \
-               ::"a"(frame)                    \
-       )
-
-#define BACKDOOR_OP_AMD64(op, frame)           \
-       __asm__ volatile (                      \
-               "pushq %%rbp;                   \n\t" \
-               "pushq %%rax;                   \n\t" \
-               "movq 0x30(%%rax), %%rbp;       \n\t" \
-               "movq 0x28(%%rax), %%rdi;       \n\t" \
-               "movq 0x20(%%rax), %%rsi;       \n\t" \
-               "movq 0x18(%%rax), %%rdx;       \n\t" \
-               "movq 0x10(%%rax), %%rcx;       \n\t" \
-               "movq 0x08(%%rax), %%rbx;       \n\t" \
-               "movq 0x00(%%rax), %%rax;       \n\t" \
-               op                              "\n\t" \
-               "xchgq %%rax, 0x00(%%rsp);      \n\t" \
-               "movq %%rbp, 0x30(%%rax);       \n\t" \
-               "movq %%rdi, 0x28(%%rax);       \n\t" \
-               "movq %%rsi, 0x20(%%rax);       \n\t" \
-               "movq %%rdx, 0x18(%%rax);       \n\t" \
-               "movq %%rcx, 0x10(%%rax);       \n\t" \
-               "movq %%rbx, 0x08(%%rax);       \n\t" \
-               "popq 0x00(%%rax);              \n\t" \
-               "popq %%rbp;                    \n\t" \
-               : /* No outputs. */ : "a" (frame) \
-                 /* No pushal on amd64 so warn gcc about the clobbered 
registers. */ \
-               : "rbx", "rcx", "rdx", "rdi", "rsi", "cc", "memory" \
-       )
-
-
-#ifdef __i386__
-#define BACKDOOR_OP(op, frame) BACKDOOR_OP_I386(op, frame)
-#else
-#define BACKDOOR_OP(op, frame) BACKDOOR_OP_AMD64(op, frame)
-#endif
-
-void
-vm_cmd(struct vm_backdoor *frame)
-{
-       BACKDOOR_OP("inl %%dx, %%eax;", frame);
-}
-
-void
-vm_ins(struct vm_backdoor *frame)
-{
-       BACKDOOR_OP("cld;\n\trep insb;", frame);
-}
-
-void
-vm_outs(struct vm_backdoor *frame)
-{
-       BACKDOOR_OP("cld;\n\trep outsb;", frame);
-}
-
-int
-vm_rpc_open(struct vm_rpc *rpc, uint32_t proto)
-{
-       struct vm_backdoor frame;
-
-       bzero(&frame, sizeof(frame));
-       frame.eax.word      = VM_MAGIC;
-       frame.ebx.word      = proto | VM_RPC_FLAG_COOKIE;
-       frame.ecx.part.low  = VM_CMD_RPC;
-       frame.ecx.part.high = VM_RPC_OPEN;
-       frame.edx.part.low  = VM_PORT_CMD;
-       frame.edx.part.high = 0;
-
-       vm_cmd(&frame);
-
-       if (frame.ecx.part.high != 1 || frame.edx.part.low != 0) {
-               /* open-vm-tools retries without VM_RPC_FLAG_COOKIE here.. */
-               DPRINTF("vmware: open failed, eax=%08x, ecx=%08x, edx=%08x\n",
-                   frame.eax.word, frame.ecx.word, frame.edx.word);
-               return EIO;
-       }
-
-       rpc->channel = frame.edx.part.high;
-       rpc->cookie1 = frame.esi.word;
-       rpc->cookie2 = frame.edi.word;
-
-       return 0;
-}
-
-int
-vm_rpc_close(struct vm_rpc *rpc)
-{
-       struct vm_backdoor frame;
-
-       bzero(&frame, sizeof(frame));
-       frame.eax.word      = VM_MAGIC;
-       frame.ebx.word      = 0;
-       frame.ecx.part.low  = VM_CMD_RPC;
-       frame.ecx.part.high = VM_RPC_CLOSE;
-       frame.edx.part.low  = VM_PORT_CMD;
-       frame.edx.part.high = rpc->channel;
-       frame.edi.word      = rpc->cookie2;
-       frame.esi.word      = rpc->cookie1;
-
-       vm_cmd(&frame);
-
-       if (frame.ecx.part.high == 0 || frame.ecx.part.low != 0) {
-               DPRINTF("vmware: close failed, eax=%08x, ecx=%08x\n",
-                   frame.eax.word, frame.ecx.word);
-               return EIO;
-       }
-
-       rpc->channel = 0;
-       rpc->cookie1 = 0;
-       rpc->cookie2 = 0;
-
-       return 0;
-}
-
-int
-vm_rpc_send(const struct vm_rpc *rpc, const uint8_t *buf, uint32_t length)
-{
-       struct vm_backdoor frame;
-
-       /* Send the length of the command. */
-       bzero(&frame, sizeof(frame));
-       frame.eax.word = VM_MAGIC;
-       frame.ebx.word = length;
-       frame.ecx.part.low  = VM_CMD_RPC;
-       frame.ecx.part.high = VM_RPC_SET_LENGTH;
-       frame.edx.part.low  = VM_PORT_CMD;
-       frame.edx.part.high = rpc->channel;
-       frame.esi.word = rpc->cookie1;
-       frame.edi.word = rpc->cookie2;
-
-       vm_cmd(&frame);
-
-       if ((frame.ecx.part.high & VM_RPC_REPLY_SUCCESS) == 0) {
-               DPRINTF("vmware: sending length failed, eax=%08x, ecx=%08x\n",
-                   frame.eax.word, frame.ecx.word);
-               return EIO;
-       }
-
-       if (length == 0)
-               return 0; /* Only need to poke once if command is null. */
-
-       /* Send the command using enhanced RPC. */
-       bzero(&frame, sizeof(frame));
-       frame.eax.word = VM_MAGIC;
-       frame.ebx.word = VM_RPC_ENH_DATA;
-       frame.ecx.word = length;
-       frame.edx.part.low  = VM_PORT_RPC;
-       frame.edx.part.high = rpc->channel;
-       frame.ebp.word = rpc->cookie1;
-       frame.edi.word = rpc->cookie2;
-#ifdef __amd64__
-       frame.esi.quad = (uint64_t)buf;
-#else
-       frame.esi.word = (uint32_t)buf;
-#endif
-
-       vm_outs(&frame);
-
-       if (frame.ebx.word != VM_RPC_ENH_DATA) {
-               /* open-vm-tools retries on VM_RPC_REPLY_CHECKPOINT */
-               DPRINTF("vmware: send failed, ebx=%08x\n", frame.ebx.word);
-               return EIO;
-       }
-
-       return 0;
-}
-
-int
-vm_rpc_send_str(const struct vm_rpc *rpc, const uint8_t *str)
-{
-       return vm_rpc_send(rpc, str, strlen(str));
-}
-
-int
-vm_rpc_get_data(const struct vm_rpc *rpc, char *data, uint32_t length,
-    uint16_t dataid)
-{
-       struct vm_backdoor frame;
-
-       /* Get data using enhanced RPC. */
-       bzero(&frame, sizeof(frame));
-       frame.eax.word      = VM_MAGIC;
-       frame.ebx.word      = VM_RPC_ENH_DATA;
-       frame.ecx.word      = length;
-       frame.edx.part.low  = VM_PORT_RPC;
-       frame.edx.part.high = rpc->channel;
-       frame.esi.word      = rpc->cookie1;
-#ifdef __amd64__
-       frame.edi.quad      = (uint64_t)data;
-#else
-       frame.edi.word      = (uint32_t)data;
-#endif
-       frame.ebp.word      = rpc->cookie2;
-
-       vm_ins(&frame);
-
-       /* NUL-terminate the data */
-       data[length] = '\0';
-
-       if (frame.ebx.word != VM_RPC_ENH_DATA) {
-               DPRINTF("vmware: get data failed, ebx=%08x\n",
-                   frame.ebx.word);
-               return EIO;
-       }
-
-       /* Acknowledge data received. */
-       bzero(&frame, sizeof(frame));
-       frame.eax.word      = VM_MAGIC;
-       frame.ebx.word      = dataid;
-       frame.ecx.part.low  = VM_CMD_RPC;
-       frame.ecx.part.high = VM_RPC_GET_END;
-       frame.edx.part.low  = VM_PORT_CMD;
-       frame.edx.part.high = rpc->channel;
-       frame.esi.word      = rpc->cookie1;
-       frame.edi.word      = rpc->cookie2;
-
-       vm_cmd(&frame);
-
-       if (frame.ecx.part.high == 0) {
-               DPRINTF("vmware: ack data failed, eax=%08x, ecx=%08x\n",
-                   frame.eax.word, frame.ecx.word);
-               return EIO;
-       }
-
-       return 0;
-}
-
-int
-vm_rpc_get_length(const struct vm_rpc *rpc, uint32_t *length, uint16_t *dataid)
-{
-       struct vm_backdoor frame;
-
-       bzero(&frame, sizeof(frame));
-       frame.eax.word      = VM_MAGIC;
-       frame.ebx.word      = 0;
-       frame.ecx.part.low  = VM_CMD_RPC;
-       frame.ecx.part.high = VM_RPC_GET_LENGTH;
-       frame.edx.part.low  = VM_PORT_CMD;
-       frame.edx.part.high = rpc->channel;
-       frame.esi.word      = rpc->cookie1;
-       frame.edi.word      = rpc->cookie2;
-
-       vm_cmd(&frame);
-
-       if ((frame.ecx.part.high & VM_RPC_REPLY_SUCCESS) == 0) {
-               DPRINTF("vmware: get length failed, eax=%08x, ecx=%08x\n",
-                   frame.eax.word, frame.ecx.word);
-               return EIO;
-       }
-       if ((frame.ecx.part.high & VM_RPC_REPLY_DORECV) == 0) {
-               *length = 0;
-               *dataid = 0;
-       } else {
-               *length = frame.ebx.word;
-               *dataid = frame.edx.part.high;
-       }
-
-       return 0;
-}
-
-int
-vm_rpci_response_successful(struct vmt_softc *sc)
-{
-       return (sc->sc_rpc_buf[0] == '1' && sc->sc_rpc_buf[1] == ' ');
-}
-
-int
-vm_rpc_send_rpci_tx_buf(struct vmt_softc *sc, const uint8_t *buf,
-    uint32_t length)
-{
-       struct vm_rpc rpci;
-       u_int32_t rlen;
-       u_int16_t ack;
-       int result = 0;
-
-       if (vm_rpc_open(&rpci, VM_RPC_OPEN_RPCI) != 0) {
-               DPRINTF("%s: rpci channel open failed\n", DEVNAME(sc));
-               return EIO;
-       }
-
-       if (vm_rpc_send(&rpci, sc->sc_rpc_buf, length) != 0) {
-               DPRINTF("%s: unable to send rpci command\n", DEVNAME(sc));
-               result = EIO;
-               goto out;
-       }
-
-       if (vm_rpc_get_length(&rpci, &rlen, &ack) != 0) {
-               DPRINTF("%s: failed to get length of rpci response data\n",
-                   DEVNAME(sc));
-               result = EIO;
-               goto out;
-       }
-
-       if (rlen > 0) {
-               if (rlen >= VMT_RPC_BUFLEN) {
-                       rlen = VMT_RPC_BUFLEN - 1;
-               }
-
-               if (vm_rpc_get_data(&rpci, sc->sc_rpc_buf, rlen, ack) != 0) {
-                       DPRINTF("%s: failed to get rpci response data\n",
-                           DEVNAME(sc));
-                       result = EIO;
-                       goto out;
-               }
-       }
-
-out:
-       if (vm_rpc_close(&rpci) != 0) {
-               DPRINTF("%s: unable to close rpci channel\n", DEVNAME(sc));
-       }
-
-       return result;
-}
-
-int
-vm_rpc_send_rpci_tx(struct vmt_softc *sc, const char *fmt, ...)
-{
-       va_list args;
-       int len;
-
-       va_start(args, fmt);
-       len = vsnprintf(sc->sc_rpc_buf, VMT_RPC_BUFLEN, fmt, args);
-       va_end(args);
-
-       if (len >= VMT_RPC_BUFLEN) {
-               DPRINTF("%s: rpci command didn't fit in buffer\n", DEVNAME(sc));
-               return EIO;
-       }
-
-       return vm_rpc_send_rpci_tx_buf(sc, sc->sc_rpc_buf, len);
-}
-
-#if 0
-       struct vm_backdoor frame;
-
-       bzero(&frame, sizeof(frame));
-
-       frame.eax.word = VM_MAGIC;
-       frame.ecx.part.low = VM_CMD_GET_VERSION;
-       frame.edx.part.low  = VM_PORT_CMD;
-
-       printf("\n");
-       printf("eax 0x%08x\n", frame.eax.word);
-       printf("ebx 0x%08x\n", frame.ebx.word);
-       printf("ecx 0x%08x\n", frame.ecx.word);
-       printf("edx 0x%08x\n", frame.edx.word);
-       printf("ebp 0x%08x\n", frame.ebp.word);
-       printf("edi 0x%08x\n", frame.edi.word);
-       printf("esi 0x%08x\n", frame.esi.word);
-
-       vm_cmd(&frame);
-
-       printf("-\n");
-       printf("eax 0x%08x\n", frame.eax.word);
-       printf("ebx 0x%08x\n", frame.ebx.word);
-       printf("ecx 0x%08x\n", frame.ecx.word);
-       printf("edx 0x%08x\n", frame.edx.word);
-       printf("ebp 0x%08x\n", frame.ebp.word);
-       printf("edi 0x%08x\n", frame.edi.word);
-       printf("esi 0x%08x\n", frame.esi.word);
-#endif
-
-/*
- * Notes on tracing backdoor activity in vmware-guestd:
- *
- * - Find the addresses of the inl / rep insb / rep outsb
- *   instructions used to perform backdoor operations.
- *   One way to do this is to disassemble vmware-guestd:
- *
- *   $ objdump -S /emul/freebsd/sbin/vmware-guestd > vmware-guestd.S
- *
- *   and search for '<tab>in ' in the resulting file.  The rep insb and
- *   rep outsb code is directly below that.
- *
- * - Run vmware-guestd under gdb, setting up breakpoints as follows:
- *   (the addresses shown here are the ones from VMware-server-1.0.10-203137,
- *   the last version that actually works in FreeBSD emulation on OpenBSD)
- *
- * break *0x805497b   (address of 'in' instruction)
- * commands 1
- * silent
- * echo INOUT\n
- * print/x $ecx
- * print/x $ebx
- * print/x $edx
- * continue
- * end
- * break *0x805497c   (address of instruction after 'in')
- * commands 2
- * silent
- * echo ===\n
- * print/x $ecx
- * print/x $ebx
- * print/x $edx
- * echo \n
- * continue
- * end
- * break *0x80549b7   (address of instruction before 'rep insb')
- * commands 3
- * silent
- * set variable $inaddr = $edi
- * set variable $incount = $ecx
- * continue
- * end
- * break *0x80549ba   (address of instruction after 'rep insb')
- * commands 4
- * silent
- * echo IN\n
- * print $incount
- * x/s $inaddr
- * echo \n
- * continue
- * end
- * break *0x80549fb    (address of instruction before 'rep outsb')
- * commands 5
- * silent
- * echo OUT\n
- * print $ecx
- * x/s $esi
- * echo \n
- * continue
- * end
- *
- * This will produce a log of the backdoor operations, including the
- * data sent and received and the relevant register values.  You can then
- * match the register values to the various constants in this file.
- */
Index: sys/dev/pv/files.pv
===================================================================
RCS file: /cvs/src/sys/dev/pv/files.pv,v
retrieving revision 1.16
diff -u -p -r1.16 files.pv
--- sys/dev/pv/files.pv 24 Jan 2020 05:14:51 -0000      1.16
+++ sys/dev/pv/files.pv 8 Jan 2021 21:07:05 -0000
@@ -13,11 +13,6 @@ device       pvclock
 attach pvclock at pvbus
 file   dev/pv/pvclock.c                pvclock needs-flag
 
-# VMware Tools
-device vmt
-attach vmt at pvbus
-file   dev/pv/vmt.c                    vmt
-
 # Xen
 device xen {}
 attach xen at pvbus
Index: usr.sbin/hostctl/hostctl.8
===================================================================
RCS file: /cvs/src/usr.sbin/hostctl/hostctl.8,v
retrieving revision 1.5
diff -u -p -r1.5 hostctl.8
--- usr.sbin/hostctl/hostctl.8  21 Jul 2017 20:58:07 -0000      1.5
+++ usr.sbin/hostctl/hostctl.8  8 Jan 2021 21:12:11 -0000
@@ -81,17 +81,6 @@ file.
 .El
 .Sh EXAMPLES
 The
-.Xr vmt 4
-driver provides access to the
-.Dq guestinfo
-information that is available in VMware virtual machines:
-.Bd -literal -offset indent
-# hostctl guestinfo.hostname
-vm-111.example.com
-# hostctl guestinfo.ip 192.168.100.111
-.Ed
-.Pp
-The
 .Xr xen 4
 driver provides access to the XenStore that is available in Xen
 virtual machines.
Index: share/man/man4/Makefile
===================================================================
RCS file: /cvs/src/share/man/man4/Makefile,v
retrieving revision 1.790
diff -u -p -r1.790 Makefile
--- share/man/man4/Makefile     6 Dec 2020 20:48:12 -0000       1.790
+++ share/man/man4/Makefile     8 Jan 2021 21:06:18 -0000
@@ -94,7 +94,7 @@ MAN=  aac.4 abcrtc.4 abl.4 ac97.4 acphy.4
        vether.4 vga.4 vgafb.4 vge.4 \
        viapm.4 viasio.4 vic.4 video.4 vio.4 \
        vioblk.4 viocon.4 viomb.4 viornd.4 vioscsi.4 virtio.4 vlan.4 \
-       vmmci.4 vmt.4 vmwpvs.4 vmx.4 vnd.4 vr.4 \
+       vmmci.4 vmwpvs.4 vmx.4 vnd.4 vr.4 \
        vscsi.4 vte.4 vxlan.4 \
        watchdog.4 wb.4 wbenv.4 wbng.4 wbsd.4 wbsio.4 wd.4 wdc.4 wdsc.4 we.4 \
        wg.4 wi.4 witness.4 wpi.4 wscons.4 wsdisplay.4 wskbd.4 wsmouse.4 \
Index: share/man/man4/pvbus.4
===================================================================
RCS file: /cvs/src/share/man/man4/pvbus.4,v
retrieving revision 1.14
diff -u -p -r1.14 pvbus.4
--- share/man/man4/pvbus.4      14 Jun 2017 12:42:09 -0000      1.14
+++ share/man/man4/pvbus.4      8 Jan 2021 21:09:20 -0000
@@ -55,13 +55,6 @@ Xen VMM
 .Pp
 Note that a hypervisor can attempt to emulate other hypervisors, so
 multiple hypervisor interfaces may be available on the same host.
-.Ss VMware paravirtual devices
-.Bl -tag -width 13n -offset ind -compact
-.It Xr vmt 4
-VMware Tools driver and
-.Dq guestinfo
-information store
-.El
 .Ss Hyper-V paravirtual devices
 .Bl -tag -width 13n -offset ind -compact
 .It Xr hvn 4
Index: share/man/man4/vmt.4
===================================================================
RCS file: share/man/man4/vmt.4
diff -N share/man/man4/vmt.4
--- share/man/man4/vmt.4        21 Jul 2015 07:01:04 -0000      1.9
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,66 +0,0 @@
-.\"    $OpenBSD: vmt.4,v 1.9 2015/07/21 07:01:04 schwarze Exp $
-.\"
-.\" Copyright (c) 2008 Marco Peereboom <[email protected]>
-.\" Text was heavily borrowed from the IPMI spec V1.5
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.Dd $Mdocdate: July 21 2015 $
-.Dt VMT 4
-.Os
-.Sh NAME
-.Nm vmt
-.Nd VMware Tools driver
-.Sh SYNOPSIS
-.Cd "vmt0 at pvbus0"
-.Sh DESCRIPTION
-The
-.Nm
-driver is a kernel level implementation of VMware Tools.
-VMware Tools are intended to provide better support for operating systems
-running inside virtual machines.
-.Pp
-.Nm
-handles shutdown and reboot requests from the host by signalling
-.Xr init 8
-with
-.Dv SIGUSR2
-and
-.Dv SIGINT
-respectively.
-.Nm
-will log notifications that the guest has been suspended or resumed by the
-host.
-It also provides access to the host machine's clock as a timedelta sensor.
-.Pp
-.Nm
-reports the guest's hostname and first non-loopback IP address to the host.
-.Sh SEE ALSO
-.Xr pvbus 4 ,
-.Xr init 8 ,
-.Xr sensorsd 8 ,
-.Xr sysctl 8
-.Pp
-A
-.Sy vmwh
-helper program is available via
-.Xr packages 7 .
-.Sh HISTORY
-The
-.Nm
-driver first appeared in
-.Ox 4.4 .
-.Sh AUTHORS
-The
-.Nm
-driver was written by
-.An David Gwynne Aq Mt [email protected] .
Index: distrib/sets/lists/man/mi
===================================================================
RCS file: /cvs/src/distrib/sets/lists/man/mi,v
retrieving revision 1.1605
diff -u -p -r1.1605 mi
--- distrib/sets/lists/man/mi   7 Dec 2020 04:27:07 -0000       1.1605
+++ distrib/sets/lists/man/mi   8 Jan 2021 21:20:56 -0000
@@ -2079,7 +2079,6 @@
 ./usr/share/man/man4/virtio.4
 ./usr/share/man/man4/vlan.4
 ./usr/share/man/man4/vmmci.4
-./usr/share/man/man4/vmt.4
 ./usr/share/man/man4/vmwpvs.4
 ./usr/share/man/man4/vmx.4
 ./usr/share/man/man4/vnd.4

Reply via email to