Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F3500605
VMware GuestRPC
No One
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
stevek
Jun 28 2018, 2:31 PM
2018-06-28 14:31:12 (UTC+0)
Size
13 KB
Referenced Files
None
Subscribers
None
VMware GuestRPC
View Options
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
File Metadata
Details
Attached
Mime Type
text/plain; charset=utf-8
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1430197
Default Alt Text
VMware GuestRPC (13 KB)
Attached To
Mode
P187 VMware GuestRPC
Attached
Detach File
Event Timeline
Log In to Comment