Page MenuHomeFreeBSD
Paste P187

VMware GuestRPC
ActivePublic

Authored by stevek on Jun 28 2018, 2:31 PM.
Index: sys/conf/files.amd64
===================================================================
--- sys/conf/files.amd64 (revision 335682)
+++ sys/conf/files.amd64 (working copy)
@@ -745,6 +745,7 @@
x86/x86/pvclock.c standard
x86/x86/stack_machdep.c optional ddb | stack
x86/x86/tsc.c standard
+x86/x86/vmware_guestrpc.c optional vmware_guestrpc
x86/x86/delay.c standard
x86/xen/hvm.c optional xenhvm
x86/xen/xen_intr.c optional xenhvm
Index: sys/conf/files.i386
===================================================================
--- sys/conf/files.i386 (revision 335682)
+++ sys/conf/files.i386 (working copy)
@@ -623,6 +623,7 @@
x86/x86/nexus.c standard
x86/x86/stack_machdep.c optional ddb | stack
x86/x86/tsc.c standard
+x86/x86/vmware_guestrpc.c optional vmware_guestrpc
x86/x86/pvclock.c standard
x86/x86/delay.c standard
x86/xen/hvm.c optional xenhvm
Index: sys/conf/options.amd64
===================================================================
--- sys/conf/options.amd64 (revision 335682)
+++ sys/conf/options.amd64 (working copy)
@@ -69,3 +69,6 @@
# EFI Runtime services support
EFIRT opt_efirt.h
+
+# VMware support
+VMWARE_GUESTRPC opt_global.h
Index: sys/conf/options.i386
===================================================================
--- sys/conf/options.i386 (revision 335682)
+++ sys/conf/options.i386 (working copy)
@@ -120,3 +120,6 @@
# options for the Intel C600 SAS driver (isci)
ISCI_LOGGING opt_isci.h
+
+# VMware support
+VMWARE_GUESTRPC opt_global.h
Index: sys/x86/include/vmware.h
===================================================================
--- sys/x86/include/vmware.h (revision 335682)
+++ sys/x86/include/vmware.h (working copy)
@@ -33,6 +33,7 @@
#define VMW_HVPORT 0x5658
#define VMW_HVCMD_GETVERSION 10
+#define VMW_HVCMD_GUESTRPC 30
#define VMW_HVCMD_GETHZ 45
#define VMW_HVCMD_GETVCPU_INFO 68
@@ -40,13 +41,25 @@
#define VMW_VCPUINFO_VCPU_RESERVED (1 << 31)
static __inline void
-vmware_hvcall(u_int cmd, u_int *p)
+vmware_hypercall(int chan, u_int cmd, u_int param, u_int *p)
{
__asm __volatile("inl %w3, %0"
: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
- : "0" (VMW_HVMAGIC), "1" (UINT_MAX), "2" (cmd), "3" (VMW_HVPORT)
+ : "0" (VMW_HVMAGIC), "1" (param), "2" (cmd),
+ "3" (VMW_HVPORT | (chan << 16))
: "memory");
}
+/*
+ * Retain the old API for backwards compatibility
+ * XXX deprecate after some time?
+ */
+static __inline void
+vmware_hvcall(u_int cmd, u_int *p)
+{
+
+ vmware_hypercall(0, cmd, UINT_MAX, p);
+}
+
#endif /* !_X86_VMWARE_H_ */
Index: sys/x86/include/vmware_guestrpc.h
===================================================================
--- sys/x86/include/vmware_guestrpc.h (nonexistent)
+++ sys/x86/include/vmware_guestrpc.h (working copy)
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2015, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _X86_VMWARE_GUESTRPC_H_
+#define _X86_VMWARE_GUESTRPC_H_
+
+struct sbuf;
+
+int vmware_guestrpc_cmd(struct sbuf *sbufp);
+int vmware_guestrpc_set_guestinfo(const char *keyword, const char *val);
+int vmware_guestrpc_get_guestinfo(const char *keyword, struct sbuf *sbufp);
+
+#endif /* _X86_VMWARE_GUESTRPC_H_ */
Property changes on: sys/x86/include/vmware_guestrpc.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: sys/x86/x86/vmware_guestrpc.c
===================================================================
--- sys/x86/x86/vmware_guestrpc.c (nonexistent)
+++ sys/x86/x86/vmware_guestrpc.c (working copy)
@@ -0,0 +1,312 @@
+/*-
+ * Copyright (c) 2013, 2015, 2018, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/limits.h>
+#include <sys/sbuf.h>
+#include <sys/sysctl.h>
+#include <sys/errno.h>
+#include <sys/module.h>
+
+#include <x86/vmware.h>
+#include <x86/vmware_guestrpc.h>
+
+#ifdef VMWARE_GUESTRPC_DEBUG
+#define VMW_GUESTRPC_DBGPRINT(fmt, ...) \
+ do { \
+ if (vmware_guestrpc_debug > 0) \
+ printf(fmt, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define VMW_GUESTRPC_DBGPRINT(fmt, ...)
+#endif
+
+/* GuestRPC Subcommands */
+#define VMW_HVGUESTRPC_OPEN 0x00
+#define VMW_HVGUESTRPC_SEND_LEN 0x01
+#define VMW_HVGUESTRPC_SEND_DATA 0x02
+#define VMW_HVGUESTRPC_RECV_LEN 0x03
+#define VMW_HVGUESTRPC_RECV_DATA 0x04
+#define VMW_HVGUESTRPC_FINISH_RECV 0x05
+#define VMW_HVGUESTRPC_CLOSE 0x06
+/* GuestRPC Parameters */
+#define VMW_HVGUESTRPC_OPEN_MAGIC 0x49435052
+/* GuestRPC Status */
+#define VMW_HVGUESTRPC_FAILURE 0x00000000
+#define VMW_HVGUESTRPC_OPEN_SUCCESS 0x00010000
+#define VMW_HVGUESTRPC_SEND_LEN_SUCCESS 0x00810000
+#define VMW_HVGUESTRPC_SEND_DATA_SUCCESS 0x00010000
+#define VMW_HVGUESTRPC_RECV_LEN_SUCCESS 0x00830000
+#define VMW_HVGUESTRPC_RECV_DATA_SUCCESS 0x00010000
+#define VMW_HVGUESTRPC_FINISH_RECV_SUCCESS 0x00010000
+#define VMW_HVGUESTRPC_CLOSE_SUCCESS 0x00010000
+
+#define VMW_GUESTRPC_EBX(_p) ((_p)[1])
+#define VMW_GUESTRPC_EDXHI(_p) ((_p)[3] >> 16)
+#define VMW_GUESTRPC_STATUS(_p) ((_p)[2])
+
+#define VMW_GUESTRPC_MAX_PARAMS 4
+
+#ifdef VMWARE_GUESTRPC_DEBUG
+int vmware_guestrpc_debug;
+SYSCTL_INT(_debug, OID_AUTO, vmware_guestrpc, CTLFLAG_RDTUN,
+ &vmware_guestrpc_debug, 0, "Debug VMware GUESTRPC hypercalls");
+#endif
+
+static __inline void
+vmware_guestrpc(int chan, uint16_t subcmd, uint32_t param, u_int *p)
+{
+
+ VMW_GUESTRPC_DBGPRINT("%s(%d, %#x, %#x, %p)\n", __func__, chan, subcmd,
+ param, p);
+ vmware_hypercall(chan, VMW_HVCMD_GUESTRPC | (subcmd << 16), param, p);
+ VMW_GUESTRPC_DBGPRINT("p[0] = %#x\np[1] = %#x\np[2] = %#x\n"
+ "p[3] = %#x\n", p[0], p[1], p[2], p[3]);
+}
+
+static int
+vmware_guestrpc_open(void)
+{
+ u_int p[VMW_GUESTRPC_MAX_PARAMS];
+
+ vmware_guestrpc(0, VMW_HVGUESTRPC_OPEN, VMW_HVGUESTRPC_OPEN_MAGIC,
+ p);
+ if (VMW_GUESTRPC_STATUS(p) != VMW_HVGUESTRPC_OPEN_SUCCESS)
+ return (-1);
+
+ return (VMW_GUESTRPC_EDXHI(p));
+}
+
+static int
+vmware_guestrpc_send_len(int channel, size_t len)
+{
+ u_int p[VMW_GUESTRPC_MAX_PARAMS];
+
+ vmware_guestrpc(channel, VMW_HVGUESTRPC_SEND_LEN, len, p);
+ if (VMW_GUESTRPC_STATUS(p) != VMW_HVGUESTRPC_SEND_LEN_SUCCESS)
+ return (-1);
+
+ return (0);
+}
+
+static int
+vmware_guestrpc_send_data(int channel, uint32_t data)
+{
+ u_int p[VMW_GUESTRPC_MAX_PARAMS];
+
+ vmware_guestrpc(channel, VMW_HVGUESTRPC_SEND_DATA, data, p);
+ if (VMW_GUESTRPC_STATUS(p) != VMW_HVGUESTRPC_SEND_DATA_SUCCESS)
+ return (-1);
+
+ return (0);
+}
+
+static int
+vmware_guestrpc_recv_len(int channel, size_t *lenp)
+{
+ u_int p[VMW_GUESTRPC_MAX_PARAMS];
+
+ vmware_guestrpc(channel, VMW_HVGUESTRPC_RECV_LEN, 0, p);
+ if (VMW_GUESTRPC_STATUS(p) != VMW_HVGUESTRPC_RECV_LEN_SUCCESS)
+ return (-1);
+
+ *lenp = VMW_GUESTRPC_EBX(p);
+ return (VMW_GUESTRPC_EDXHI(p));
+}
+
+static int
+vmware_guestrpc_recv_data(int channel, int id, uint32_t *datap)
+{
+ u_int p[VMW_GUESTRPC_MAX_PARAMS];
+
+ vmware_guestrpc(channel, VMW_HVGUESTRPC_RECV_DATA, id, p);
+ if (VMW_GUESTRPC_STATUS(p) != VMW_HVGUESTRPC_RECV_DATA_SUCCESS)
+ return (-1);
+
+ *datap = VMW_GUESTRPC_EBX(p);
+ return (0);
+}
+
+static int
+vmware_guestrpc_close(int channel)
+{
+ u_int p[VMW_GUESTRPC_MAX_PARAMS];
+
+ vmware_guestrpc(channel, VMW_HVGUESTRPC_CLOSE, 0, p);
+ if (VMW_GUESTRPC_STATUS(p) != VMW_HVGUESTRPC_CLOSE_SUCCESS)
+ return (-1);
+
+ return (0);
+}
+
+int
+vmware_guestrpc_cmd(struct sbuf *sbufp)
+{
+ char *buf;
+ size_t cnt, len;
+ int chan, id, status;
+ uint32_t data;
+
+ chan = vmware_guestrpc_open();
+ if (chan == -1)
+ return (-1);
+
+ buf = sbuf_data(sbufp);
+ len = sbuf_len(sbufp);
+ status = vmware_guestrpc_send_len(chan, len);
+ if (status == -1)
+ goto done;
+
+ while (len > 0) {
+ data = 0;
+ cnt = min(sizeof(data), len);
+ memcpy(&data, buf, cnt);
+ status = vmware_guestrpc_send_data(chan, data);
+ if (status == -1)
+ goto done;
+ buf += cnt;
+ len -= cnt;
+ }
+
+ id = vmware_guestrpc_recv_len(chan, &len);
+ if (id == -1)
+ goto done;
+
+ sbuf_clear(sbufp);
+ while (len > 0) {
+ status = vmware_guestrpc_recv_data(chan, id, &data);
+ if (status == -1)
+ goto done;
+ sbuf_bcat(sbufp, &data, sizeof(data));
+ len -= min(sizeof(data), len);
+ }
+
+done:
+ vmware_guestrpc_close(chan);
+ return (status);
+}
+
+int
+vmware_guestrpc_set_guestinfo(const char *keyword, const char *val)
+{
+ struct sbuf sb;
+ char *buf;
+
+ VMW_GUESTRPC_DBGPRINT("%s: %s=%s\n", __func__, keyword, val);
+
+ if (sbuf_new(&sb, NULL, 256, SBUF_AUTOEXTEND) == NULL)
+ return (-1);
+ sbuf_printf(&sb, "info-set guestinfo.fbsd.%s %s", keyword, val);
+ sbuf_trim(&sb);
+ sbuf_finish(&sb);
+
+ if (vmware_guestrpc_cmd(&sb) == -1)
+ return (-1);
+
+ sbuf_finish(&sb);
+ buf = sbuf_data(&sb);
+
+ VMW_GUESTRPC_DBGPRINT("%s: result: %s\n", __func__, buf);
+
+ /*
+ * VMware hypervisor returns:
+ * "1" on sucess
+ * "0" on failure
+ */
+ return ((buf[0] == '0') ? -1 : 0);
+}
+
+int
+vmware_guestrpc_get_guestinfo(const char *keyword, struct sbuf *sbufp)
+{
+ struct sbuf sb;
+ char *buf;
+ ssize_t len;
+
+ VMW_GUESTRPC_DBGPRINT("%s: %s\n", __func__, keyword);
+
+ if (sbuf_new(&sb, NULL, 256, SBUF_AUTOEXTEND) == NULL)
+ return (-1);
+ sbuf_printf(&sb, "info-get guestinfo.fbsd.%s", keyword);
+ sbuf_trim(&sb);
+ sbuf_finish(&sb);
+
+ if (vmware_guestrpc_cmd(&sb) == -1)
+ return (-1);
+
+ sbuf_finish(&sb);
+ buf = sbuf_data(&sb);
+ len = sbuf_len(&sb);
+ if (len < 2)
+ return (-1);
+
+ VMW_GUESTRPC_DBGPRINT("%s: result: %s\n", __func__, buf);
+
+ /*
+ * VMware hypervisor returns:
+ * "1 <value>" on success
+ * "0 No value found" on failure
+ */
+ if (buf[0] == '0')
+ return (-1);
+
+ sbuf_cat(sbufp, buf + 2);
+ return (0);
+}
+
+static int
+vmware_guestrpc_modload(struct module *module, int cmd, void *arg)
+{
+ int error;
+
+ switch (cmd) {
+ case MOD_LOAD:
+ case MOD_UNLOAD:
+ error = 0;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
+
+static moduledata_t vmware_guestrpc_mod = {
+ "vmware_guestrpc",
+ &vmware_guestrpc_modload,
+ NULL
+};
+
+DECLARE_MODULE(vmware_guestrpc, vmware_guestrpc_mod, SI_SUB_HYPERVISOR,
+ SI_ORDER_MIDDLE);
+MODULE_VERSION(vmware_guestrpc, 1);
Property changes on: sys/x86/x86/vmware_guestrpc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+FreeBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property

Event Timeline

stevek created this paste.Jun 28 2018, 2:31 PM
stevek created this object in space S1 Global.